Help desks

The support inbox: desks, conversations, messages, and their events.

A help desk is a support inbox with its own agents, rules and help center. Through the API you can run one without opening the product: bring conversations in from your own systems, reply and take notes, assign and solve, and keep an exact copy of every thread.

A key acts as its owner. Reading needs help_desk:read. Anything written as someone (a reply, an assignment, a status change) needs help_desk:respond and the key's owner must staff the desk, so the work is attributed to a real agent. Configuration needs help_desk:configure and, for someone who staffs the desk, the lead or admin desk role. Ids from another desk are treated as not existing: 404 in a path, 422 in a body.

Seven events describe what happens on a desk: helpdesk.conversation.created, helpdesk.conversation.assigned, helpdesk.conversation.solved, helpdesk.conversation.escalated (moved from the AI agent to a person), helpdesk.message.created (public messages only), helpdesk.sla.breached and helpdesk.csat.submitted. They carry ids and facts rather than message text; fetch the conversation or its timeline with your key for the content. Subscribing to them by webhook needs help_desk:read as well as the webhook capability.

List help desks#

Desks the key can open, newest first. That is the desks of the key's organization that its owner can reach: shared with the organization, created by them, or staffed by them.

GET/api/v1/help-desks

Query parameters

searchstring
Match name or description.
statusstring
`active`, `paused` or `archived`.
limitnumber
Page size, up to 100.
Default50
cursorstring
`meta.pagination.nextCursor` from the previous page.

Responses

The desks.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"helpDesks": [
{
"id": "8d1e…",
"name": "Member support",
"slug": "member-support",
"description": "Claims, billing and plan questions.",
"status": "active",
"defaultBrandId": "51aa…",
"defaultScheduleId": "c702…",
"defaultSlaPolicyId": "0e93…",
"settings": {
"autoCloseAfterMinutes": 5760,
"allowMessageEditing": true,
"messageEditWindowMinutes": 5,
"allowMessageDeletion": false,
"collisionDetection": true,
"reassignOnOffline": false,
"requireTagOnSolve": false,
"transcriptRetentionDays": null,
"redactionPatterns": []
},
"isOrgShared": true,
"createdAt": "2026-09-30T15:02:11.000Z",
"updatedAt": "2026-09-30T15:02:11.000Z",
"agentCount": 6
}
]
},
"meta": {
"requestId": "req_…",
"pagination": {
"nextCursor": null,
"limit": 50
}
}
}

Create a help desk#

A working desk: it arrives with a brand, business hours, an SLA policy, the standard inbox views and a starter set of tags, and the key's owner staffs it as its admin. Set `isOrgShared` to let the rest of the organization in; staffing a desk does not, on its own, give someone access to it.

POST/api/v1/help-desks

Body

application/json
name
string
required
description
string
slug
string (lowercase letters, digits, dashes)
timeZone
string (IANA zone for the seeded business hours)
isOrgShared
boolean

Responses

The created desk.

curl -X POST "https://voice.evryhealth.com/api/v1/help-desks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Member support",
"timeZone": "America/Chicago",
"isOrgShared": true
}'
Response201
{
"data": {
"id": "8d1e…",
"name": "Member support",
"slug": "member-support",
"description": "Claims, billing and plan questions.",
"status": "active",
"defaultBrandId": "51aa…",
"defaultScheduleId": "c702…",
"defaultSlaPolicyId": "0e93…",
"settings": {
"autoCloseAfterMinutes": 5760,
"allowMessageEditing": true,
"messageEditWindowMinutes": 5,
"allowMessageDeletion": false,
"collisionDetection": true,
"reassignOnOffline": false,
"requireTagOnSolve": false,
"transcriptRetentionDays": null,
"redactionPatterns": []
},
"isOrgShared": true,
"createdAt": "2026-09-30T15:02:11.000Z",
"updatedAt": "2026-09-30T15:02:11.000Z"
},
"meta": {
"requestId": "req_…"
}
}

