Use CSV ingestion to send text-based or voice conversations to Heap Conversation Intelligence when a direct integration with your customer support or phone platform isn't available or hasn't been configured.
The files you provide depend on the conversation type:
-
Text conversations:
-
conversations.csv, with one row per conversation. -
messages.csv, with one row per message.
-
-
Voice conversations:
-
conversations.csv, with one row per conversation. -
voice_segments.csv, with one row per audio file. - The related audio files, uploaded to the Amazon S3 location provided by Heap.
-
The files are linked by source_id and conversation_source_id. Choose the format that matches your source data before preparing your files.
Before you begin
Make sure that:
- The CSV files are UTF-8 encoded.
- The comma (
,) is used as the delimiter. - For text conversations, both files are delivered together as one batch.
- Use the delivery method configured for your account, such as a single upload, SFTP drop, or shared Amazon S3 prefix.
- Identifiers remain stable between uploads.
- Timestamps include a timezone.
- Voice conversations should be solved or closed.
- Each voice conversation contains at least one back-and-forth exchange or is a bot-only conversation.
- For voice ingestion, Heap will provide an Amazon S3 bucket, folder, and credentials for uploading audio files. Voice recordings must be stereo, with one speaker on each channel. Use one channel for the agent and the other for the customer.
If a field from your source system doesn't map clearly to the format, contact your Customer Success Manager before generating the export.
General formatting requirements
| Type | Format | Example |
| Datetime | RFC 3339 with a timezone. UTC is preferred. |
2026-03-12T14:22:05Z or 2026-03-12T09:22:05-05:00
|
| Boolean | Lowercase true or false
|
true |
| Float | Decimal using a period (.) |
0.85 |
| List | JSON array in one field | ["billing","refund"] |
| Object | JSON object in one field | {"region":"EMEA","priority":"P2"} |
| Empty or unknown value | Leave the cell empty |
CSV fields that contain a comma, quotation mark, or newline must be enclosed in double quotation marks, in accordance with RFC 4180. Escape a quotation mark inside a quoted field by doubling it.
For example:
CONV-1001,CHAT,2026-03-12T14:20:00Z,2026-03-12T15:08:00Z,agent-42,Jane Smith,0.75,4,Alex Rivera,Acme,"[""billing"",""refund""]",Timestamps must be complete and monotonic:
- Every message must have a
source_createdvalue. - The earliest message timestamp must be at or after the conversation's
source_createdtimestamp. - Messages belonging to the same conversation must be ordered by
source_created.
Text conversations
File 1: conversations.csv
Create one row for each conversation.
Required columns
| Column | Type | Description |
|---|---|---|
source_id |
String | A unique identifier for the conversation in your source system. Use the same value for re-uploads. Heap uses it to de-duplicate conversations and link messages. |
channel |
Enum |
The conversation channel. For text conversations, use one of these channel values:
For voice conversations, set |
source_created |
Datetime | The timestamp when the conversation was originally created in your source system. |
Optional columns
| Column | Type | Description |
|---|---|---|
solve_time |
Datetime | The timestamp when the conversation was solved. Leave empty if the conversation isn't solved or the value is unknown. |
solving_agent_source_id |
String | The stable identifier of the agent who solved the conversation. |
solving_agent_name |
String | The display name of the agent who solved the conversation. |
normalized_csat |
Float | The customer satisfaction score normalized to a range from 0.0 -1.0. For example, a 4/5 rating can be represented as 0.75, and a 5/5 rating as 1.0. |
raw_rating |
String | The rating as it appears in your source system, such as "5", "good", or "Very Satisfied". Provide this together with normalized_csat when possible. |
customer_name |
String | The display name of the customer. Don't include additional personally identifiable information beyond what your source system already exposes. |
brand |
String | The brand associated with the conversation, if your organization operates multiple brands. |
tags |
JSON array of strings | Conversation-level tags, such as ["refund","priority-high"]. |
related_ticket_source_id |
String | The source_id of a related or parent conversation, if applicable. |
Example
source_id,channel,source_created,solve_time,solving_agent_source_id,solving_agent_name,normalized_csat,raw_rating,customer_name,brand,tags,related_ticket_source_id
CONV-1001,CHAT,2026-03-12T14:20:00Z,2026-03-12T15:08:00Z,agent-42,Jane Smith,0.75,4,Alex Rivera,Acme,"[""billing"",""refund""]",
CONV-1002,EMAIL,2026-03-12T15:45:00Z,,,,,,Sam Lee,Acme,"[""shipping""]",File 2: messages.csv
Use messages.csv for text conversations only.
Create one row for each message. Each row must link to a conversation through conversation_source_id.
Every message must have a source_created value. The earliest message timestamp must be at or after the conversation's source_created timestamp. Messages for the same conversation must be ordered by source_created.
Required columns
| Column | Type | Description |
|---|---|---|
conversation_source_id |
String | Must match a source_id in conversations.csv. |
message_source_id |
String | A unique identifier for the message within the conversation. Heap uses it for de-duplication and updates. |
message_type |
Enum | Use IN for a customer-to-agent message or OUT for an agent-to-customer message. |
message_body |
String | The message text. Preserve newlines using \n inside a quoted field. |
source_created |
Datetime | The timestamp when the message was sent. Messages must be sortable by this field. |
Optional columns
| Column | Type | Description |
|---|---|---|
author_source_id |
String | The stable identifier of the author. Use the agent ID for OUT messages and the customer ID for IN messages. For customer messages, this isn't strictly required and can be empty. |
author_name |
String | The display name of the author. |
author_email |
String | The email address of the author, when available. |
is_author_bot |
Boolean | Set to true when the message was sent by a bot or automation instead of a human agent. The default is false. |
For CSV ingestion, message_type accepts only IN and OUT. Don't use the API values OUT-HUMAN, OUT-BOT, or OUT-AUTO-REPLY. Use is_author_bot to identify messages sent by a bot or automation.
Example
conversation_source_id,message_source_id,message_type,message_body,source_created,author_source_id,author_name,author_email,is_author_bot
CONV-1001,MSG-1,IN,"Hi, I was double-charged for my last order.",2026-03-12T14:20:05Z,cust-9001,Alex Rivera,alex@example.com,false
CONV-1001,MSG-2,OUT,"Hello Alex — I'm sorry to hear that. Let me pull up your order.",2026-03-12T14:20:45Z,agent-42,Jane Smith,jane@acme.com,false
CONV-1001,MSG-3,IN,"Order #A7788.",2026-03-12T14:21:10Z,cust-9001,Alex Rivera,alex@example.com,false
CONV-1001,MSG-4,OUT,"I've issued a refund for the duplicate charge. It will appear in 3–5 business days.",2026-03-12T15:07:50Z,agent-42,Jane Smith,jane@acme.com,false
CONV-1002,MSG-1,IN,"Where is my package?",2026-03-12T15:45:00Z,cust-9002,Sam Lee,sam@example.com,falseVoice conversations
Voice conversations use conversations.csv for conversation-level data, voice_segments.csv for audio segment metadata, and the related audio files.
Voice conversations don't require messages.csv. Heap transcribes the audio and identifies the speakers.
Audio files
Heap will provide an Amazon S3 bucket, folder, and credentials for uploading audio files.
The audio files must be:
- Stereo, with one speaker per channel.
- In
.opus,.wav, or.mp3format. - Consistent in format across the delivery.
.opusis the default Genesys export format and works without conversion.
Use a unique path for each audio file. The recommended path pattern is:
audio/<conversation_source_id>/<segment_id>.opus
Conversation-level fields in conversations.csv
Set channel to VOICE.
Include the following fields when available:
| Field | Description |
is_inbound_call |
true when the customer called your organization, or false when an agent called the customer. |
voice_call_type |
Your call-type label, such as sales, support, or billing. |
call_talk_time, call_hold_time, call_wrap_up_time, call_consultation_time
|
In seconds. |
Segment-level fields in voice_segments.csv
Create one row for each audio file, not one row for each conversation.
A single call can contain multiple audio segments, such as transfers, consultations, or hold-and-return events. Use conversation_source_id to link each segment to its parent conversation.
Required columns
| Column | Type | Description |
conversation_source_id |
String | Must match source_id in conversations.csv. |
segment_id |
String | An identifier that is unique within the conversation. A globally unique value is recommended. |
audio_file_path |
String | The path or key of the audio file in the Amazon S3 bucket. Each value must be unique. |
audio_start_time |
Datetime | The time when the audio segment started, in RFC 3339 format with a timezone. |
audio_duration_seconds |
Number | The duration of the audio segment in seconds. |
Where available
| Column | Type | Description |
agent_source_id |
String | The stable identifier of the agent who handled the segment. Use the same identifier for the same agent across all rows and files. |
agent_name |
String | The agent's name. |
agent_email |
String | The agent's email address. |
agent_channel |
Number |
The stereo channel used by the agent: 1 or 2. Providing |
Example
conversation_source_id,segment_id,audio_file_path,audio_start_time,audio_duration_seconds,agent_source_id,agent_name,agent_email,agent_channel
CONV-2001,SEG-1,audio/CONV-2001/SEG-1.opus,2026-03-12T14:20:00Z,420,agent-42,Jane Smith,jane@acme.com,1
CONV-2001,SEG-2,audio/CONV-2001/SEG-2.opus,2026-03-12T14:27:10Z,290,agent-77,Mark Chen,mark@acme.com,1
Deliver the files
Deliver the files using the delivery method configured for your account, such as a single upload, SFTP drop, or shared Amazon S3 prefix.
Before sending the files, confirm the requirements for the selected format.
Text conversation checklist
- Every
messages.csvrow has aconversation_source_idthat exists inconversations.csv. - Every
source_idinconversations.csvis unique. - Every (
conversation_source_id,message_source_id) pair inmessages.csvis unique. - All timestamps use RFC 3339 format and include
Zor a numeric timezone offset. - Every message timestamp is at or after the conversation's
source_createdtimestamp. - Messages for each conversation are ordered by
source_created. - Every channel value is supported and isn't
VOICE. - Every
is_author_botvalue is lowercasetrueorfalse. - JSON fields contain valid JSON after CSV parsing.
- Both files are UTF-8 encoded.
Voice conversation checklist
- Every
voice_segments.csvrow has aconversation_source_idthat exists inconversations.csv. - Every
source_idinconversations.csvis unique. - Every
segment_idis unique within its conversation. - Every
audio_file_pathpoints to the correct audio file and is unique withinvoice_segments.csv. - All timestamps use RFC 3339 format and include a timezone.
- Every voice conversation has
channelset toVOICE. - Agent identifiers remain stable across all rows and files.
- The audio files are stereo, with one speaker per channel.
- Conversations are solved or closed.
- Each voice conversation contains at least one back-and-forth exchange or is a bot-only conversation.
- All CSV files are UTF-8 encoded.
Re-upload conversations
You can re-upload a conversation by using the same source_id.
When you re-upload:
- Heap updates the existing conversation.
- New messages are appended.
- Existing messages are updated in place when their
message_source_idmatches an existing message. -
source_idandmessage_source_idmust not be renamed between uploads.