Reference
The WhatsApp export format, documented
What is actually inside a WhatsApp export, down to the characters that do not render. Written for anyone parsing one, and for anyone wondering why their converter produced nonsense.
Last updated
What is inside a WhatsApp export?
An export is a ZIP containing a single transcript and, when media was included, the attachment files beside it. There is no manifest, no index and no metadata file. Everything a reader needs to reconnect a message to its attachment is in the transcript itself.
_chat.txt IMG-20240315-WA0001.jpg VID-20240315-WA0004.mp4 PTT-20240315-WA0009.opus STK-20240316-WA0002.webp
| IMG | A photo, usually JPEG. |
|---|---|
| VID | A video, usually MP4. |
| PTT | A voice note, recorded in the app. Opus in an OGG container. |
| AUD | An audio file that was sent rather than recorded. |
| STK | A sticker, usually WebP. |
What do WhatsApp timestamps look like?
Every line of the transcript begins with a timestamp and a sender. There are two shapes, and which one you get depends on the platform and the phone's language settings rather than on anything you can choose.
[3/15/24, 9:22:31 AM] Sarah Chen: Can you send the schedule? 3/15/24, 9:22 - Sarah Chen: Can you send the schedule?
- The bracket form usually comes from iOS and carries seconds.
- The dash form usually comes from Android and usually does not.
- Both appear in 12-hour and 24-hour versions, again depending on the phone.
Why does an export contain invisible characters?
This is the single most common reason a converter produces garbage. iOS exports contain characters that do not render and are easy to miss when you open the file in a text editor.
| U+200E | Left-to-right mark. Frequently sits immediately after the opening bracket and before attachment markers, so a parser anchored on “[” alone drifts by one character. |
|---|---|
| U+202F | Narrow no-break space. Appears between the time and AM or PM, so a pattern expecting a plain space fails to match. |
Stripping them before parsing is tempting and wrong: they are part of the file whose digest you are about to publish. Read past them, do not rewrite them.
Which lines are messages, and which are not?
Not every line in the file is a message, and not every message is one line.
- Continuations. Any line that does not begin with a timestamp belongs to the message above it. A message containing line breaks produces several lines.
- System messages. Encryption notices, group membership changes and subject changes are written like messages but have no sender.
- Attachments. Written as
<attached: FILENAME>on iOS andFILENAME (file attached)on Android. - Omitted media. When the export was made without media, attachments become a short phrase such as
image omittedand the file itself is simply absent.
Every one of these is worth checking against a real file rather than taken on trust. The export viewer reads one in your browser and names the lines it could not attribute, and the export guide covers getting the file off the phone in the first place.
How are voice notes stored in an export?
A voice note appears in the transcript as an attachment line naming a .opus file, and that file sits in the archive. The link between a message and its audio therefore costs nothing to establish: it is written down.
The hard part is not finding the audio, it is decoding it. Opus in an OGG container is handled unevenly across browsers, which is why a fallback decoder matters more than the transcription model does.
Keep reading
- How to export a WhatsApp chatStep-by-step export instructions for iPhone and Android, what “Attach Media” changes, why WhatsApp Desktop cannot export, and what ends up inside the ZIP.
- What Bates numbering isWhere the name comes from, what a Bates number looks like, why it runs continuously across a production, and what stamping one does not accomplish.
- How a SHA-256 digest proves a file has not changedWhat a hash is, why changing a single byte changes the whole digest, how to compute one yourself on macOS, Windows and Linux, and what a digest cannot tell you.