Conversations

View as Markdown

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’s id, name and email.
  • 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.