Conventions
Conventions that apply to every endpoint — read once here and avoid repetition on each reference page.
Request headers
| Header | Required | Description |
|---|---|---|
Content-Type: application/json; charset=utf-8 | Yes (for bodies) | Body format. |
Accept: application/json | Recommended | Restricts response to JSON. |
Authorization or X-API-Key | Yes (except public endpoints) | See Authentication. |
X-Org-Id | When applicable | Pins the context organization for users with multiple orgs. |
X-Request-Id | Optional | Your own identifier. If not sent, the server generates one and returns it in the X-Request-Id response header. |
Traceparent | Optional | W3C Trace Context for distributed tracing. |
x-locale | Optional | pt-BR or en-US. Forces the language of messages, overriding Accept-Language. |
Accept-Language | Optional | Language fallback when x-locale is not sent. |
Response headers
Every response includes:
X-Request-Id: 8e1f2c3a4b5c6d7e8f90
X-Trace-Id: 4bf92f3577b34da6a3ce929d0e0e4736
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: no-referrer
Cache-Control: no-store
And, on rate-limited routes (see Limits):
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 2026-04-24T15:31:00Z
Multi-tenancy and context
Most endpoints require an organization context to operate. Resolution:
- API key → already bound to an organization.
X-Org-Idis optional and, when sent, must match. - JWT/cookie → the user's default organization is used. Send
X-Org-Idto switch to another organization you belong to. - Platform admin → can access any organization; send
X-Org-Idto specify.
Accessing a resource belonging to another organization returns 404 not_found (privacy — we don't leak the existence of other tenants' resources).
Pagination
List endpoints accept two schemes depending on the domain:
Offset-based (simple)
GET /platform/projects?limit=50&offset=100
Response:
{
"items": [ ... ],
"total": 237,
"limit": 50,
"offset": 100
}
limit— max items returned. Default and max vary per endpoint; common defaults are 50, max 200.offset— items to skip. Very large paginations (> 10,000) may be slow; use tighter filters in that case.
Cursor-based (for large or real-time lists)
GET /notifications?limit=50&cursor=eyJ0cyI6IjIwMjYtMDQtMjRUMTU6MzA6MDBaIn0
Response:
{
"items": [ ... ],
"next_cursor": "eyJ0cyI6IjIwMjYtMDQtMjRUMTQ6MDA6MDBaIn0",
"has_more": true
}
cursoris opaque — don't try to decode it.- When
has_more=falseandnext_cursor=null, you're done.
Endpoints that use cursors are explicitly marked in the reference.
Filters and ordering
Filters are passed as query params:
GET /platform/projects?status=active&owner_id=123
Ordering uses sort and order:
GET /platform/projects/{id}/cases?sort=created_at&order=desc
When not specified, the default order is documented per endpoint (usually created_at desc).
Dates and times
- Always ISO 8601 UTC with
Zsuffix:2026-04-24T15:30:00Z - Never send alternative timezones. Convert to UTC on the client.
- Fields representing a date without time use
YYYY-MM-DD.
IDs
- Opaque strings (UUID v4 in most cases).
- We don't guarantee format stability across versions — treat as a black box.
- IDs are case-sensitive.
Idempotency
GET,PATCH,PUT,DELETEare idempotent by contract — repeating the same call with the same input leads to the same final state.POSTthat creates resources is not idempotent — repeating creates multiple resources.- For critical operations use the
Idempotency-Keyheader when the endpoint documents support (currently applicable toPOST /platform/projects/{id}/cases/runandPOST /platform/projects/{id}/versions/{id}/publish). The server returns the same result for the same key for 24 hours.
Internationalization
The API supports messages in two languages:
pt-BR(default, full coverage)en-US(high coverage, filling in)
Choose by sending:
x-locale: en-US
or the standard Accept-Language. This affects only message and hint in responses — code, IDs, enums and data stay in English/neutral.
Unknown fields
If your client sends a field the server doesn't recognize, the response is 422 request_validation_failed (strict schema, extra="forbid"). This prevents silent typos. Validate the payload against the endpoint reference before sending.
SSE connections (Server-Sent Events)
Two endpoints use SSE:
POST /ai/stream— incremental AI responses.GET /notifications/stream— real-time notification count.
To connect:
Accept: text/event-stream
Cache-Control: no-cache
X-API-Key: rfk_…
Response:
Content-Type: text/event-stream
event: message
data: {"type": "token", "text": "Hello"}
event: message
data: {"type": "done"}
Each organization/user has a limit of concurrent SSE connections. When exceeded: 429 rate_limited. Reuse the open connection instead of opening new ones.
Uploads
Endpoints that accept files (for example, POST /platform/organizations/{id}/integrations/{id}/sync-import) use multipart/form-data. This is documented case by case — the vast majority of the API is pure JSON.
Versions and deprecations
When a field is deprecated:
- the response includes
deprecated: trueindetails(when applicable); - the
Warning: 299 - "Field X deprecated, use Y"header is sent; - a new replacement endpoint or field is documented.
Deprecated fields remain sent for at least 6 months before removal, and removal only happens in a new major.