Skip to content
Chatvia Docs

REST API

Get in touch: Ahmad Mayahi, creator of Chatvia, Spectra and Shakomako

The Chatvia REST API lets your own software do what your team does in the dashboard. Your backend sends a request over HTTPS, and Chatvia answers with JSON.

Use it when a task should happen without a person clicking through the dashboard. Some examples:

  • Your shop adds a new product page. A script adds the page to the support agent's knowledge.
  • A customer signs up on your site. Your backend creates a chatter account for them and hands them a sign-in link to your agent.
  • Your CRM wants to show the agent's answer inside a ticket. It opens a conversation and sends the customer's question.
  • Your deploy pipeline runs the agent's evals and stops the release when the pass rate drops.

This section is for developers. Each page below covers one group of endpoints, with the parameters, a curl example and an example response.

Page What it covers
Agents List, create, update and delete agents. List saved prompts.
Sources Add and delete files, texts, websites and Q&A pairs.
Functions Manage webhook functions and attach them to agents.
Connectors Manage MCP servers and attach them to agents.
Conversations Chat with an agent, read and delete chat history.
Chatters Manage chatter accounts, their access and sign-in links.
Teams and users Manage teams, roles and who holds them.
Forms and leads Manage inline forms, read and export submissions.
Evals Start eval runs and read their results.
Topics Manage the topics conversations are tagged with.
Analytics and audit log Read usage numbers and the tool-call audit log.

A first request

This request lists your agents:

bash
curl https://chat.example.com/api/v1/agents \
  -H "Authorization: Bearer $CHATVIA_API_KEY"

The answer is one page of agents:

json
{
  "data": [
    {
      "id": "a3f9c2e17b4d08",
      "team": { "id": "0199f3a2-1c4e-7b1a-9d2e-5f6a7b8c9d01", "name": "Support" },
      "name": "Help Desk",
      "is_public": true,
      "metadata": {},
      "source": "dashboard",
      "system_instructions": "You answer questions about our shop.",
      "prompt_id": null,
      "slug": "help-desk",
      "url": "https://chat.example.com/chat/help-desk",
      "permanent_url": "https://chat.example.com/chat/a3f9c2e17b4d08",
      "created_at": "2026-10-01T08:12:44+00:00",
      "updated_at": "2026-10-20T15:03:10+00:00"
    }
  ],
  "next_cursor": null
}

Base URL

Every endpoint lives under /api/v1 on your Chatvia server:

text
https://chat.example.com/api/v1

Here https://chat.example.com stands for your install's own address (APP_URL). Use the address you open the dashboard on.

Send request bodies as JSON with Content-Type: application/json. The one exception is a file upload, which is multipart/form-data. See Add a file.

Authentication

Every request carries an API key. An API key is a secret string that tells Chatvia who is calling. Send it in the Authorization header as a bearer token:

text
Authorization: Bearer YOUR_API_KEY

To get a key, open Workspace → Integrations → API Keys and click Generate key. The key is shown once. API keys has the steps and tips for keeping keys safe.

Keep keys on your server. Never put a key in a web page or a mobile app, where anyone can read it.

A key stops working when:

  • someone clicks Revoke on it.
  • the account that made it is deactivated.
  • it is one year old. The admin of your Chatvia server can change this with SANCTUM_TOKEN_TTL_MINUTES in the environment file.

A request without a working key gets 401 Unauthorized.

Who a key acts as

A key acts as the person who generated it, with exactly the access that person has in the dashboard.

  • The workspace owner's key can call every endpoint.
  • A teammate's key can only do what the teammate's role allows. It sees only the agents the role reaches. Roles are set up in Teams & roles. A teammate's key uses the role of the team the teammate has open in the dashboard. When they switch teams there, the key follows.

Some endpoints are for the owner only, whatever a teammate's role says:

  • creating an agent
  • everything under /teams and /users

Each endpoint on the following pages names the permission it needs. The names are the ones you see when you edit a role in the dashboard. In short:

What you call Permission a teammate needs
Read an agent, its sources, functions, connectors and forms Access to the agent only
Open a conversation and send messages Access to the agent only
Update an agent Setup agent
Delete an agent Delete agent
Add a file, text, website or Q&A pair Train Files, Train Text, Train Web or Train Q&A
Delete a source Delete sources
Attach or detach a function Manage Functions
Attach or detach a connector, change forms Manage Connectors
List and read conversations and messages View conversations
Delete a conversation Delete conversations
Read form submissions View leads
Export form submissions Export leads
List and read eval runs View evals
Start an eval run Manage evals
Topics Manage topics
Analytics Chat analytics, Sentiment, Tones, Topics or Sources
An agent's audit log View audit log
Workspace functions Functions
Workspace connectors Connectors
Chatters and sign-in links Chatters
The prompt library Prompts
The workspace audit log Governance

