Import conversations using CSV files

This feature is only available to paid customers as an add-on. To upgrade, contact your Customer Success Manager or sales@heap.io

Use CSV ingestion to send text-based conversations to Heap Conversational Intelligence when a direct integration with your customer support platform isn't available or hasn't been configured.

You must provide two CSV files:

  • conversations.csv, with one row per conversation.
  • messages.csv, with one row per message.

The files are linked by source_id and conversation_source_id.

Before you begin

Make sure that:

  • Both files are UTF-8 encoded.
  • The comma (,) is used as the delimiter.
  • Both files are delivered together as one batch.
  • The delivery method is the one configured for your account, such as a single upload, SFTP drop, or shared Amazon S3 prefix.
  • Voice conversations aren't included in this format. Don't set channel to VOICE.
  • Identifiers remain stable between uploads.
  • Timestamps include a timezone.

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_created value.
  • The earliest message timestamp must be at or after the conversation's source_created timestamp.
  • Messages belonging to the same conversation must be ordered by source_created.

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. Use one of: EMAIL, CHAT, SMS, MESSAGING, WEB, MOBILE_SDK, FACEBOOK, INSTAGRAM, TWITTER, WHATSAPP, TIKTOK, or API.
source_created Datetime The timestamp when the conversation was originally created in your source system.

Don't use VOICE for CSV ingestion. Voice conversations use a separate ingestion method.

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

Create one row for each message. Each row must link to a conversation through conversation_source_id.

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,false

Deliver the files

Deliver conversations.csv and messages.csv together as a single batch using the delivery method configured for your account.
 

Before sending the files, confirm that:

  1. Every messages.csv row has a conversation_source_id that exists in conversations.csv.
  2. Every source_id in conversations.csv is unique.
  3. Every (conversation_source_id, message_source_id) pair in messages.csv is unique.
  4. All timestamps use RFC 3339 format and include Z or a numeric timezone offset.
  5. Every message timestamp is at or after the conversation's source_created timestamp.
  6. Messages for each conversation are ordered by source_created.
  7. Every channel value is supported and isn't VOICE.
  8. Every is_author_bot value is lowercase true or false.
  9. JSON fields contain valid JSON after CSV parsing.
  10. Both 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_id matches an existing message.
  • source_id and message_source_id must not be renamed between uploads.

 

Last updated
Powered by Zendesk