Get a help desk#

One desk, with its settings and defaults.

GET/api/v1/help-desks/{helpDeskId}

Path parameters

helpDeskIdstringrequired
Help desk id.

Responses

The desk.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"id": "8d1e…",
"name": "Member support",
"slug": "member-support",
"description": "Claims, billing and plan questions.",
"status": "active",
"defaultBrandId": "51aa…",
"defaultScheduleId": "c702…",
"defaultSlaPolicyId": "0e93…",
"settings": {
"autoCloseAfterMinutes": 5760,
"allowMessageEditing": true,
"messageEditWindowMinutes": 5,
"allowMessageDeletion": false,
"collisionDetection": true,
"reassignOnOffline": false,
"requireTagOnSolve": false,
"transcriptRetentionDays": null,
"redactionPatterns": []
},
"isOrgShared": true,
"createdAt": "2026-09-30T15:02:11.000Z",
"updatedAt": "2026-09-30T15:02:11.000Z"
},
"meta": {
"requestId": "req_…"
}
}

Update a help desk#

Rename it, pause it, change its settings or defaults, or share it with the organization. Settings merge: send only the ones you are changing. Needs `help_desk:configure` and, for someone who staffs the desk, the lead or admin desk role.

PATCH/api/v1/help-desks/{helpDeskId}

Path parameters

helpDeskIdstringrequired
Help desk id.

Body

application/json
name
string
description
string
status
active | paused | archived
settings
object (any subset of the desk settings)
defaultBrandId
string
defaultScheduleId
string
defaultSlaPolicyId
string
isOrgShared
boolean

Responses

The updated desk.

curl -X PATCH "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"requireTagOnSolve": true
},
"isOrgShared": true
}'
Response200
{
"data": {
"id": "8d1e…",
"name": "Member support",
"slug": "member-support",
"description": "Claims, billing and plan questions.",
"status": "active",
"defaultBrandId": "51aa…",
"defaultScheduleId": "c702…",
"defaultSlaPolicyId": "0e93…",
"settings": {
"autoCloseAfterMinutes": 5760,
"allowMessageEditing": true,
"messageEditWindowMinutes": 5,
"allowMessageDeletion": false,
"collisionDetection": true,
"reassignOnOffline": false,
"requireTagOnSolve": false,
"transcriptRetentionDays": null,
"redactionPatterns": []
},
"isOrgShared": true,
"createdAt": "2026-09-30T15:02:11.000Z",
"updatedAt": "2026-09-30T15:02:11.000Z"
},
"meta": {
"requestId": "req_…"
}
}

Delete a help desk#

Archives the desk. Its conversations are support history and are kept; the desk stops appearing anywhere. Needs `help_desk:delete`.

DELETE/api/v1/help-desks/{helpDeskId}

Path parameters

helpDeskIdstringrequired
Help desk id.

Responses

Deleted.

curl -X DELETE "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"deleted": true
},
"meta": {
"requestId": "req_…"
}
}

List conversations#

Conversations on the desk. Narrow with a saved view, an inline filter in the same grammar views use, a search, or your own `externalRef`. Snoozed conversations are left out unless asked for.

GET/api/v1/help-desks/{helpDeskId}/conversations

Path parameters

helpDeskIdstringrequired
Help desk id.

Query parameters

viewIdstring
A saved view on this desk.
filterstring
A JSON filter group, for example `{"op":"and","rules":[{"field":"priority","op":"eq","value":"urgent"}]}`.
searchstring
Subject, contact name or email, and message text.
externalRefstring
Exact match on the reference you set when creating it.
sortstring
lastMessageAt, createdAt, updatedAt, priority, status, nextSlaDueAt, waitingSince, csatScore, sentiment, contactName, companyName, assignedAgentName or messageCount.
directionstring
`asc` or `desc`.
includeSnoozedboolean
Include snoozed conversations.
Defaultfalse
limitnumber
Page size, up to 200.
Default50
cursorstring
`meta.pagination.nextCursor` from the previous page.

