Skip to main content

Errors, rate limits & conventions

Every Trinitite endpoint — regardless of surface — shares the same error envelope, rate-limit contract, pagination scheme, and idempotency rules. This page is the single source of truth; per-endpoint pages document only their surface-specific extensions.

Error envelope

Every error response uses one JSON shape, regardless of HTTP status:

{
"error": {
"code": "validation_error",
"message": "human readable description",
"details": { },
"request_id": "req_01J9X..."
}
}
FieldTypeDescription
error.codestringStable, snake_case, machine-readable. Safe to switch on.
error.messagestringHuman-readable. May vary across releases — never switch on it.
error.detailsobject | nullEndpoint-specific structured context (validation paths, missing scopes, conflict markers).
error.request_idstringCorrelates with the X-Request-Id header and the audit log. Always include it when reporting an issue.

Common top-level codes:

HTTPerror.codeMeaning
400validation_errorBody or query failed schema validation. details lists field paths.
400bad_requestSemantic precondition violated (e.g. editing a finalized policy).
401unauthenticatedMissing or invalid credential.
403forbiddenAuthenticated but lacking the required permission. details.required_permission is set.
403entitlement_deniedCaller's organization is missing a required entitlement or feature flag.
404not_foundResource does not exist or is outside the caller's organization.
409conflictResource state precludes the transition (version race, delete-in-progress).
409idempotency_conflictSame idempotency key reused with a different request body.
410resource_goneHard-deleted resource.
422unprocessable_entityDomain-level validation failed (e.g. Guardian not in ready state).
429rate_limitedPer-organization rate limit exceeded. See § Rate limits.
500internal_errorUnexpected platform error. Safe to retry with backoff.
502 / 504upstream_error, upstream_timeoutDownstream LLM provider, MCP server, or training service failed.
503emergency_shutdownOrg-wide emergency kill switch is engaged (see Governance Controls).

HTTP status usage

CodeUsed for
200 OKSuccessful synchronous request returning a body.
201 CreatedSynchronous resource creation. Response includes the new record.
202 AcceptedAsynchronous work queued. Response includes a polling identifier.
204 No ContentSuccessful request with no body (typical for DELETE and some PATCH).
3xxNot used by the platform API. Public verifier URLs may issue 302 for short-link redirects.

Asynchronous operations & polling

Long-running work — Guardian training, policy ingestion, scenario generation, training campaigns — accepts the request and responds 202 Accepted immediately:

{
"job_id": "job_01J...",
"status": "queued",
"poll_url": "/v1/training/jobs/job_01J..."
}
  • Initial poll interval: 2 seconds.
  • Backoff: linear up to 10 seconds, then steady.
  • Terminal states: ready / completed / failed / cancelled. Once terminal, the resource never changes state again — a retry creates a new job.
  • Failure detail lives on the resource itself (error_message, failure_reason, ingestion_error), not in the polling envelope.

Rate limits

Authenticated endpoints are rate-limited per organization. Standard headers are emitted on every response:

HeaderDescription
X-RateLimit-LimitQuota for the current window.
X-RateLimit-RemainingRequests remaining in the current window.
X-RateLimit-ResetUnix epoch seconds at which the window resets.
Retry-AfterSeconds to wait. Present on 429 responses only.

Retry guidance:

  • On 429, wait for Retry-After before retrying. The limiter is a hard bucket and will keep returning 429 until the window resets.
  • On 5xx, use exponential backoff with jitter starting at 1 s, capping at 30 s.
  • Idempotent retries are safe for GET, PUT, DELETE, and any POST carrying an Idempotency-Key header.

Health and metrics endpoints are not rate-limited.

Pagination

List endpoints use cursor-based pagination by default:

ParamDefaultDescription
limit25Page size. Maximum is endpoint-specific (typically 100; 500 on some log surfaces).
cursorOpaque token from the previous response's next_cursor. Omit for the first page.
{
"data": [ /* items */ ],
"page": {
"next_cursor": "string | null",
"has_more": true
}
}

A small number of legacy / audit-style endpoints use offset pagination (page + page_size); these are flagged on the endpoint page.

Filtering, sorting & time windows

ParamTypeDescription
from / toISO-8601 timestampTime window. Inclusive of from, exclusive of to. Defaults to last 24 h where applicable.
sortstringComma-separated field list. Prefix - for descending.
qstringFree-text search where supported.

Surface-specific filters (status, guardian_id, verdict, risk_tier, …) are documented on the endpoint.

Idempotency

Mutating endpoints (POST, PATCH, DELETE) accept an idempotency key:

Idempotency-Key: <uuid-or-stable-string>
  • On first call with a given key, the platform processes the request and stores the response.
  • On a repeat call within 24 hours with the same key:
    • If the body is byte-identical, the original response is returned (same status, same body).
    • If the body differs, 409 idempotency_conflict is returned with the original request_id in details.
  • After 24 hours, the key is forgotten.

GET requests are inherently idempotent and do not require the header.

Time, IDs & encodings

ConventionFormatExample
TimestampsRFC 3339 / ISO-8601 with timezone2026-04-26T15:42:00Z
DurationsISO-8601 durationPT30S, P1D
Resource IDsLowercase prefix + ULID-style suffixgov_01J9X…, nhi_01J9X…, pol_01J9X…
MoneyDecimal string in minor units"12500" cents
HashesLowercase hexe3b0c4…
Binary contentBase64 (standard, not URL-safe)inside a string field
ArraysAlways returned, never null[] denotes empty

Resource ID prefixes by surface:

PrefixSurface
gov_Guardian
pol_Policy document
nhi_Non-human identity
key_API key
org_Organization
usr_User
role_Role
ts_Test suite
tr_Test run
cmp_Training campaign
job_Async job
att_Attestation report
evd_Evidence snapshot
mcp_MCP server registration
sk_Skill

Versioning & deprecation

  • Endpoints are versioned in the path (/v1/…). Breaking changes ship under a new path prefix.
  • Additive changes — new optional request fields, new response fields, new enum values, new endpoints — do not trigger a path bump. Clients must ignore unknown response fields.
  • Deprecated endpoints emit a Deprecation: true header and a Sunset: header (RFC 8594) with the planned removal date.
  • Removal lead time is at least 12 months from the first Deprecation header.

Standard headers

HeaderDirectionPurpose
AuthorizationRequestSession token or API key (see Authentication).
X-Trinitite-Nhi-Token / X-Trinitite-Nhi-IdRequestNHI principal headers when acting on behalf of an autonomous workload.
X-Trinitite-Workload-OriginRequestRequired alongside any NHI header.
Idempotency-KeyRequestSee § Idempotency.
X-Request-IdRequestClient-supplied correlation ID; echoed back. If omitted, the platform assigns one.
X-Request-IdResponseStable correlation ID for this request.
X-RateLimit-*ResponseOn rate-limited surfaces.
ETagResponseOn versioned resources; use with If-Match for optimistic-concurrency PATCH.
Deprecation / SunsetResponseWhen applicable.
Retry-AfterResponseOn 429 and select 503 responses.

Authentication — principals, tokens, scopes, the API-key CRUD surface. → Verdict vocabulary — the three outcomes and receipt fields every govern call returns. → Webhooks — event delivery for verdicts and async job completion.