API & Webhooks
Connect Tyrex AI to your own software — API keys, chat endpoints, and webhook triggers for workflows. Endpoint reference, request/response formats, and error handling.
Tyrex AI exposes a straightforward API for developers who want to build on top of their AIs, plus webhook triggers so external systems can start workflows.
API access is included with the Elite plan. Webhook triggers are available from Pro and up. You can still use workflows with in-app triggers on every plan.
API keys
Create and manage API keys from Settings → API keys. Keys use the tx_live_ prefix and carry one or more scopes that decide which endpoints they can call.
| Scope | Covers |
|---|---|
chat | Sessions and messaging — the endpoints on this page |
workflows | Triggering and managing workflows |
app-builder | Reading and driving App Builder projects |
account | Your account, plan, and usage details |
Keys are created with chat when you don't pick scopes. The authoritative list is served by the API at GET /api-keys/scopes — read it from there instead of hardcoding it, so your client can't drift from the server.
- Keys are shown once at creation — store them somewhere safe.
- Revoke any key at any time; revoking kills all requests made with it.
- A key only reaches endpoints that accept API keys. Calling one outside its scopes returns
403naming the missing scope.
Base URL
https://aiapi.tyrex.id/api/v1
Authenticate by sending your API key as a bearer token on every request:
Authorization: Bearer <your-api-key>
Response envelope
Every successful response is wrapped in a standard envelope:
{
"success": true,
"data": { ... },
"timestamp": "2026-08-12T09:00:00.000Z",
"path": "/api/v1/ai/sessions"
}
The examples below show the data payload for readability. Errors use a different envelope — see Error handling.
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /ai/sessions | API key or session | Create a new session (optionally with a first message) |
GET | /ai/sessions | API key or session | Cursor-paginated list of the caller's sessions, newest first |
POST | /ai/sessions/:sessionId/messages | API key or session | Send a message in a session and get the assistant's reply |
GET | /ai/sessions/:sessionId | API key or session | Session details with full message history |
POST | /workflows/webhook/<workflow-id>/<secret> | None (secret in URL) | Trigger a workflow run with a payload |
List sessions
GET /ai/sessions?limit=20&cursor=<last-session-id>
Authorization: Bearer <your-api-key>
Returns your sessions, newest first, cursor-paginated:
| Query param | Type | Description |
|---|---|---|
limit | number | Max rows to return (1–100, default 20) |
cursor | string | The last returned session ID — pass it to fetch the next page |
{
"items": [
{
"id": "sess_...",
"type": "GENERAL",
"status": "ACTIVE",
"title": "Order triage",
"updatedAt": "2026-08-12T09:00:00.000Z"
}
],
"nextCursor": null
}
nextCursor is null when there are no more pages.
Chat with your AI
1. Create a session
POST /ai/sessions
Authorization: Bearer <your-api-key>
{
"title": "Order triage",
"personaId": "...",
"initialMessage": "Help me triage today's orders"
}
POST /ai/sessions is idempotent — send the same Idempotency-Key header on a retry and you won't create two sessions or double-charge.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | No | Session title (derived from the first message when omitted) |
personaId | string | No | The persona (AI) to run this session as — its identity and knowledge base scope |
initialMessage | string | No | If supplied, the first user turn is dispatched immediately |
model | string | No | Model override — any model your plan allows: tyrex1.5:raptor / carno / rex / coder, or a third-party slug such as anthropic/claude-sonnet-5, deepseek-ai/DeepSeek-V4-Flash, moonshotai/Kimi-K3. Free plans are limited to tyrex1.5:raptor. |
Response
{
"id": "sess_...",
"type": "GENERAL",
"status": "ACTIVE",
"title": "Order triage",
"personaId": "...",
"createdAt": "2026-08-12T09:00:00.000Z",
"updatedAt": "2026-08-12T09:00:00.000Z"
}
2. Send a message
Send a message to an existing session. The reply is returned in full in a single synchronous response.
POST /ai/sessions/<session-id>/messages
Authorization: Bearer <your-api-key>
{
"content": "Summarize my uploaded document",
"model": "tyrex1.5:carno"
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | The message to send (max 8,000 characters) |
model | string | No | Model override for this turn — any model your plan allows (tyrex1.5:* or a third-party slug like anthropic/claude-opus-5). A model outside your plan returns 403. |
attachments | array | No | Attachments to include with the message |
Response
{
"userMessage": {
"id": "msg_...",
"role": "USER",
"content": "Summarize my uploaded document",
"attachments": null,
"createdAt": "2026-08-12T09:01:00.000Z"
},
"assistantMessage": {
"id": "msg_...",
"role": "ASSISTANT",
"content": "Here is a summary of your uploaded document...",
"thinking": null,
"createdAt": "2026-08-12T09:01:04.000Z"
},
"tokensUsed": 1240
}
assistantMessage.thinkingholds the model's reasoning trace when present (this session's AI has thinking enabled).tokensUsedreports consumption for the turn and is reflected in your usage meters.
Streaming mode
For long responses, pass ?stream=true on the URL. The request is queued and runs in the background, and the response is delivered over the realtime channel instead of as a single body:
POST /ai/sessions/<session-id>/messages?stream=true
Authorization: Bearer <your-api-key>
{
"content": "Analyze this report"
}
{
"sessionId": "sess_...",
"turnId": "...",
"status": "queued",
"deliverVia": "ws:/ai-assistance"
}
- The work continues even if the HTTP connection drops — the turn is tracked by
turnId. - Chunks arrive over the
ai-assistancerealtime channel; reconnect and replay usingturnId.
Webhook triggers for workflows
Any workflow with a Webhook trigger exposes a public URL you can call from your own systems. The secret is generated by Tyrex when you pick the trigger — no bearer token needed, the secret is the credential.
POST /workflows/webhook/<workflow-id>/<secret>
Content-Type: application/json
{
"orderId": "ORD-8831",
"customerEmail": "[email protected]",
"items": 3
}
The request body is passed to the workflow as its input payload. Use cases: a store backend starts the order-triage workflow, a form submission starts a follow-up, a monitoring tool starts an alert workflow.
- Rotate the secret any time with
POST /workflows/<workflow-id>/webhook/rotate(API key required). The old secret stops working immediately. - A
200response means the run was accepted — check the workflow's run log for the result. - Repeated calls with the same payload within 5 minutes are deduplicated, so safe retries from your side won't double-run.
- Runs are logged and metered like any other run.
Versioning & deprecation
The API is versioned in the URL path — everything on this page lives under /api/v1. Every response also carries an X-API-Version header, so a client can confirm which contract it's talking to without parsing the path:
X-API-Version: v1
When an endpoint is being retired it keeps working, but starts returning deprecation headers (RFC 8594 / RFC 9745 / RFC 8288) so clients can migrate on their own schedule instead of discovering it from a 404:
Deprecation: true
Sunset: Fri, 01 Jan 2027 00:00:00 GMT
Link: </api/v1/replacement/path>; rel="successor-version"
X-Deprecation-Note: Use the lighter endpoint instead
| Header | Meaning |
|---|---|
X-API-Version | The contract version serving this response (currently v1) |
Deprecation | true when the endpoint is deprecated but still functional |
Sunset | Date after which the endpoint may be removed (HTTP-date) |
Link | With rel="successor-version", points at the replacement endpoint |
X-Deprecation-Note | Short human-readable migration hint |
Deprecated endpoints are never removed before their Sunset date, and a successor is always named in Link. If you receive no deprecation headers, nothing on that endpoint is going away.
Rate limits & usage
- API requests consume the same usage units as chat in the app — the meters in your dashboard reflect combined usage.
- Webhook calls are subject to per-workflow rate limits to prevent runaway loops.
Error handling
The API uses standard HTTP status codes:
| Code | Meaning |
|---|---|
200 | Success |
400 | Invalid request payload — check field types and required fields |
401 | Missing or invalid API key |
402 | Quota or credit issue — see structured error codes below |
403 | Forbidden — plan or permission doesn't cover this request |
404 | Resource not found — session, persona, or workflow doesn't exist |
429 | Rate limit exceeded — slow down |
500 | Server error — check the run log and retry |
Errors share one envelope:
{
"status": 402,
"message": "Monthly unit quota exhausted",
"extensions": {
"code": "INSUFFICIENT_CREDITS",
"servicePath": "/api/v1/ai/sessions/sess_.../messages",
"timestamp": "2026-08-12T09:05:00.000Z",
"details": {
"error": "INSUFFICIENT_CREDITS",
"required": 1200,
"remaining": 0
}
}
}
Structured error codes carried in extensions.details:
| Code | HTTP | Meaning |
|---|---|---|
INSUFFICIENT_CREDITS | 402 | Not enough units for the request — includes required and remaining |
MODEL_UNAVAILABLE | 402 | The requested model can't serve this turn — includes model and reason |
SPACE_LIMIT_REACHED | 403 | Storage or space cap hit |
SPACE_LIMIT_SOFT_QUEUED | 409 | At the cap but requests are queued rather than rejected |
Validation failures return 400 with per-field errors in extensions.errors:
{
"status": 400,
"message": "Validation failed",
"extensions": {
"code": "ER:400",
"errors": [
{ "field": "message", "message": "message must be a string" }
]
}
}
Security
- All API traffic is HTTPS.
- Keys are revocable and never stored in readable form after creation.
- Webhook URLs contain a 48-character random secret — keep them private and rotate after any suspected leak.
- Webhook tools and endpoints are validated against server-side request forgery — Tyrex will not fetch internal addresses.
Next: Privacy & Data.