# Transform your data

> How to turn any export into one row per message in the Dimension Labs format, with recipes, the toolkit script and a checklist.

Most exports are not shaped like a conversation file. A survey tool gives you one row per respondent. A call recorder puts the whole call in one cell. A help desk hands you nested JSON. Transforming means turning any of these into the [conversation data format](/data/conversation-format): **one row per message**, with `text`, `userId`, `incoming`, `sessionId` and `dimensionlabs_timestamp` on every row, and anything else you want to filter or join on kept as extra columns.


You can do it yourself with the recipes on these pages, or a technical person on your team can, or Dimension Labs technical support can do it for you (see [Get help](#get-help-from-dimension-labs)).

## Start here

1. **Recognize the shape** of what you have: [Recognize your data's shape](/transform/shapes).
2. **Try the in-browser converter first.** For column renames, reviews, chats and tickets with a role column, and wide surveys, [Convert a file](/data/convert-a-file) is enough and needs no code.
3. **Use a recipe** when the converter can't do it: transcripts in one cell, HTML bodies, system rows to skip, nested JSON, several exports to combine.
4. **Or use the toolkit**, a single script driven by a mapping file you keep and rerun every month: [The toolkit](/transform/toolkit).
5. **Check before you send**: [Before you send it](/transform/checklist).

## Which page do you need?

| What one row of your export holds | Go to |
|---|---|
| One message, with columns for who wrote it and when | [The converter](/data/convert-a-file) or [the toolkit](/transform/toolkit) |
| A whole conversation, with labels like `Agent:` and `Customer:` | [Split a transcript into turns](/transform/recipe-split-transcript) |
| A whole call, with speakers' names instead of roles | [Turn call transcripts into turns](/transform/recipe-call-transcripts) |
| One survey respondent, one column per question | [Reshape a wide survey](/transform/recipe-wide-survey) |
| An Excel workbook (`.xlsx`) with dates and long ids | [Excel and Excel dates](/transform/recipe-excel) |
| Nested JSON from an API or a data export | [Nested JSON to rows](/transform/recipe-nested-json) |
| Email or ticket bodies full of HTML and quoted replies | [Clean ticket and email text](/transform/recipe-clean-text) |
| Dates in local time, the wrong year, or seconds | [Fix timestamps](/transform/recipe-fix-timestamps) |
| Several exports (chat, email, monthly files) | [Combine several exports](/transform/recipe-combine-exports) |
| Orders, accounts or CRM fields you want next to conversations | [Attach business fields](/transform/recipe-business-fields) |
| A file too large for your own tools to open or convert | [Split a large file](/transform/recipe-split-large-file). For the upload itself there's no need: Dimension Labs splits a large file for you. |

## Where the result goes

The output of every recipe is a CSV or JSONL file you upload in **Data Sources** ([Upload a file](/data/upload-a-file)). Uploads accept CSV, TSV and JSONL, with no size limit: Dimension Labs splits a large file for you. After the upload, start a backfill from the **Backfill** tab to enrich it.

If you send data with the [universal API](/api/tracker) instead, the same rows become the JSON messages you `POST`: the field names are the same, and extra columns go in a nested `platformJson` object. A JSONL line can use that same shape. Send anything older than an hour to `/trackhistorical`, then run a backfill.

## What every recipe gets right

These rules come from the [conversation data format](/data/conversation-format) and from real conversions that went wrong:

- **Read columns by name, not position.** A script that reads "the fourth column" breaks the month the export adds a column.
- **Use a real CSV parser** (Papa Parse, Python's `csv`, pandas). Text with commas, quotes and line breaks breaks hand-written splitting.
- **Keep ids stable.** Derive `userId` and `sessionId` from ids in the export, never from random numbers, so a rerun produces the same conversations. Duplicates you upload are removed when Dimension Labs ingests them, so stable ids make a rerun safe.
- **Never use personal data as an id.** Don't use email addresses, phone numbers or names as `userId`, `sessionId` or a join key. Use the tool's internal ids, or the same hash of the email on both sides of a join.
- **Give replies the customer's id.** In a bot or agent conversation, `userId` is the end user's id on both their messages and the replies.
- **Get the direction right.** `incoming` is `true` only for what the customer or end user wrote.
- **Say which time zone a time is in.** A time like `1/3/2026 9:12 AM` has no zone until you give it one.
- **Drop rows with no text.** Don't fill them with placeholder text such as `[No Response]`.
- **Write to a fresh output folder each run**, so a rerun never appends to last run's files.

## Get help from Dimension Labs

Dimension Labs technical support can run large or complex transformations for you. Email **support@dimensionlabs.io** with:

1. **A sample of 20 to 50 rows** with sensitive values removed or replaced (names, emails, phone numbers, account numbers).
2. **The column list**, exactly as it appears in the export.
3. **What one row means**: one message, one conversation, one respondent, one call.
4. **Where the export came from**: the tool, and the report or API endpoint you used.
5. **The question you want answered**, so the right fields come along as metadata.

The [file checker](/data/check-a-file)'s downloadable report lists problems by code, row and column without your values, so you can attach it too.
