Inside a WhatsApp export: the .txt format explained
In short
A WhatsApp export is a plain text file with no official specification: _chat.txt inside a .zip on iPhone, or a .txt file on Android. Each message starts with a timestamp header, followed by the author, a colon and the text. iPhone puts the date in square brackets with seconds, Android adds a dash before the author, and the date format follows the phone's regional settings.
A WhatsApp export looks like a simple text file until you try to read it with a program. This is a practical tour of how the file is built, every variation we have run into, and how a parser can cope with them.
By the Chat Recap team · Updated
When you export a WhatsApp chat, you get a plain text file: _chat.txt inside a .zip on iPhone, or a file like “WhatsApp Chat with Sunday Dinners.txt” on Android. There is no official specification for it. The layout depends on the phone’s operating system, its language and its regional settings, and it has changed over the years. Everything below is based on real exports and on the rules the parser behind Chat Recap uses (all examples use made-up names and numbers).
The basic line: date, time, author, message
Each message starts on a new line with a header (a timestamp), then the author’s name, a colon and the text. The two big families are iPhone and Android.
iPhone puts the timestamp in square brackets and includes seconds:
[05/10/2026, 09:32:15] Marta: Who's booking the restaurant?
Android uses no brackets, no seconds and a dash before the author:
05/10/2026, 09:32 - Marta: Who's booking the restaurant?
Splitting the author from the text sounds easy, but names can contain spaces, accents, hyphens and emoji (Joan 🦄, Anna Puig-Ferrer), and messages often contain colons too. The safe rule is to cut at the first colon followed by a space, after the header. So in Núria: good night: see you tomorrow, the author is Núria and the text keeps its own colon. The parser also caps the name at 80 characters, which avoids treating a long sentence with a colon as a name.
Newer exports sometimes put ~ in front of people who are not in your contacts (~ Álex). That prefix is decoration and should be removed so the same person isn’t counted twice.
Dates and times: the messy part
The timestamp is written using your phone’s regional settings, so the same moment can appear in many shapes:
| Example header | Typical source |
|---|---|
[05/10/2026, 21:15:02] |
iPhone, Europe, 24 h |
[10/5/26, 9:15:02 PM] |
iPhone, US English, 12 h |
05/10/2026, 21:15 - |
Android, Europe |
5/10/26, 9:15 p. m. - |
Android, Spanish, 12 h |
2026-10-05, 21:15 - |
Year-first locales |
05.10.26, 21:15 - |
Dotted dates (e.g. German) |
A few details trip up naive parsers:
- Day or month first?
05/10/2026is 5 October in most of the world and May 10 in the US, and the file does not say which. Chat Recap decides once for the whole file: any part above 12 settles it (a25/10can only be day-first), a four-digit first part means year-first, and if every date is ambiguous it picks the order that keeps the chat in chronological order. If that still ties, plainAM/PM(typical of US English) tips it to month-first; otherwise it defaults to day-first. - Two-digit years.
5/10/26means 2026. - 12-hour clocks.
12:00 AMis midnight and12:05 PMis just after noon. Spanish phones writea. m.andp. m.with dots. - Invisible spaces. iPhones in English put a narrow no-break space (U+202F) between the time and
PM. It looks like a normal space but a regex that expects" PM"will fail. - Separators. Some locales add a word between date and time (
a les,a las,at). Date separators can be/,.or-. - Impossible dates. A header like
31/02/2026should be rejected rather than silently rolled over into March.
Multi-line messages
A message with line breaks continues on the next lines without a header:
05/10/2026, 09:34 - Anna: But first
I need to finish work
and then I'll come
The rule: any line that doesn’t start with a valid header belongs to the previous message, including blank lines, which are part of what the person typed. This is also why you can’t just split the file by newline and count lines to get a message count.
System messages
WhatsApp mixes its own notices into the file: the end-to-end encryption notice, “created group”, “added”, “left”, “changed the subject”, security code changes, disappearing messages, pinned messages and so on. They are written differently on each platform.
On Android they have no author and no colon:
05/10/2026, 09:31 - Marta created group "Sunday Dinners 🍕"
05/10/2026, 09:31 - Marta added Anna
14/10/2026, 00:10 - Marta changed the subject from "Sunday Dinners" to "Dinners: season 2"
Note the last one: the new group name contains : , so a naive parser would think a person called Marta changed the subject from "Sunday Dinners" to "Dinners wrote a message. Chat Recap’s parser catches this case by spotting a one-off “author” with a long name whose text looks like a notice.
On iPhone, notices are usually attributed to the group name and the text starts with an invisible mark:
[05/10/26, 09:30:02] Sunday Dinners: Marta created group "Sunday Dinners"
If you count authors naively, the group itself becomes the chattiest member. A parser should recognise these lines as system messages and leave them out of per-person statistics. The text of system lines also often contains phone numbers (“Marta added +34 600 000 000”), which is worth masking.
Placeholders: media, deletions, edits, polls and calls
What replaced the photo depends on platform, language and whether you included media:
| What happened | Android (EN) | iPhone (EN) |
|---|---|---|
| Media, exported without it | <Media omitted> |
image omitted, video omitted, audio omitted, sticker omitted |
| Media, exported with it | IMG-20260301-WA0001.jpg (file attached) |
<attached: 00000123-PHOTO-2026-03-01-10-05-00.jpg> |
| Deleted | This message was deleted / You deleted this message |
same text |
| Edited | text followed by <This message was edited> |
same |
In Spanish they become <Multimedia omitido>, imagen omitida or Se eliminó este mensaje, and in Catalan <Fitxers multimèdia omesos> or S'ha suprimit aquest missatge. When media is included, the file name reveals its type (PTT- or AUDIO- for voice notes, STICKER-, VID-, PHOTO-). iPhone documents can look like Menu.pdf • 3 pages document omitted.
Some other generated bodies are worth knowing:
[01/03/26, 10:01:00] Pau: Missed voice call. Click to call back
[01/03/26, 10:04:00] Anna: POLL:
Where shall we eat?
OPTION: Pizza place (3 votes)
OPTION: Someone's house (0 votes)
Calls have an author but nobody “wrote” them. Polls arrive as a multi-line block with the question and each option with its vote count. “View once” messages and “This message can’t be displayed here” also show up as text. Here is how a careful parser (and ours) treats each:
- Media placeholders count as a message of type media, with no text.
- Deleted messages count as a message by that person, with the text emptied.
- The
<This message was edited>tag is stripped and the message is flagged as edited. - Polls keep only the question as text, without options and vote counts.
- Calls and group invite links become system lines, so they don’t count as someone writing.
- A real message that merely mentions a call (
Voice call?? where are you) stays a normal message.
Invisible characters
iPhone exports are full of zero-width Unicode marks, especially the left-to-right mark U+200E. It appears at the start of some lines, right before media placeholders and system texts, and around phone numbers (+1 (555) 010-0000 hides U+202A and U+202C). Files can also start with a byte order mark (U+FEFF) and use Windows line endings (\r\n).
These marks are useful hints: on iPhone, a body that starts with U+200E was generated by WhatsApp, not typed by a person. But they must be stripped before comparing names or text, otherwise “Marta” and “Marta” become two people.
How a robust parser handles it
Putting it together, a parser that survives real-world files tends to work like this:
- Normalise line endings and remove the byte order mark.
- First pass: find every line that looks like an iPhone or Android header, ignoring leading invisible marks.
- Decide the date order using all headers at once, not line by line.
- Second pass: build messages; lines without a header are appended to the previous one.
- Classify each message as normal, media or system, and detect deletions, edits and polls.
- Replace phone numbers. Our parser shows authors saved only as a number as “Contact 1”, “Contact 2” and masks numbers typed inside messages.
- Never drop a line silently. Lines before the first header, lines that look like a date but don’t parse (
05/10/2026 9h33) and impossible dates are recorded as warnings.
Finally, sanity-check the result. The analyzer rejects a file only when almost nothing looks like WhatsApp: it needs at least two real messages and either 15% of non-empty lines being headers or at least 50 headers. The format work all happens in your browser, as the privacy policy explains.
Next step
Open your own export in a text editor and find three things: the first header, a multi-line message and a media placeholder. Once you can spot them, the numbers in WhatsApp group statistics explained will make a lot more sense, and you can check them against your file in the analyzer.
FAQ
How can I tell if the dates in a WhatsApp export are day first or month first?
The file doesn't say. Any part above 12 settles it and a four-digit first part means year-first. If every date is ambiguous, Chat Recap picks the order that keeps the chat in chronological order, deciding once for the whole file.
What does <Media omitted> mean in a WhatsApp chat export?
It marks a photo, video, sticker or audio that was sent but left out because the chat was exported without media. iPhone writes lines such as image omitted instead, and the wording changes with the phone's language.
Why does the same person appear twice when I analyze a WhatsApp export?
iPhone exports contain invisible Unicode marks such as U+200E, and newer exports put "~ " in front of people who aren't in your contacts. If a tool doesn't strip them, one person can be counted as two different authors.
How are multi-line messages stored in a WhatsApp export?
The extra lines follow the first one without a timestamp header. Any line that doesn't start with a valid header, blank lines included, belongs to the previous message, so counting lines won't give you the number of messages.