Conversations
A conversation is one thread between a customer and your team or the AI agent. Requests use your secret API key as a bearer token. See authentication.
The conversation object
| Field | Type | Meaning |
|---|---|---|
id |
string | The conversation id. |
status |
string | open, snoozed or closed. |
customer_id |
string | The customer in the conversation. |
assignee_id |
string or null | The team member who owns it, or null when unassigned. |
handled_by |
string | ai when the AI agent is handling it, otherwise team. |
channel |
string | Where it started: widget, email or api. |
subject |
string or null | The subject line, when there is one. |
tags |
array of strings | Tag names on the conversation. |
snoozed_until |
string or null | When a snoozed conversation returns to open. |
last_message_at |
string or null | Time of the latest message. |
created_at |
string | When it started. |
updated_at |
string | When it last changed. |
List conversations
GET/api/v1/conversations
Needs the conversations:read scope. Newest first.
| Parameter | Type | What it does |
|---|---|---|
status |
string | One of open, snoozed or closed. |
assignee_id |
string | Only conversations assigned to this team member. |
handled_by |
string | ai or team. |
tag |
string | Only conversations with this tag, by name or id. |
customer_id |
string | Only conversations of this customer. |
limit |
integer | Page size, 1 to 100. Defaults to 25. |
cursor |
string | The next_cursor from the previous page. |
curl
curl "https://app.tirver.com/api/v1/conversations?status=open" \
-H "Authorization: Bearer $TIRVER_API_KEY"
JavaScript
const res = await fetch('https://app.tirver.com/api/v1/conversations?status=open', {
headers: { Authorization: `Bearer ${process.env.TIRVER_API_KEY}` },
});
const { data, next_cursor, has_more } = await res.json();
Python
res = requests.get(
"https://app.tirver.com/api/v1/conversations",
params={"status": "open"},
headers={"Authorization": f"Bearer {os.environ['TIRVER_API_KEY']}"},
timeout=10,
)
data = res.json()["data"]
{
"data": [
{
"id": "8c1f0d52",
"status": "open",
"customer_id": "3b7a91e4",
"assignee_id": null,
"handled_by": "ai",
"channel": "widget",
"subject": "Cannot log in",
"tags": ["bug"],
"snoozed_until": null,
"last_message_at": "2026-11-14T09:05:00.000Z",
"created_at": "2026-11-14T09:02:00.000Z",
"updated_at": "2026-11-14T09:05:00.000Z"
}
],
"next_cursor": null,
"has_more": false
}
Get a conversation
GET/api/v1/conversations/{id}
Needs conversations:read. Returns the conversation fields above, plus:
customer: the customer’sid,nameandemail.summary: a short plain extract of the thread (the first customer message, the latest, and the number of replies). It is not an AI summary.messages: up to the first 500 messages, oldest first, internal notes included.
curl https://app.tirver.com/api/v1/conversations/8c1f0d52 \
-H "Authorization: Bearer $TIRVER_API_KEY"
List messages
GET/api/v1/conversations/{id}/messages
Needs conversations:read. Oldest first. Takes limit and cursor. Each message looks like this.
| Field | Type | Meaning |
|---|---|---|
id |
string | The message id. |
conversation_id |
string | The conversation it belongs to. |
type |
string | reply is visible to the customer. note is internal. |
sender |
string | customer, agent or ai. |
author_id |
string or null | The team member or customer id. Null for the AI agent. |
body |
string | The text. |
citations |
array | Sources the AI agent used, each with title and url. |
created_at |
string | When it was sent. |
Reply to a conversation
POST/api/v1/conversations/{id}/messages
Needs conversations:write. A reply reaches the customer and takes the conversation off the AI agent. A note stays with your team. Returns 201 with the new message.
| Field | Type | What it does |
|---|---|---|
body |
string | Required. The message text, 1 to 4000 characters. |
type |
string | Required: reply or note. There is no default, so a note is never sent as a reply by leaving it out. |
author_id |
string | Optional. The team member the message is from. Defaults to the person who created the key. |
curl
curl https://app.tirver.com/api/v1/conversations/8c1f0d52/messages \
-H "Authorization: Bearer $TIRVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"body": "Thanks, we have fixed this.", "type": "reply"}'
JavaScript
await fetch('https://app.tirver.com/api/v1/conversations/8c1f0d52/messages', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.TIRVER_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ body: 'Thanks, we have fixed this.', type: 'reply' }),
});
Python
requests.post(
"https://app.tirver.com/api/v1/conversations/8c1f0d52/messages",
headers={"Authorization": f"Bearer {os.environ['TIRVER_API_KEY']}"},
json={"body": "Thanks, we have fixed this.", "type": "reply"},
timeout=10,
)
{
"id": "5d2e7a10",
"conversation_id": "8c1f0d52",
"type": "reply",
"sender": "agent",
"author_id": "u_1",
"body": "Thanks, we have fixed this.",
"citations": [],
"created_at": "2026-11-15T10:00:00.000Z"
}
Close a conversation
POST/api/v1/conversations/{id}/close
Needs conversations:write. Returns the conversation with status set to closed. Closing sends no message to the customer.
A conversation the AI agent answered, that no person touched, can count as an AI resolution when it is closed. See what counts as a resolution.