Chat API
The Chat API lets you run Revelry Ai conversations from your own applications: create a chat, send messages, stream the response as it is generated, read history, and manage chats. Every chat is scoped to a Project and can optionally use an Agent and a pinned model.
Chats created through the API are separate from the chats people have in the Revelry Ai app. An API key can only see the chats it created, and the app's interactive chats are never reachable through the API.
Authentication
Include your API key in the Authorization header on every request:
Authorization: Bearer YOUR_API_KEY
Both kinds of key work with the Chat API. See Managing API Keys for how they differ:
- An Organization API key creates chats owned by the organization.
- A Personal API key creates chats owned by you. They run with your permissions and appear as your activity.
Chats created by one kind of key are not visible to the other.
Base URL
https://app.revelry.ai/api/v2
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /chats | Create a chat, optionally sending the first message |
POST | /chats/:id/messages | Send a message and get the assistant's reply |
GET | /chats/:id/messages | Read message history |
GET | /chats | List chats |
GET | /chats/:id | Get one chat |
DELETE | /chats/:id | Archive a chat |
Create a Chat
Endpoint: POST /api/v2/chats
Body:
| Field | Type | Required | Description |
|---|---|---|---|
project_id | integer | Yes | The Project the chat belongs to. Sets the Knowledge scope and credits used. |
agent_id | integer | No | An Agent whose instructions and Skills shape every turn. |
model_configuration_id | integer | No | A specific model. Defaults to your organization's default model. |
content | string | No | An initial user message. When present, the assistant replies before the response returns. |
stream | boolean | No | Stream the first reply as Server-Sent Events. Only used with content. Default false. |
Request:
curl -X POST https://app.revelry.ai/api/v2/chats \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": 1,
"agent_id": 7,
"content": "Summarize the open safety issues on this project."
}'
Response (201):
{
"status": "ok",
"response": {
"chat": {
"id": 42,
"title": "Open safety issues",
"project_id": 1,
"model_configuration_id": 5,
"agent_id": 7,
"created_at": "2026-09-17T12:00:00.000000Z"
},
"message": {
"id": 101,
"role": "assistant",
"content": "Here's what I found...",
"model": "claude-sonnet-5",
"created_at": "2026-09-17T12:00:05.000000Z",
"tool_executions": []
}
}
}
Without content, the response contains only chat.
If the first reply fails (for example, insufficient credits), the chat is still created. Its id is returned as response.chat_id in the error body, or in the chat field of the streamed error event, so you can retry with a message.
Send a Message
Endpoint: POST /api/v2/chats/:id/messages
Body:
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | The user message. Must be non-empty. |
stream | boolean | No | Stream the reply as Server-Sent Events. Default false. Must be a boolean, not a string. |
To run a Skill, put its slash command in content, for example /sprint-summary for the current sprint.
Request (non-streaming):
curl -X POST https://app.revelry.ai/api/v2/chats/42/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Which of those are overdue?"}'
Response (200):
{
"status": "ok",
"response": {
"message": {
"id": 103,
"role": "assistant",
"content": "Three issues are past their due date...",
"model": "claude-sonnet-5",
"created_at": "2026-09-17T12:01:10.000000Z",
"tool_executions": [
{
"id": 555,
"tool_name": "knowledge_search",
"tool_call_id": "call_abc123",
"status": "completed",
"parameters": {"query": "overdue safety issues"},
"result": "...",
"error": null,
"execution_time_ms": 840
}
]
}
}
}
Non-streaming requests wait for the full reply, up to five minutes. For long-running turns with many tool calls, use streaming.
The assistant uses the tools enabled for the chat (Knowledge, Artifacts, Skills, and connected integrations). Tool calls run without the approval prompts the app shows in interactive chat.
One message is processed at a time per chat. Sending another while a turn is in progress returns 409 Conflict.
Streaming
Set "stream": true on either POST /chats or POST /chats/:id/messages. The response is text/event-stream with HTTP status 200, and each event is formatted as:
event: <name>
data: <json>
| Event | Payload |
|---|---|
content | {"content": "..."} A chunk of assistant text. |
tool_start | {"tool_call_id": "...", "tool_name": "...", "parameters": {...}} |
tool_result | {"tool_call_id": "...", "tool_name": "...", "result": ..., "error": null, "execution_time_ms": 840} |
done | {"message": {...}} The complete assistant message. On POST /chats this also includes "chat": {...}. |
error | {"message": "...", "code": 402} The code is the HTTP status the error maps to. |
Request:
curl -N -X POST https://app.revelry.ai/api/v2/chats/42/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Draft an email to the site lead about the overdue items.", "stream": true}'
Response:
event: content
data: {"content": "Subject: Overdue safety"}
event: content
data: {"content": " items on Riverside Tower\n\n"}
event: done
data: {"message": {"id": 104, "role": "assistant", "content": "Subject: Overdue safety items on Riverside Tower\n\n...", "model": "claude-sonnet-5", "created_at": "2026-09-17T12:02:00.000000Z", "tool_executions": []}}
If your client disconnects mid-stream, generation continues on the server. Read the chat's history to retrieve the finished message.
Read Message History
Endpoint: GET /api/v2/chats/:id/messages
Returns messages in chronological order, oldest first.
Query parameters:
| Parameter | Default | Description |
|---|---|---|
page | 1 | 1-based page number |
page_size | 50 | Messages per page, maximum 100 |
Response (200):
{
"status": "ok",
"response": {
"messages": [
{"id": 100, "role": "user", "content": "Summarize the open safety issues on this project.", "model": null, "created_at": "2026-09-17T12:00:00.000000Z", "tool_executions": []},
{"id": 101, "role": "assistant", "content": "Here's what I found...", "model": "claude-sonnet-5", "created_at": "2026-09-17T12:00:05.000000Z", "tool_executions": []}
],
"pagination": {"page": 1, "page_size": 50, "total_count": 2, "total_pages": 1}
}
}
List Chats
Endpoint: GET /api/v2/chats
Returns the chats your API key created, newest first. Archived chats are excluded.
Query parameters:
| Parameter | Default | Description |
|---|---|---|
project_id | none | Only return chats in this Project |
page | 1 | 1-based page number |
page_size | 50 | Chats per page, maximum 100 |
Response (200):
{
"status": "ok",
"response": {
"chats": [
{"id": 42, "title": "Open safety issues", "project_id": 1, "model_configuration_id": 5, "agent_id": 7, "created_at": "2026-09-17T12:00:00.000000Z"}
],
"pagination": {"page": 1, "page_size": 50, "total_count": 1, "total_pages": 1}
}
}
Get a Chat
Endpoint: GET /api/v2/chats/:id
Response (200):
{
"status": "ok",
"response": {
"chat": {
"id": 42,
"title": "Open safety issues",
"project_id": 1,
"model_configuration_id": 5,
"agent_id": 7,
"created_at": "2026-09-17T12:00:00.000000Z",
"message_count": 4
}
}
}
Archive a Chat
Endpoint: DELETE /api/v2/chats/:id
Archives the chat. It no longer appears in lists, cannot be read, and cannot receive messages. Data is retained for billing and audit.
Response: 204 No Content
Pagination
List endpoints use page-based pagination. Pass page and page_size as query parameters. Every list response includes:
{"page": 1, "page_size": 50, "total_count": 120, "total_pages": 3}
page_size is capped at 100. A page or page_size that is not a positive integer returns 400 Bad Request.
Errors
All errors share one shape:
{
"status": "error",
"response": {
"code": 404,
"error": "Not Found",
"message": "Chat not found. Please provide a valid chat id."
}
}
| Status | When |
|---|---|
400 | Missing or empty content, non-boolean stream, invalid pagination parameter, or missing project_id |
401 | Missing API key, or no permission to the Project or Agent |
402 | Your organization has insufficient credits |
403 | Invalid or revoked API key, or an action your key is not permitted to take |
404 | Project, Agent, or chat not found, or the chat is archived |
409 | Another message is already being processed for this chat |
429 | Rate limit reached. Wait for the number of seconds in the Retry-After header. |
500 | The model or a tool failed while generating the reply |
504 | The non-streaming reply took longer than five minutes. Read the history to see if it finished. |
During streaming, errors arrive as an error event with the same code and message instead of an HTTP status.
Next Steps
- Managing API Keys: Organization and Personal API keys
- API Usage Guide: Artifact generation endpoints and webhooks
- Executing Skills: Run a Skill from a chat message with a slash command
- OpenAPI Documentation: Full request and response schemas