Rate limits

A rate limit caps how many requests you can send in a minute. Chatvia counts per person, so all the keys of one person share one budget.

Requests Limit
All API requests 300 a minute
Sending a chat message 30 a minute, on top of the general limit
Exporting form submissions as CSV 10 a minute, shared with exports from the dashboard
Starting an eval run 6 a minute, shared with runs started in the dashboard

Sending a message has its own, lower limit because every message costs a reply from an AI model.

When you go over a limit, Chatvia answers 429 Too Many Requests:

json
{
  "message": "Too Many Attempts."
}

The Retry-After header says how many seconds to wait. Every answer also carries X-RateLimit-Limit and X-RateLimit-Remaining, so you can slow down before you hit the limit. For bulk jobs, such as adding a thousand pages, send a few requests at a time instead of all at once.

Errors

A request that fails gets an HTTP status code and a JSON body with a message. This holds even when you leave out the Accept: application/json header. The API never redirects you to a sign-in page or returns an HTML error page.

Status Meaning
200 OK Done. The body holds the result.
201 Created A new record was made. The body holds it.
204 No Content Done. There is no body, for example after a delete.
401 Unauthorized The key is missing, wrong, revoked or expired, or its account is deactivated.
403 Forbidden The key works, but its person may not do this. The permission is missing, the route is owner-only, or the agent is outside the teammate's role.
404 Not Found The record does not exist, belongs to another workspace, or belongs to another agent than the one in the path. A malformed id is a 404 too.
422 Unprocessable Content The request was understood, but a value is wrong or missing.
429 Too Many Requests You went over a rate limit. See above.

A 401 looks like this:

json
{
  "message": "Unauthenticated."
}

A 422 names each field that failed in errors:

json
{
  "message": "The name field is required. (and 1 more error)",
  "errors": {
    "name": ["The name field is required."],
    "is_public": ["The is_public field is required."]
  }
}

Some refusals that happen after the input checks also come back as a 422 on one field. For example, adding a text your workspace already has:

json
{
  "message": "This text is already in your knowledge base.",
  "errors": {
    "content": ["This text is already in your knowledge base."]
  }
}

A few routes answer 404 instead of 403 when the permission is missing, so they don't reveal that the record exists. The prompt library is one of them.

Sending a chat message has a few more error codes of its own. See Send a message.

Pagination

Every list endpoint returns one page of items, newest first, plus a next_cursor:

json
{
  "data": ["…"],
  "next_cursor": "eyJpZCI6MTg2LCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9"
}

To get the next page, send that value back as the cursor query parameter:

bash
curl "https://chat.example.com/api/v1/agents?cursor=eyJpZCI6MTg2LCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9" \
  -H "Authorization: Bearer $CHATVIA_API_KEY"

On the last page next_cursor is null. Stop there.

Query parameter Type Default Notes
per_page integer 25 How many items a page holds, from 1 to 100. A value outside that range is brought into range, not refused.
cursor string none The next_cursor of the previous page. Leave it out for the first page.

A cursor marks a place in the list, not a page number. Items added or deleted while you page through don't shift what you get. That is also why there are no page numbers and no total count. Treat the cursor as an opaque string: send back exactly what you received. A cursor that Chatvia did not hand out starts the list again at the first page.

IDs and dates

  • Most records are named by a UUID, such as 0199f3a2-7c4e-7b1a-9d2e-5f6a7b8c9d0e. The field is always called id in responses.
  • Agents have a shorter id of their own, 14 letters and digits, such as a3f9c2e17b4d08. It is the same id you see in the agent's chat address and in the embed code (data-agent-id).
  • An id in the path that is not in the right shape is a 404.
  • Dates and times are in ISO 8601 with a time zone offset, such as 2026-10-25T09:14:03+00:00. A few fields that hold a day only use 2026-10-25.

Interactive reference

Your Chatvia server also publishes a reference that it builds from its own code. Open https://chat.example.com/docs/api in a browser. It lists every endpoint with its fields, and you can send test requests from the page with your key. The same reference is available as an OpenAPI file at https://chat.example.com/docs/api.json, which many tools can import to generate a client.

Both pages are open to anyone who can reach your server, without signing in. They describe the API only. They don't show any of your data.

What the API can't do

Some tasks need a person in the dashboard:

  • Training files and websites. A file or website added through the API waits until a teammate clicks Train. Texts start training on their own. See Sources.
  • Connecting catalog connectors that sign in with OAuth. They need a browser.
  • Approving tool calls. Tools that need a person's approval are not offered to the agent in API conversations.
  • Creating eval cases. The API runs the cases you set up on the agent's Evals page.

Search guides, settings and commands.