Introduction
The Tirver REST API lets your own code work with your workspace: read conversations and reply to them, look up customers, read and draft help articles, file feedback, read the changelog and ask the AI agent a question. It is for servers and scripts you write. To let an AI assistant such as Claude work with your workspace, use the MCP server instead. Both use the same API key.
Base address
All requests go to one address and use HTTPS.
https://app.tirver.com/api/v1
Every endpoint on these pages is shown with its full path, for example /api/v1/conversations, so you can add it after https://app.tirver.com.
An OpenAPI 3.1 description of every endpoint is published at https://app.tirver.com/api/v1/openapi.json. It needs no key.
How it behaves
- Requests and responses are JSON. Send
Content-Type: application/jsonwith a body. - Every request is made on behalf of one workspace, the workspace that owns the API key.
- Field names are
snake_case. Times are ISO 8601 in UTC, for example2026-11-14T09:02:00.000Z. Ids are strings: treat them as opaque. - Lists are paged with a cursor. See pagination.
- Each key can make 120 requests a minute. See rate limits.
- No CORS headers are sent, so call the API from a server, not from a browser.
Your first request
Create an API key as described in authentication, then list your open conversations.
curl
curl "https://app.tirver.com/api/v1/conversations?status=open&limit=5" \
-H "Authorization: Bearer $TIRVER_API_KEY"
JavaScript
const res = await fetch('https://app.tirver.com/api/v1/conversations?status=open&limit=5', {
headers: { Authorization: `Bearer ${process.env.TIRVER_API_KEY}` },
});
if (!res.ok) throw new Error(`Tirver ${res.status}`);
const { data, next_cursor, has_more } = await res.json();
console.log(data.length, 'open conversations', has_more ? next_cursor : 'no more');
Python
import os, requests
res = requests.get(
"https://app.tirver.com/api/v1/conversations",
params={"status": "open", "limit": 5},
headers={"Authorization": f"Bearer {os.environ['TIRVER_API_KEY']}"},
timeout=10,
)
res.raise_for_status()
body = res.json()
print(len(body["data"]), "open conversations", body["next_cursor"])
A successful response looks like this.
{
"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
}
Other endpoints
Besides the resource pages, the API has a few small endpoints.
| Endpoint | Scope | What it does |
|---|---|---|
GET /api/v1/workspace |
none | Your workspace, and the name, prefix and scopes of the key you used. |
POST /api/v1/ask |
ai:ask |
Ask the AI agent a question. Returns answer and citations. Stores nothing and uses no credits. Limited to 10 a minute per key. |
GET /api/v1/credits |
credits:read |
balance, granted and spent, the same numbers as Settings, Billing. |
GET /api/v1/knowledge/sources |
knowledge:read |
The files, pages and sitemaps the AI agent learns from, with their status. Read only. |
GET /api/v1/search |
help-center:read |
Keyword search over published articles. See articles. |
What the API does not do
You cannot create or update customers, assign or snooze conversations, publish anything, change knowledge sources, move roadmap items or manage webhooks, and nothing can be edited or deleted. The only writes are replies and notes, closing a conversation, article drafts and feedback posts.
Where to go next
- Authentication explains keys and how to keep them safe.
- Permissions lists the scopes a key can hold.
- Errors and rate limits tell you how to handle trouble.
- The resource pages list every endpoint: conversations, customers, articles, feedback posts and changelog entries.