Responses

The conversations, in the shape an inbox list needs.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"conversations": [
{
"id": "2b6f…",
"helpDeskId": "8d1e…",
"channel": "api",
"subject": "Card declined at checkout",
"status": "open",
"priority": "high",
"assignedAgentId": "a41c…",
"assignedAgentName": "Sam",
"teamId": null,
"handledBy": "human",
"contactId": "f0d2…",
"contactName": "Casey Rivera",
"contactEmail": "casey@example.com",
"lastMessageAt": "2026-09-30T15:04:52.000Z",
"lastMessagePreview": "My card was declined at checkout.",
"lastMessageSenderType": "contact",
"messageCount": 1,
"awaitingReplySince": "2026-09-30T15:04:52.000Z",
"nextSlaDueAt": "2026-09-30T16:04:52.000Z",
"hasSlaBreach": false,
"tags": [
{
"id": "77c0…",
"name": "billing",
"color": "#2563eb"
}
],
"createdAt": "2026-09-30T15:04:52.000Z",
"updatedAt": "2026-09-30T15:04:52.000Z"
}
]
},
"meta": {
"requestId": "req_…",
"pagination": {
"nextCursor": "bzo1MA",
"limit": 50
}
}
}

Create a conversation#

Bring support work in from somewhere else: an email system, a form, your own app. Name an existing contact, or describe one. An `externalId` you send is treated as verified, so the same customer always resolves to the same contact; details without one create a new, unidentified contact. The opening message is the customer's unless `from` says `agent`. Sending the same `externalRef` again returns the conversation it already created, with 200 and nothing appended, so a retried request never makes a duplicate. The key's owner must staff the desk. Assigning needs `help_desk:assign` as well.

POST/api/v1/help-desks/{helpDeskId}/conversations

Path parameters

helpDeskIdstringrequired
Help desk id.

Body

application/json
contactId
string (or contact)
contact
{ externalId?, email?, name?, phone? }
subject
string
channel
api | chat | email (default api)
priority
low | normal | high | urgent
brandId
string
externalRef
string (your own id, for finding it again)
customFields
object
tagIds
string[]
assignedAgentId
string
teamId
string
message
{ body: string, from?: contact | agent }

Responses

The conversation.

curl -X POST "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact": {
"externalId": "cust_4821",
"email": "casey@example.com",
"name": "Casey Rivera"
},
"subject": "Card declined at checkout",
"priority": "high",
"externalRef": "ticket-99812",
"message": {
"body": "My card was declined at checkout."
}
}'
Response201
{
"data": {
"id": "2b6f…",
"helpDeskId": "8d1e…",
"channel": "api",
"subject": "Card declined at checkout",
"status": "open",
"priority": "high",
"assignedAgentId": "a41c…",
"assignedAgentName": "Sam",
"teamId": null,
"handledBy": "human",
"contactId": "f0d2…",
"contactName": "Casey Rivera",
"contactEmail": "casey@example.com",
"lastMessageAt": "2026-09-30T15:04:52.000Z",
"lastMessagePreview": "My card was declined at checkout.",
"lastMessageSenderType": "contact",
"messageCount": 1,
"awaitingReplySince": "2026-09-30T15:04:52.000Z",
"nextSlaDueAt": "2026-09-30T16:04:52.000Z",
"hasSlaBreach": false,
"tags": [
{
"id": "77c0…",
"name": "billing",
"color": "#2563eb"
}
],
"createdAt": "2026-09-30T15:04:52.000Z",
"updatedAt": "2026-09-30T15:04:52.000Z",
"brandId": "51aa…",
"sequence": 3,
"contact": {
"id": "f0d2…",
"externalId": "cust_4821",
"email": "casey@example.com",
"name": "Casey Rivera",
"isIdentified": true
},
"externalRef": "ticket-99812",
"customFields": {
"region": "midwest"
},
"slaClocks": [
{
"metric": "first_reply",
"targetMinutes": 60,
"dueAt": "2026-09-30T16:04:52.000Z",
"state": "ok"
}
],
"liveSessions": [],
"followers": [
{
"agentId": "a41c…",
"name": "Sam"
}
]
},
"meta": {
"requestId": "req_…"
}
}

