Chat API
Use Rivya Chat API for non-streaming or SSE turns, API-created sessions, file_id image attachments, and token-based credit settlement.
Last reviewed on 2026/05/11
Use POST /api/v1/chat/completions for one complete non-streaming chat response, or POST /api/v1/chat/completions/stream for Server-Sent Events.
Chat API is session-based. Omit session_id to start a new API chat session. Pass a returned session_id to continue that same API-created session.
Current Scope
Chat API v1 supports:
- non-streaming assistant responses
- SSE streaming with
text/event-stream - API-created chat sessions
- account credit reservation and final token-based settlement
- optional web search, reasoning effort, and thought mode when supported by the selected model
- image attachments through Files API
file_idvalues
Chat API v1 does not support:
- user-supplied raw
messageshistory - continuing Studio-only chat sessions
- arbitrary external attachment URLs
- Chat webhook events
Required Scopes
Use an API key with:
chat:create
chat:readNew keys created in Settings include both scopes by default. Older keys may need to be recreated before calling Chat API.
Create A Chat Completion
curl https://rivya.ai/api/v1/chat/completions \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: chat-turn-001" \
-d '{
"model": "gpt-5-2-chat",
"message": "Write a concise launch plan for a new product image campaign",
"client_request_id": "chat-001"
}'Response:
{
"id": "chatcmpl_...",
"object": "chat.completion",
"session_id": "session_id",
"model": "gpt-5-2-chat",
"created_at": "2026-05-11T00:00:00.000Z",
"message": {
"id": "assistant_message_id",
"role": "assistant",
"content": "..."
},
"usage": {
"input_tokens": 1200,
"output_tokens": 320,
"total_tokens": 1520
},
"credits": {
"reserved": 3,
"final": 2
}
}Stream A Chat Completion
Use POST /api/v1/chat/completions/stream when your server wants assistant deltas as they arrive:
curl -N https://rivya.ai/api/v1/chat/completions/stream \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-H "Idempotency-Key: chat-stream-001" \
-d '{
"model": "gpt-5-2-chat",
"message": "Write a concise launch plan for a new product image campaign",
"client_request_id": "chat-stream-001"
}'Streaming responses use Content-Type: text/event-stream; charset=utf-8.
Events:
| Event | Meaning |
|---|---|
session.created | The API key, model, session, attachments, rate limit, and credit reservation checks passed. |
message.delta | A display delta for the assistant message. This is not a committed message yet. |
message.completed | The assistant message was committed to the API-created session. |
usage.completed | Token usage and final credits were settled. |
heartbeat | Keepalive event during long pauses. |
error | Public API error envelope for a failure after streaming started. |
done | The stream completed successfully. |
Example stream:
event: session.created
data: {"request_id":"req_...","session_id":"session_id","model":"gpt-5-2-chat"}
event: message.delta
data: {"request_id":"req_...","session_id":"session_id","delta":"Draft ","index":0}
event: message.completed
data: {"request_id":"req_...","session_id":"session_id","message":{"id":"assistant_message_id","role":"assistant","content":"Draft ...","created_at":"2026-05-11T00:00:00.000Z"}}
event: usage.completed
data: {"request_id":"req_...","session_id":"session_id","usage":{"input_tokens":1200,"output_tokens":320,"total_tokens":1520},"credits":{"reserved":3,"final":2}}
event: done
data: {"request_id":"req_...","ok":true}If an error happens after the first SSE event, the stream sends event: error and then closes:
event: error
data: {"error":{"code":"internal_error","message":"The request could not be completed.","requestId":"req_..."}}If the client disconnects before completion, Rivya stops the in-flight generation stream when possible. Partial deltas are not saved as a final assistant message. If the server has already committed message.completed, the final result can be read later with GET /api/v1/chat/sessions/{sessionId}.
Continue A Session
Use the returned session_id:
curl https://rivya.ai/api/v1/chat/completions \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: chat-turn-002" \
-d '{
"model": "gpt-5-2-chat",
"session_id": "session_id",
"message": "Now turn that into a 5-step execution checklist."
}'The session must belong to the same Rivya account and must have been created by Public API. Studio-only chat sessions are not returned or continued by Chat API.
Image Attachments
Chat attachments use Files API records, not external URLs.
- Upload an image with
POST /api/v1/files. - Use the returned
idasattachments[].file_id.
{
"model": "gpt-5-2-chat",
"message": "Review this product photo and suggest a cleaner editorial direction.",
"attachments": [
{
"file_id": "file_..."
}
]
}The file must belong to the same account, have kind: "image", and be available. Models that do not support image attachments return chat_attachment_not_supported.
Optional Controls
{
"model": "gpt-5-2-chat",
"message": "Compare three launch options.",
"enable_web_search": false,
"reasoning_effort": "default",
"thought_mode": "default"
}Control support varies by model. Read /api/v1/models and check chat_capabilities before exposing controls in your UI.
List Sessions
Use GET /api/v1/chat/sessions with a key that includes chat:read.
curl https://rivya.ai/api/v1/chat/sessions \
-H "Authorization: Bearer rvya_sk_..."This returns API-created sessions only:
{
"object": "list",
"data": [
{
"id": "session_id",
"object": "chat.session",
"model": "gpt-5-2-chat",
"tool_slug": null,
"title": "Write a concise launch plan...",
"controls": {
"enable_web_search": false,
"reasoning_effort": null,
"thought_mode": null
},
"created_at": "2026-05-11T00:00:00.000Z",
"updated_at": "2026-05-11T00:00:00.000Z",
"last_message_at": "2026-05-11T00:00:00.000Z"
}
]
}Get A Session
Use GET /api/v1/chat/sessions/{sessionId} to read one API-created session and its committed messages.
curl https://rivya.ai/api/v1/chat/sessions/session_id \
-H "Authorization: Bearer rvya_sk_..."The response includes committed user and assistant messages. It does not expose internal provider fields.
Idempotency
Use Idempotency-Key for every production POST /api/v1/chat/completions and POST /api/v1/chat/completions/stream request.
If a retry uses the same key and the same body, Rivya can return the stored response without creating another message or consuming credits again. If the same key is reused with different input, the API returns idempotency_conflict.
For streaming retries, Rivya does not replay historical token deltas. A completed replay returns a minimal SSE sequence with session.created, message.completed, usage.completed, and done.
Common Errors
| Code | Meaning |
|---|---|
chat_model_not_supported | The selected model is not available for Chat API. |
chat_session_conflict | The session cannot be used for this request. |
chat_attachment_not_supported | The attachment is missing, not owned by the account, not an image, or unsupported by the model. |
insufficient_credits | The account does not have enough credits for the turn. |
idempotency_conflict | The idempotency key was reused with different input. |