Conversations
Conversations are the core resource in oHallo. Each conversation represents a message thread between a customer contact and oHallo on a single channel.
Required scope: conversations:read for GET endpoints, conversations:write for POST endpoints.
List conversations
Section titled “List conversations”Retrieve conversations for a workspace, optionally filtered by status or contact.
curl "https://api.ohallo.eu/api/conversations?workspaceId=a1b2c3d4-e5f6-7890-abcd-ef1234567890&status=open&limit=50" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | UUID | No | Filter by workspace |
status | string | No | Filter by status: open, in_progress, awaiting_contact, resolved, closed, abandoned |
contactId | UUID | No | Filter by contact |
accountId | UUID | No | Filter by account |
q | string | No | Free-text search across contact name / email / subject |
humanManaged | boolean | No | Filter to conversations currently owned by a human operator |
hasAttention | boolean | No | Filter to conversations with one or more open attention items |
limit | integer | No | Page size (default 50, max 100) |
cursor | string | No | Opaque pagination cursor from a previous response’s nextCursor |
Response:
{ "data": [ { "id": "c9f8e7d6-b5a4-3210-fedc-ba9876543210", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "channelId": "d4e5f6a7-b8c9-0123-4567-890abcdef012", "contactId": "f7e8d9c0-b1a2-3456-7890-abcdef123456", "status": "open", "lastMessagePreview": "Hi, I placed order NP-2026-0142 last week. Can you tell me when...", "lastMessageAt": "2026-03-15T14:30:00.000Z", "contactName": "Henrik Larsen", "contactEmail": "henrik@nordic-parts.dk", "accountName": "Nordic Parts ApS" } ], "nextCursor": "eyJsYXN0SWQiOiJjOWY4ZTdkNi1iNWE0LTMyMTAtZmVkYy1iYTk4NzY1NDMyMTAifQ=="}Pagination is cursor-based: pass the nextCursor value from one response as the cursor query param of the next. When the response omits nextCursor, there are no more items. Optional fields (contactName, contactEmail, accountName, humanManaged, formType, autoResolved, lastTurnRoutingPath) are only included on conversations that have those signals — do not rely on their presence in every item.
Get conversation
Section titled “Get conversation”Retrieve full details for a single conversation: the conversation row, the resolved contact + account records, the message history, the per-turn context entries, and any attention items raised by the AI pipeline.
curl "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "id": "c9f8e7d6-b5a4-3210-fedc-ba9876543210", "tenantId": "10000000-0000-4000-8000-000000000001", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "channelId": "d4e5f6a7-b8c9-0123-4567-890abcdef012", "channelType": "email", "contactId": "f7e8d9c0-b1a2-3456-7890-abcdef123456", "accountId": "33445566-7788-99aa-bbcc-ddeeff001122", "status": "in_progress", "stateSummary": "Customer inquired about delivery date for order NP-2026-0142...", "outcome": null, "humanManagingUserId": null, "lastActivityAt": "2026-03-15T14:35:00.000Z", "createdAt": "2026-03-15T09:12:00.000Z", "updatedAt": "2026-03-15T14:35:00.000Z", "contact": { "id": "f7e8d9c0-...", "firstName": "Henrik", "lastName": "Larsen", "email": "henrik@nordic-parts.dk" }, "account": { "id": "33445566-...", "name": "Nordic Parts ApS" }, "history": [ /* array of message objects — see Get messages below */ ], "contextEntries": [ /* KB + policy entries the AI used on the latest turn */ ], "attentionItems": [ /* attention items raised for this conversation */ ]}The contact, account, history, contextEntries, and attentionItems fields are only present when the corresponding upstream fetch succeeds. There is no subject or messageCount field — stateSummary holds the AI-maintained running summary, and the history array length gives you the count.
Get messages
Section titled “Get messages”Retrieve the message history for a conversation, ordered chronologically.
curl "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/messages" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: returns a bare array of message objects, ordered chronologically.
[ { "id": "11111111-2222-3333-4444-555555555555", "direction": "inbound", "speaker": null, "body": "Hi, I placed order NP-2026-0142 last week. Can you tell me when it will be delivered?", "sentAt": "2026-03-15T09:12:01.000Z", "channel": "email", "fromAddress": "henrik@nordic-parts.dk", "subject": "Question about order #NP-2026-0142" }, { "id": "66666666-7777-8888-9999-aaaaaaaaaaaa", "direction": "outbound", "speaker": null, "body": "Hello Henrik,\n\nThank you for reaching out...", "sentAt": "2026-03-15T09:12:45.000Z", "channel": "email" }]fromAddress and subject are present when the source channel carries them (typically email). On voice channels, every message has direction: "inbound" but speaker is set to "caller" or "ai" so consumers can render call transcripts correctly.
Get attachments
Section titled “Get attachments”Retrieve attachments for a conversation.
curl "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/attachments" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: returns a bare array of attachment objects.
[ { "id": "aaaabbbb-cccc-dddd-eeee-ffffffffffff", "messageId": "11111111-2222-3333-4444-555555555555", "fileName": "purchase-order.pdf", "mimeType": "application/pdf", "sizeBytes": 245780, "status": "ready", "createdAt": "2026-03-15T09:12:01.000Z" }]Reply to conversation
Section titled “Reply to conversation”Send a human-authored reply. This signals the conversation workflow to deliver the message via the original channel.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/reply" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "content": "Henrik, I have just confirmed with our warehouse -- your order shipped this morning. Tracking number: DHL-98765432. You should receive it by end of day tomorrow." }'Response:
{ "ok": true}Resolve conversation
Section titled “Resolve conversation”Mark a conversation as resolved, optionally with an outcome description.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/resolve" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "outcome": "Delivery date confirmed, customer satisfied" }'Response:
{ "ok": true}Take over conversation
Section titled “Take over conversation”Pause the AI pipeline and take manual control of the conversation. While taken over, the AI will not process new messages or send automatic replies.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/take-over" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Release conversation
Section titled “Release conversation”Release a taken-over conversation back to the AI pipeline. The AI resumes processing on the next inbound message.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/release" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Compose outbound conversation
Section titled “Compose outbound conversation”Start a new outbound conversation. This creates a conversation, resolves or creates the contact, and delivers the first message.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/compose" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "channelId": "d4e5f6a7-b8c9-0123-4567-890abcdef012", "contactEmail": "anna@scandinavian-imports.se", "contactName": "Anna Johansson", "content": "Hello Anna,\n\nFollowing up on our conversation about the Q2 catalogue. The new product line is now available. Would you like me to send over the updated pricing?" }'Response:
{ "conversationId": "new_conv_id-1234-5678-9abc-def012345678"}Attention items
Section titled “Attention items”Attention items are flags raised by the AI pipeline when something requires human review — for example, an MCP tool failure, a discrepancy between KB entries, or a validation failure.
List attention items
Section titled “List attention items”curl "https://api.ohallo.eu/api/attention-items?workspaceId=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | UUID | No | Filter to a single workspace |
status | string | No | open, acknowledged, resolved, or dismissed (default returns all) |
conversationId | UUID | No | Filter to a single conversation |
Response: returns a bare array of attention items.
[ { "id": "11112222-3333-4444-5555-666677778888", "tenantId": "10000000-0000-4000-8000-000000000001", "conversationId": "c9f8e7d6-b5a4-3210-fedc-ba9876543210", "type": "mcp_failure", "status": "open", "context": { "toolName": "get_order", "error": "Connection timeout after 30s" }, "createdAt": "2026-03-15T14:30:00.000Z", "resolvedAt": null, "turnId": "98765432-1234-5678-90ab-cdef12345678", "assignedToUserId": null }]type is one of: validation_failed, approval_gate, escalation, mcp_failure, auth_failure, customer_reply_pending, expiry_warning. The context JSON object varies by type.
Resolve attention item
Section titled “Resolve attention item”curl -X POST "https://api.ohallo.eu/api/attention-items/11112222-3333-4444-5555-666677778888/resolve" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "reason": "Order delivered, customer confirmed receipt." }'Response: { "ok": true } on success, 404 if the attention item does not belong to your tenant.
Assign conversation
Section titled “Assign conversation”Assign a conversation to a specific user.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/assign" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "userId": "aabbccdd-eeff-4788-9233-445566778899" }'Unassign conversation
Section titled “Unassign conversation”Remove the assignment, returning the conversation to the shared queue.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/unassign" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Approve pending action
Section titled “Approve pending action”Approve a guardrail-gated tool call waiting for human approval. Resumes the AI pipeline.
Required scope: conversations:write
curl -X POST "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/approve" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Status counts
Section titled “Status counts”Get aggregate conversation counts by status for a workspace.
Required scope: conversations:read
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/conversations/status-counts" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "open": 12, "in_progress": 8, "awaiting_contact": 23, "resolved": 156, "closed": 4, "abandoned": 2}