Get a conversation#

One conversation with its contact, SLA clocks and followers. `sequence` is the last position in its timeline; see the timeline endpoint.

GET/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.

Responses

The conversation.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"id": "2b6f…",
"helpDeskId": "8d1e…",
"channel": "api",
"subject": "Card declined at checkout",
"status": "open",
"priority": "high",
"assignedAgentId": "a41c…",
"assignedAgentName": "Sam",
"teamId": null,
"handledBy": "human",
"contactId": "f0d2…",
"contactName": "Casey Rivera",
"contactEmail": "casey@example.com",
"lastMessageAt": "2026-09-30T15:04:52.000Z",
"lastMessagePreview": "My card was declined at checkout.",
"lastMessageSenderType": "contact",
"messageCount": 1,
"awaitingReplySince": "2026-09-30T15:04:52.000Z",
"nextSlaDueAt": "2026-09-30T16:04:52.000Z",
"hasSlaBreach": false,
"tags": [
{
"id": "77c0…",
"name": "billing",
"color": "#2563eb"
}
],
"createdAt": "2026-09-30T15:04:52.000Z",
"updatedAt": "2026-09-30T15:04:52.000Z",
"brandId": "51aa…",
"sequence": 3,
"contact": {
"id": "f0d2…",
"externalId": "cust_4821",
"email": "casey@example.com",
"name": "Casey Rivera",
"isIdentified": true
},
"externalRef": "ticket-99812",
"customFields": {
"region": "midwest"
},
"slaClocks": [
{
"metric": "first_reply",
"targetMinutes": 60,
"dueAt": "2026-09-30T16:04:52.000Z",
"state": "ok"
}
],
"liveSessions": [],
"followers": [
{
"agentId": "a41c…",
"name": "Sam"
}
]
},
"meta": {
"requestId": "req_…"
}
}

Update a conversation#

Any of the fields an agent changes, in one request, applied in the order the inbox applies them so the timeline reads correctly: status last. Reassigning needs `help_desk:assign`; taking a conversation off the AI agent needs `help_desk:escalate`. The desk's own rules hold, including a required tag before solving.

PATCH/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.

Body

application/json
status
open | pending | on_hold | solved | closed
priority
low | normal | high | urgent
assignedAgentId
string | null
teamId
string | null
subject
string | null
tagIds
string[] (replaces the set)
customFields
object
snoozeUntil
ISO 8601 date-time in the future
handoffToHuman
true

Responses

The updated conversation.

curl -X PATCH "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "solved",
"tagIds": [
"77c0…"
]
}'
Response200
{
"data": {
"id": "2b6f…",
"helpDeskId": "8d1e…",
"channel": "api",
"subject": "Card declined at checkout",
"status": "solved",
"priority": "high",
"assignedAgentId": "a41c…",
"assignedAgentName": "Sam",
"teamId": null,
"handledBy": "human",
"contactId": "f0d2…",
"contactName": "Casey Rivera",
"contactEmail": "casey@example.com",
"lastMessageAt": "2026-09-30T15:04:52.000Z",
"lastMessagePreview": "My card was declined at checkout.",
"lastMessageSenderType": "contact",
"messageCount": 1,
"awaitingReplySince": "2026-09-30T15:04:52.000Z",
"nextSlaDueAt": "2026-09-30T16:04:52.000Z",
"hasSlaBreach": false,
"tags": [
{
"id": "77c0…",
"name": "billing",
"color": "#2563eb"
}
],
"createdAt": "2026-09-30T15:04:52.000Z",
"updatedAt": "2026-09-30T15:04:52.000Z",
"brandId": "51aa…",
"sequence": 3,
"contact": {
"id": "f0d2…",
"externalId": "cust_4821",
"email": "casey@example.com",
"name": "Casey Rivera",
"isIdentified": true
},
"externalRef": "ticket-99812",
"customFields": {
"region": "midwest"
},
"slaClocks": [
{
"metric": "first_reply",
"targetMinutes": 60,
"dueAt": "2026-09-30T16:04:52.000Z",
"state": "ok"
}
],
"liveSessions": [],
"followers": [
{
"agentId": "a41c…",
"name": "Sam"
}
]
},
"meta": {
"requestId": "req_…"
}
}

