Conversations
Export your chat conversations, the threads shoppers had with the AI assistant (and your operators after a handoff), for analytics, your data warehouse, CRM enrichment, or compliance archives.
The endpoints here are read-only. You can list conversations (filtered by date, cursor-paginated) and retrieve a single conversation with its full message transcript, the tags attached to it, and the interaction events it produced (add-to-cart, product clicks, support-button clicks).
Lean by default
The list endpoint returns conversation metadata and tags only. Pass include=messages to inline the transcript, and include=contact to inline customer contact details. This keeps a date-range sweep fast and lets you opt into the heavier data only when you need it.
The Conversation object
| Field | Type | Description |
|---|---|---|
humind_id | string | 24-char hex id of the conversation. Use it as {id} on the retrieve endpoint. |
created_at | ISO 8601 | When the conversation started (UTC). |
updated_at | ISO 8601 | Last activity (UTC). Drives updated_after incremental sync. |
last_message_at | ISO 8601 | Timestamp of the most recent message. |
origin | string | Channel the conversation started on (e.g. shopify). |
origin_url | string | The page URL where the chat began, when known. |
language | string[] | Detected language(s), ISO 639-1. |
title | string | AI/operator-assigned conversation title, when set. |
handoff_status | string | One of ai_active, queued, human_active. |
tags | string[] | AI- and operator-assigned tags. Always present (may be empty). |
has_triggered_cart | boolean | true if the shopper added a product to cart during the conversation. |
contact_id | string | Id of the identified customer, when one is linked. Returned unless include=contact is set (then the full contact object replaces it). |
contact | object | null | Customer contact details. Only present when include=contact is set. See Contact. |
messages | object[] | The message transcript. Always present on the retrieve endpoint; on the list only when include=messages is set. See Message. |
message_count | integer | Number of exported messages. Present only when messages are included. |
event_count | integer | Total interaction events across all messages. Present only when messages are included. |
Message
| Field | Type | Description |
|---|---|---|
humind_id | string | Id of the message. |
from | string | Who sent it: user, assistant, or operator. |
role | string | conversation (a user turn) or answer (an assistant turn). |
source | string | How a user message was sent, when known (e.g. typed, follow_up, product_page_question). |
content | string[] | The message text, as one or more blocks. |
created_at | ISO 8601 | When the message was sent (UTC). |
product_ids | string[] | Humind ids of products shown in this turn. Omitted when empty. |
referenced_product_ids | string[] | Humind ids of products cited inline (not shown as cards). Omitted when empty. |
attachments | object[] | Files uploaded in this turn. Omitted when empty. Each: { id, type, original_name, mime_type, size, width?, height? }. |
events | object[] | Interaction events on this message. Omitted when empty. See Interaction event. |
Interaction event
The visitor interactions captured against a message: what shoppers did, not just what they said.
| Field | Type | Description |
|---|---|---|
humind_id | string | Id of the event. |
type | string | One of add_product, remove_product, open_product_page, open_product_url, click_support_button. |
created_at | ISO 8601 | When the event was logged (UTC). |
product_id | string | Humind product id. Present for the four product event types. |
product_title | string | Product title, included when resolvable. |
product_variant_id | string | The variant added/removed. Present for add_product / remove_product. |
price_at_event | number | Unit price captured when the event was logged. Present for add_product / remove_product. |
button_identifier | string | Which support button was clicked: email, contact_us, support_page, or phone. Present for click_support_button. |
Contact
Returned only when you pass include=contact. Contains personal data. See the warning below.
| Field | Type | Description |
|---|---|---|
id | string | Id of the contact. |
name | string | Customer name, when known. |
email | string | Customer email, when known. |
phone | string | Customer phone, when known. |
When include=contact is set but the conversation has no identified contact, contact is null.
Contact data is personal data
name, email, and phone are PII. They are excluded by default and only returned when you explicitly add include=contact. Handle this data in line with your privacy policy and applicable regulations (GDPR, etc.), and only request it when your use case needs it.
What's excluded
The export is the merchant-facing view of a conversation. The following are intentionally not returned:
- Playground/sandbox conversations: test threads from the dashboard playground never appear.
- Internal operator notes: operator-only annotations are not part of the transcript.
- Deleted messages: soft-deleted messages are omitted rather than returned as tombstones.
- Internal AI fields: embeddings, response-quality ratings, tool calls, and reasoning traces are never exposed.
List conversations
GET /conversations returns the conversations that belong to the company the API key is bound to, newest-first.
Required scope: conversations:read
| Query parameter | Type | Description |
|---|---|---|
created_after | ISO 8601 | Only conversations started at/after this instant. Accepts a date (2026-05-01) or a date-time (2026-05-01T00:00:00Z). |
created_before | ISO 8601 | Only conversations started at/before this instant. |
updated_after | ISO 8601 | Incremental sync: only conversations updated at/after this instant (a new message bumps updated_at). |
include | string | Comma-separated opt-in set: messages (inline the transcript with nested events), contact (inline contact PII). |
handoff_status | string | Filter by status: ai_active, queued, human_active. |
limit | integer | Items per page (1 to 100). Defaults to 50. |
cursor | string | Opaque cursor returned as next_cursor in the previous page. Omit on the first call. |
Cursor pagination
The response returns up to limit items plus a next_cursor. Pass it back as cursor to fetch the next page. When next_cursor is null, you've reached the end. The cursor is opaque: don't parse it; the format may change in a future version.
Request
curl "https://api.thehumind.com/public/v1/conversations?created_after=2026-05-01&limit=50" \
-H "Authorization: Bearer hmd_live_..."Response 200 OK
{
"data": [
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e5f",
"created_at": "2026-05-15T10:00:00Z",
"updated_at": "2026-05-15T10:05:00Z",
"last_message_at": "2026-05-15T10:05:00Z",
"origin": "shopify",
"origin_url": "https://example.com/products/creme-hydratante",
"language": ["fr"],
"title": "Question sur la crème hydratante",
"handoff_status": "ai_active",
"tags": ["high-intent", "skincare"],
"has_triggered_cart": true,
"contact_id": "65f1c0de8e7d4a2b1c3d4e70"
}
],
"next_cursor": "eyJpZCI6IjY1ZjFhYjljOGU3ZDRhMmIxYzNkNGU1ZiJ9"
}To inline the transcript and interaction events in a single sweep:
curl "https://api.thehumind.com/public/v1/conversations?created_after=2026-05-01&include=messages&limit=25" \
-H "Authorization: Bearer hmd_live_..."Retrieve a conversation
GET /conversations/{id} returns a single conversation with its full message transcript (each message with its nested interaction events). {id} is the conversation humind_id.
Required scope: conversations:read
| Query parameter | Type | Description |
|---|---|---|
include | string | Pass contact to inline customer contact PII. The transcript (messages) is always included on this endpoint. |
Request
curl https://api.thehumind.com/public/v1/conversations/65f1ab9c8e7d4a2b1c3d4e5f \
-H "Authorization: Bearer hmd_live_..."Response 200 OK
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e5f",
"created_at": "2026-05-15T10:00:00Z",
"updated_at": "2026-05-15T10:05:00Z",
"last_message_at": "2026-05-15T10:05:00Z",
"origin": "shopify",
"language": ["fr"],
"handoff_status": "ai_active",
"tags": ["high-intent", "skincare"],
"has_triggered_cart": true,
"contact_id": "65f1c0de8e7d4a2b1c3d4e70",
"message_count": 3,
"event_count": 1,
"messages": [
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e60",
"from": "user",
"role": "conversation",
"source": "typed",
"content": ["Vous l'avez en 50 ml ?"],
"created_at": "2026-05-15T10:01:00Z"
},
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e61",
"from": "assistant",
"role": "answer",
"content": ["Oui, la crème hydratante existe en 50 ml."],
"created_at": "2026-05-15T10:01:30Z",
"product_ids": ["65f1aa008e7d4a2b1c3d4e10"]
},
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e62",
"from": "user",
"role": "conversation",
"content": ["Parfait, je la prends."],
"created_at": "2026-05-15T10:02:00Z",
"events": [
{
"humind_id": "65f1ab9c8e7d4a2b1c3d4e80",
"type": "add_product",
"created_at": "2026-05-15T10:02:05Z",
"product_id": "65f1aa008e7d4a2b1c3d4e10",
"product_title": "Crème hydratante",
"product_variant_id": "65f1aa008e7d4a2b1c3d4e11",
"price_at_event": 29.90
}
]
}
]
}To include contact details:
curl "https://api.thehumind.com/public/v1/conversations/65f1ab9c8e7d4a2b1c3d4e5f?include=contact" \
-H "Authorization: Bearer hmd_live_..."The contact_id field is then replaced by a contact object:
{
"contact": {
"id": "65f1c0de8e7d4a2b1c3d4e70",
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "+33123456789"
}
}Recipes
Export a date range
Page through everything that started in a window:
# First page
curl "https://api.thehumind.com/public/v1/conversations?created_after=2026-05-01&created_before=2026-06-01&include=messages&limit=50" \
-H "Authorization: Bearer hmd_live_..."
# Next page: pass the previous response's next_cursor
curl "https://api.thehumind.com/public/v1/conversations?created_after=2026-05-01&created_before=2026-06-01&include=messages&limit=50&cursor=PASTE_NEXT_CURSOR" \
-H "Authorization: Bearer hmd_live_..."Keep following next_cursor until it comes back null.
Incremental sync
Pull only what changed since your last run. Store the timestamp of your previous sync and pass it as updated_after:
curl "https://api.thehumind.com/public/v1/conversations?updated_after=2026-06-07T00:00:00Z&include=messages" \
-H "Authorization: Bearer hmd_live_..."This returns every conversation touched (new message, handoff, tag change) since that instant, ideal for a nightly ETL into your warehouse.
Common errors
| Status | Code | When | Fix |
|---|---|---|---|
400 | validation_failed | Bad date format, invalid cursor, or malformed {id}. details points to the issue. | Fix the parameter and resend. |
401 | missing_credentials, invalid_key, revoked | Auth header missing, malformed, or the key is no longer active. | See Authentication. |
403 | insufficient_scope | Key lacks conversations:read. | Create a key with the conversations:read scope. |
404 | not_found | {id} doesn't match a conversation owned by your company (cross-tenant and playground ids also return 404). | Confirm the humind_id. |
429 | rate_limited | Too many requests for this key. | Back off using the Retry-After header. See Rate limits. |
Next
- Authentication: generate a
conversations:readkey. - Conventions: dates, pagination, identifiers.
- Errors: full error code reference.