Sooner or later somebody wants the chat data out: a quarterly review, a migration, a legal request, or an analyst who would rather work in a spreadsheet than in anybody's dashboard. The export on the chat history screen does this, and it has enough structure to be worth ten minutes of reading before you use it in anger.
Two choices, made separately
There are two dropdowns and they are independent. The first is the export type: session list only, or chat messages. The second is the format: CSV or XML. That gives four combinations and they are genuinely different files.
Session list gives you one row per conversation — who, when, which agent, which department, the rating, the browser and page they came from. Chat messages gives you the message text as well. In CSV that means one row per message, with the whole set of session columns repeated on every row of the same conversation. A twenty-message chat becomes twenty rows. That is the right shape for a pivot table and the wrong shape for counting conversations, so know which question you are answering before you pick.
XML keeps the nesting instead: each session is an element with its messages inside it. If your destination is another system rather than a spreadsheet, XML is usually less work at the far end, because you do not have to reconstruct the grouping that CSV flattened.
Four limits that will stop you
The export refuses to run in four situations, and each one tells you which:
- No date range. A start date is required. There is no export-everything button, deliberately.
- Free plan, older than five days. On the free plan the export window is the last five days.
- More than 366 days. The range itself cannot exceed a year and a day.
- More than fifty thousand sessions. Above that you are asked to narrow the range.
The fifty thousand cap counts sessions, not messages, so a chat-messages export can produce far more rows than that and still be allowed. If you are exporting a busy year, split it by quarter and stitch the files together afterwards; that is less work than discovering the cap at the end of a long-running request.
The export obeys the filters on screen
This is the single most common surprise. The export is not a dump of everything in the date range — it runs the search you currently have set up. Agent, department, customer name, email and tags all narrow the export exactly as they narrow the list.
That is genuinely useful once you know it: one agent's conversations for a review, or one tag for an incident write-up, are a matter of setting the filter and exporting. It is also the reason an export can come back much smaller than expected. If the number of rows looks wrong, check the filters before you doubt the data.
Why the two exports disagree
Run both exports over the same range and the conversation counts will often not match. This is expected. The chat-messages export skips any session that has no messages stored against it, because there is nothing to write. The session-list export includes them.
Sessions with no messages are real — a visitor who opened the widget and left, a connection that dropped before anybody typed. So the session list is the honest count of conversations started, and the message export is the count of conversations that actually contained something. Do not try to reconcile them; each is answering a different question, and the difference between the two is itself a number worth looking at.
CSV quirks that look like bugs
Four things about the CSV file surprise people, and all four are deliberate.
Every line ends with a comma. A separator is written after every column including the last, so both the header and each row finish with a trailing empty field. Excel copes. Stricter parsers may report one more column than you were expecting, and if you are scripting against the file it is worth accounting for rather than being caught by it.
There is a byte order mark at the start. The file opens with a UTF-8 marker, which is what makes accented names and non-Latin scripts appear correctly when the file is double-clicked into a spreadsheet instead of arriving as mojibake. If you are reading the file in code, open it as UTF-8 with the mark handled, rather than treating those first bytes as data.
Line breaks inside a message disappear. Carriage returns and newlines are stripped from every field before it is written, so a message a visitor typed across three lines arrives as one. This keeps each record on a single line, which is what makes the file safe to process line by line, but it does mean the export is not a faithful reproduction of the original formatting.
Some cells gain a leading apostrophe. If a value begins with an equals sign, a plus, a minus or an at sign, an apostrophe is added in front of it. This is not corruption — it stops a spreadsheet from interpreting text a stranger typed into your chat widget as a formula to execute. It is a deliberate safety measure against a real attack, and the apostrophe is easy to strip if you are processing the file programmatically. Anything you export from a public-facing channel deserves this treatment.
Reading the time columns carefully
Times are converted to your account's time zone rather than being left in UTC, so the file matches what you saw on screen.
Which makes it worth knowing what your account actually believes about its time zone before you hand the file to anyone. An account holding only a UTC offset cannot say whether your area observes daylight saving, so an export covering part of the year can be an hour out and still look entirely reasonable — why your timestamps need a region, not just an offset explains the fix and who it applies to.
The column shapes differ, though, and it matters. The start time carries a full date and time. The end time is a time only, with no date — as does the per-message time in the chat export. For a conversation inside one day that reads fine. For one that crosses midnight, an end time that looks earlier than the start time is not an error in the data; the date is simply not in that column. Take the date from the start-time column and you will not go wrong.
One more column behaves conditionally: the feedback comment is only fetched for conversations that carry a rating. If you are looking for comments, look for them alongside ratings rather than expecting the column to be independently populated.
Large exports
Big exports stream rather than being assembled in memory first: sessions are fetched in batches and written out as they go, and the page allows itself considerably longer than a normal request to finish. In practice that means a large export starts downloading and keeps going, rather than sitting on a blank page and then failing.
What it also means is that the download begins before the work is finished. A file that stops early is a request that was interrupted, not a complete export — so for the big ones, check the tail of the file rather than trusting that a file arriving means a file finished. Custom fields you collect on the pre-chat form travel with the export too, which is often the reason to do this at all: they are the columns your own reporting cares about, and the transcript screen is where you confirm you are collecting them in the first place.
If your export total does not match the bar on a dashboard chart, the difference is usually a definition rather than a missing row. Which chats your dashboard charts actually count explains which sessions each chart includes.