List messages#

The thread, oldest first within a page, internal notes included. Pages go backwards from the newest message: pass `nextCursor` to get the ones before.

GET/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.

Query parameters

limitnumber
Page size, up to 200.
Default50
cursorstring
`meta.pagination.nextCursor` from the previous page.

Responses

The messages.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"messages": [
{
"id": "9c3a…",
"conversationId": "2b6f…",
"seqNumber": 4,
"senderType": "agent",
"senderAgentId": "a41c…",
"senderContactId": null,
"senderName": "Sam from Support",
"body": "Thanks Casey, I can see the decline. Looking into it now.",
"contentType": "text",
"visibility": "public",
"deliveryState": "sent",
"replyToMessageId": null,
"metadata": {},
"editedAt": null,
"deletedAt": null,
"createdAt": "2026-09-30T15:06:10.000Z",
"attachments": [],
"reactions": []
}
]
},
"meta": {
"requestId": "req_…",
"pagination": {
"nextCursor": "4",
"limit": 50
}
}
}

Send a message#

Reply as the key's owner, add an internal note, or record a message from the customer that arrived somewhere else (`from: contact`). Agent replies get the desk's placeholders resolved and the signature added, exactly as in the inbox. Attach files uploaded to this conversation by id.

POST/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.

Body

application/json
body
string
required
from
agent | contact (default agent)
visibility
public | internal (default public; contact messages are always public)
attachmentIds
string[]
replyToMessageId
string
mentionedAgentIds
string[]

Responses

The message.

curl -X POST "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi {{contact.firstName}}, looking into it now."
}'
Response201
{
"data": {
"id": "9c3a…",
"conversationId": "2b6f…",
"seqNumber": 4,
"senderType": "agent",
"senderAgentId": "a41c…",
"senderContactId": null,
"senderName": "Sam from Support",
"body": "Thanks Casey, I can see the decline. Looking into it now.",
"contentType": "text",
"visibility": "public",
"deliveryState": "sent",
"replyToMessageId": null,
"metadata": {},
"editedAt": null,
"deletedAt": null,
"createdAt": "2026-09-30T15:06:10.000Z",
"attachments": [],
"reactions": []
},
"meta": {
"requestId": "req_…"
}
}

Get a message#

One message.

GET/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.
messageIdstringrequired
Message id.

Responses

The message.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"id": "9c3a…",
"conversationId": "2b6f…",
"seqNumber": 4,
"senderType": "agent",
"senderAgentId": "a41c…",
"senderContactId": null,
"senderName": "Sam from Support",
"body": "Thanks Casey, I can see the decline. Looking into it now.",
"contentType": "text",
"visibility": "public",
"deliveryState": "sent",
"replyToMessageId": null,
"metadata": {},
"editedAt": null,
"deletedAt": null,
"createdAt": "2026-09-30T15:06:10.000Z",
"attachments": [],
"reactions": []
},
"meta": {
"requestId": "req_…"
}
}

Edit a message#

Change the text of a message the key's owner sent, within the desk's edit window and only when the desk allows editing.

PATCH/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.
messageIdstringrequired
Message id.

Body

application/json
body
string
required

Responses

The edited message.

