CSV export of iPhone messages: what every column means
A CSV export of an iPhone conversation is one row per message and fourteen comma separated columns, written as UTF-8 with a byte order mark and CRLF line ends so that Excel on Windows reads the accents and the emoji correctly. It is the format to choose when somebody is going to count, filter or sort the conversation rather than read it. Whether a double click also splits it into columns depends on your Windows, which is the next section but one. Getting to it is the same job as any other export, which how to export text messages from an iPhone to a computer covers from the backup onwards.
What are the fourteen columns?
In this order, which is the format’s contract and the thing a script depends on. One row from the sample published on this site, so you can check it against the file rather than against this page:
2026-02-06T19:04:00.000+01:00,+1 555 0142,false,"Picking Emily up Friday at 4, same as we agreed.",,,false,false,,,false,false,
That row has thirteen fields rather than fourteen, for the reason in the next section.
| # | Column | What it holds |
|---|---|---|
| 1 | timestamp | ISO 8601 with the offset the phone recorded, so local time and the zone travel together |
| 2 | sender | The handle the message came from, or me for your own |
| 3 | is_from_me | true or false |
| 4 | service | iMessage, SMS or RCS as the source recorded it, empty when it recorded nothing |
| 5 | text | The words, with the attachment placeholder character stripped |
| 6 | attachments | The attachment filenames, several separated by ; |
| 7 | reactions | Each reaction as kind:sender, several separated by ; |
| 8 | edited | Whether this message was edited |
| 9 | deleted | Whether it is marked deleted |
| 10 | edited_at | When the edit happened, when the row records it |
| 11 | previous_versions | The superseded wordings, one per line inside the cell, each prefixed with its replacement time when known |
| 12 | retracted | Whether the sender unsent part of this message |
| 13 | recovered_deleted | Whether this row came from the Recently Deleted store, which holds a deleted message for about 30 days, rather than from the live thread |
| 14 | deleted_at | When it was deleted, when the row records it |
Columns 9 to 14 are the ones a screenshot cannot give you. Column 8 is the exception and worth
naming as one: the phone does show Edited under a message it has edited, so that fact is on
screen, while the wording it replaced is not. Two of these columns need a switch turned on
before the export runs rather than after: previous_versions fills only when edit history was
requested, and recovered_deleted only when the Recently Deleted store was included, which
holds a deleted message for the 30 to 40 days Apple documents and nothing older.
Why does the sample file have thirteen columns?
Because the sample on this site was generated before service existed, and the card beside it
counts the file you can download rather than the program that wrote it. The published sample
has thirteen columns and no service; the program ships fourteen.
One consequence matters if you are writing a script against the sample rather than against
your own export: with service absent, every column after the third shifts left by one, so
text is the fourth field in the sample and the fifth in the table above. The contract is the
header row, which is why reading the header rather than counting positions is the habit that
survives this kind of change.
Correcting the sample’s count to fourteen would make this site describe a file nobody can download, so the two numbers stay until the sample is regenerated. You can check both halves yourself: the sample exports page carries the file.
Why is the header in English when my document is in German?
Because the header row is machine identifiers rather than reading matter. is_from_me and
recovered_deleted are names a formula, a filter or a script refers to, and translating them
would break the only thing this format exists for. The values are raw data for the same reason:
ISO timestamps, raw handles, booleans.
Exactly one thing in a CSV follows the document language, and only on an unlicensed run: the trial notice. The document language picker changes the PDF, the TXT and the HTML, and leaves the CSV’s structure alone on purpose. Which fourteen document languages exist, and why the choice is separate from the program’s own interface language, is on the download page.
Why does everything land in one column?
Because Excel splits a double clicked CSV on the list separator from your Windows regional
settings, not on the comma in the file. Where the decimal separator is a comma, which covers
German, French, Italian, Spanish, Portuguese and Polish Windows, the list separator is a
semicolon, so a comma separated file arrives with every row sitting in column A. Microsoft’s own
support answers say so plainly: opening a .csv this way
relies on the Windows country or region settings of that PC.
Nothing is wrong with the file, and there are two ways round it. Either open it through Data, then From Text/CSV, which lets you set the delimiter before anything is loaded, or change the list separator in Windows regional settings. The first is the one to use when the file is going to somebody else, because it changes nothing on your machine.
The byte order mark and the CRLF line ends do a different job: they are why the accents, the Polish characters and the emoji come out as themselves rather than as mojibake.
What else is worth knowing before you open it?
Two habits and one surprise.
Open a copy, not the file you will file. Excel offers to save in its own format and to
reformat what it thinks are dates. Neither is reversible in a way you want to discover later,
and the exported CSV is the thing whose checksum sits in the .sha256 file beside it.
Sorting is fine, but sort back. The rows come out in conversation order, and sorting by sender to group one person’s messages is the common and useful operation. A file that no longer reads as a conversation is not the file to attach to anything, so do that work on the copy.
Expect a leading apostrophe on some cells.
Excel and Google Sheets treat a cell beginning with =, +, - or @ as a formula, and
OWASP’s note on CSV injection records that quoting the field correctly does not stop it. Four
columns carry words the other side of the conversation wrote, so those four are the ones
guarded: sender, text, attachments and previous_versions. Each arrives with Excel’s own
treat-as-text apostrophe in front of it when it begins with one of those characters, which is
why a phone number may look like '+1 555 0142 in a text editor.
What is never touched is what the program writes itself: the timestamps, the booleans, the
transport name and the reactions column, which always begins with the reaction’s own kind.
Two notes on the apostrophe, because it is a mitigation rather than a fix. OWASP says the technique is unreliable once a CSV has been saved and reopened from Excel, which is a second reason to work on a copy. And a spreadsheet that imports rather than opens the file may show the apostrophe in the cell instead of hiding it.
What does a trial CSV look like?
Like a licensed one with an extra column. The unlicensed run adds a fifteenth column named
trial_notice and repeats the notice on every row, rather than writing a comment line above
the header.
A preamble line would break every script and spreadsheet that reads the file, turning “your trial output is watermarked” into “your CSV is corrupt”. Repeating the notice per row means it survives somebody sorting, filtering or copying a block of rows out, which a notice on the first row would not. The trial itself stops at the 50 most recent messages of a conversation.
What a CSV cannot do
- It cannot show the photographs. The
attachmentscolumn names the files; it does not carry them. A document that needs the images in it is a PDF or an HTML export, which is exporting messages with photos and attachments. - It cannot be handed to somebody as a document. It is a data file. A reader who is not going to filter anything is better served by the PDF, and most people filing a conversation want both: the PDF to read, the CSV to check.
- It cannot carry the integrity page. The source checksums, the device details and the
scope sentence are part of the PDF’s front matter, which is the page a recipient reads to see
where the document came from. The CSV gets the same
.sha256sidecar beside the file, which lets anyone check that this file is the one the program wrote, and says nothing about its origin. - It cannot tell you what it never held. An empty
edited_atmeans the row records no edit time, which is not the same as “was not edited”.
Questions people ask
Can I load a message CSV into a spreadsheet and still show it is unchanged?
Not after you save it from the spreadsheet, and that is the point of exporting once and working on a copy. The checksum belongs to the exported file byte for byte. Checking one is how to verify a PDF with SHA256, and the procedure is the same for a CSV.
Why are my own messages shown as me instead of my name?
Because me is unambiguous and a name is not: a filter matching on me cannot be fooled by
somebody in your contacts who shares your first name. The column beside it, is_from_me,
carries the same fact as a boolean, so a script never has to match on a word at all.
Does the CSV include group chats?
Yes, with the sender column holding the handle per row, which is what makes a group filterable by person. The participant list and the per sender counts are on the PDF’s front matter rather than in the CSV, because a data file has nowhere sensible to put them.
Is there a JSON export?
Not today. The five formats are PDF, TXT, HTML, CSV and RSMF, and RSMF is the one built for a review platform rather than for a reader. Anything else named on a roadmap is not something this page will promise.
Where to go next
- How to export text messages from an iPhone to a computer, the route the file comes out of.
- Exporting iPhone messages with their metadata, for what the other formats carry beside the words.
- The sample exports, to open a real CSV before installing anything.