Skip to main content

Conventions

Conventions that apply to every endpoint — read once here and avoid repetition on each reference page.

Request headers

HeaderRequiredDescription
Content-Type: application/json; charset=utf-8Yes (for bodies)Body format.
Accept: application/jsonRecommendedRestricts response to JSON.
Authorization or X-API-KeyYes (except public endpoints)See Authentication.
X-Org-IdWhen applicablePins the context organization for users with multiple orgs.
X-Request-IdOptionalYour own identifier. If not sent, the server generates one and returns it in the X-Request-Id response header.
TraceparentOptionalW3C Trace Context for distributed tracing.
x-localeOptionalpt-BR or en-US. Forces the language of messages, overriding Accept-Language.
Accept-LanguageOptionalLanguage 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:

  1. API key → already bound to an organization. X-Org-Id is optional and, when sent, must match.
  2. JWT/cookie → the user's default organization is used. Send X-Org-Id to switch to another organization you belong to.
  3. Platform admin → can access any organization; send X-Org-Id to 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
}
  • cursor is opaque — don't try to decode it.
  • When has_more=false and next_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 Z suffix:
    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, DELETE are idempotent by contract — repeating the same call with the same input leads to the same final state.
  • POST that creates resources is not idempotent — repeating creates multiple resources.
  • For critical operations use the Idempotency-Key header when the endpoint documents support (currently applicable to POST /platform/projects/{id}/cases/run and POST /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: true in details (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.