curl -X PATCH "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Corrected reply."
}'
Response200
{
"data": {
"id": "9c3a…",
"conversationId": "2b6f…",
"seqNumber": 4,
"senderType": "agent",
"senderAgentId": "a41c…",
"senderContactId": null,
"senderName": "Sam from Support",
"body": "Thanks Casey, I can see the decline. Looking into it now.",
"contentType": "text",
"visibility": "public",
"deliveryState": "sent",
"replyToMessageId": null,
"metadata": {},
"editedAt": "2026-09-30T15:07:01.000Z",
"deletedAt": null,
"createdAt": "2026-09-30T15:06:10.000Z",
"attachments": [],
"reactions": []
},
"meta": {
"requestId": "req_…"
}
}

Delete a message#

Redact a message when the desk allows deletion. Agents may redact their own; leads and admins anyone's, including the customer's. The message keeps its place in the thread without its text.

DELETE/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.
messageIdstringrequired
Message id.

Responses

Deleted.

curl -X DELETE "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/messages/{messageId}" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"deleted": true
},
"meta": {
"requestId": "req_…"
}
}

Conversation timeline#

Everything that happened in a conversation after a sequence number: messages and events (assignments, status changes, tags, SLA) in one ordered stream. Sequence numbers are gapless and shared by both, so storing the last one you processed and asking for what came after it keeps an exact mirror.

GET/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/timeline

Path parameters

helpDeskIdstringrequired
Help desk id.
conversationIdstringrequired
Conversation id.

Query parameters

afternumber
Return entries after this sequence number.
Default0
cursorstring
`meta.pagination.nextCursor` from the previous page.
limitnumber
Page size, up to 500.
Default100

Responses

The entries, in sequence order.

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/{helpDeskId}/conversations/{conversationId}/timeline" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"data": {
"entries": [
{
"type": "event",
"sequence": 1,
"event": {
"eventType": "conversation.created",
"actorType": "system",
"data": {
"channel": "api"
}
}
},
{
"type": "message",
"sequence": 2,
"message": {
"id": "9c3a…",
"conversationId": "2b6f…",
"seqNumber": 4,
"senderType": "agent",
"senderAgentId": "a41c…",
"senderContactId": null,
"senderName": "Sam from Support",
"body": "Thanks Casey, I can see the decline. Looking into it now.",
"contentType": "text",
"visibility": "public",
"deliveryState": "sent",
"replyToMessageId": null,
"metadata": {},
"editedAt": null,
"deletedAt": null,
"createdAt": "2026-09-30T15:06:10.000Z",
"attachments": [],
"reactions": []
}
},
{
"type": "event",
"sequence": 3,
"event": {
"eventType": "conversation.assigned",
"actorType": "agent",
"data": {
"agentId": "a41c…"
}
}
}
]
},
"meta": {
"requestId": "req_…",
"pagination": {
"nextCursor": null,
"limit": 100
}
}
}

Help desk event stream#

Help desk events as they happen, as server-sent events, for a key that can read help desks. Only events for desks the key can open are sent. Resume with `Last-Event-ID`. The same events also arrive on the organization stream and through webhooks.

GET/api/v1/help-desks/events

Query parameters

helpDeskIdstring
Only this desk's events. Required to follow a desk another organization shared with yours, whose events are published to that organization.
typesstring
Comma-separated event types to narrow to.
lastEventIdstring
Resume point. The `Last-Event-ID` header does the same thing.

Responses

An event stream (text/event-stream).

curl -X GET "https://voice.evryhealth.com/api/v1/help-desks/events" \
-H "Authorization: Bearer YOUR_API_KEY"
Response200
{
"event": "helpdesk.message.created",
"id": "1790000502113-0",
"data": {
"type": "helpdesk.message.created",
"organizationId": "7380…",
"occurredAt": "2026-09-30T15:06:10.000Z",
"data": {
"helpDeskId": "8d1e…",
"conversationId": "2b6f…",
"messageId": "9c3a…",
"sequence": 4,
"senderType": "agent"
}
}
}