Skip to main content

API Reference (OpenAPI and examples)

Version française : ../../fr/guides/api-reference.md

This page is the entry point of the API reference of the Navin Platform. It explains the two APIs, where their reference lives on the documentation site and in the repository, how to authenticate, and how errors, pages, retries and traces work. Who: developers and integrators.

The two APIs​

APIWhat it servesPrefixCredentialReference on the documentation siteSource of the reference
Control Plane APItenants and projects, identities and access, agents and runs, models and the LLM gateway, knowledge, tools and MCP, governance, security, FinOps; every portal screen, SDK and CLI command goes through it/v1OIDC token, portal session or API key eai_.../api/control-planedocs/api/openapi-v1.json
Navin Manager APIthe infrastructure of the platform: hosts, clusters, services, high availability, backups, restores and disaster recovery/api/v1 of the Navin Managermanager API token nmt_.../api/managernavin-manager/docs/api/manager-openapi.json

On the documentation site, open /api/control-plane for the Control Plane API and /api/manager for the Navin Manager API. In this repository, read the Control Plane API route by route and the Navin Manager SDKs and CLI for the Navin Manager API. In the portal, Developer portal > API reference links to the /docs, /redoc and /openapi.json of your Control Plane and shows its version.

note

When the documentation is enabled on a Control Plane server, the server itself serves the reference at /redoc, the interactive console at /docs and the machine contract at /openapi.json.

Sources of truth​

The published OpenAPI schema is docs/api/openapi-v1.json, generated from the FastAPI app by services/control-plane/src/eai/api_openapi.py (a breaking change is refused). The request surface is docs/api/control-plane-v1.requests.json and the route by route description docs/api/control-plane-v1.md. The JSON Schema contracts live in contracts/v1.

cd services/control-plane
.venv/bin/python -m eai.api_openapi --check
.venv/bin/python -m eai.api_surface --check

The Navin Manager schema navin-manager/docs/api/manager-openapi.json is written from the server by tools/manager/openapi.py, and its Python, TypeScript and Go clients are generated from it by tools/manager/gen_sdks.py.

Authentication​

The tenant of a Control Plane call always comes from the credential, never from the request body.

CredentialHeaderTypical caller
OIDC access token issued by KeycloakAuthorization: Bearer <token>users of the portal, SDKs and CLI after a sign in
Portal session eais_... opened by POST /v1/auth/loginAuthorization: Bearer eais_...local accounts
API key eai_...X-API-Key: eai_... or Authorization: Bearer eai_...scripts, CI pipelines, back end services
Navin Manager API token nmt_...Authorization: Bearer nmt_... on the Navin Manager APIautomation of the infrastructure

The Navin Manager also accepts X-NM-On-Behalf-Of: <user> from a token that holds auth:delegate; any other caller gets 403 on_behalf_of_forbidden.

Examples​

List the contracts (GET /v1/contracts), validate a manifest (POST /v1/contracts/{name}/validate), start a run (POST /v1/agents/{agent_id}/runs) and read its steps (GET /v1/runs/{run_id}/steps).

curl -H "X-API-Key: $EAI_API_KEY" https://ai.acme.example/v1/contracts
curl -X POST -H "X-API-Key: $EAI_API_KEY" -H 'Content-Type: application/json' \
-d @agent.json https://ai.acme.example/v1/contracts/agent-manifest/validate

First calls​

  1. Check who you are. The answer proves the credential works and shows the tenant, roles and scopes the server resolved from it.

    curl -H "X-API-Key: $EAI_API_KEY" https://ai.acme.example/v1/me

    Expected result: 200 with your principal.

    If it fails: 401 unauthenticated (no credential), 401 invalid_api_key or 401 api_key_revoked.

  2. Check the API version. GET /v1/meta gives the server version and the API version; a client written for /v1 expects v1.

    curl -H "X-API-Key: $EAI_API_KEY" https://ai.acme.example/v1/meta

    Expected result: api_version is v1.

    If it fails: another value means the server and your client do not speak the same major version.

  3. Read a list page by page. List routes return {"items": [...], "next_cursor": "..."}; send limit (default 50, maximum 500) and cursor=<next_cursor> for the next page, until next_cursor is null.

    curl -H "X-API-Key: $EAI_API_KEY" "https://ai.acme.example/v1/runs?limit=50"

    Expected result: a page of runs and a next_cursor.

    If it fails: 400 invalid_cursor means a damaged cursor; never decode or build it.

  4. Retry a creation safely. Send an Idempotency-Key header (1 to 200 characters): a retry with the same key and body returns the stored answer with Idempotency-Replayed: true. Long creations also return Operation-Id and Operation-Location, followed with GET /v1/operations/{operation_id}.

    Expected result: one resource created, whatever the number of retries.

    If it fails: 409 idempotency_conflict (same key, another body) or 409 operation_in_progress (the first request still runs).

  5. Correlate a call. Send your own X-Request-Id and a W3C traceparent; the response carries X-Request-Id, the error envelope repeats it, and the audit events carry the same trace id.

    Expected result: GET /v1/audit/correlations finds every event of the call chain.

    If it fails: an X-Request-Id with characters outside letters, digits and . _ : - is replaced by a generated req_<hex> id.

Errors​

Every error follows the error envelope with code, message, message_i18n (en, fr), details and request_id; the SDKs turn it into typed errors (see the SDK guides Python, TypeScript, Go).

{"error": {"code": "forbidden", "message": "...", "message_i18n": {"en": "...", "fr": "..."},
"details": {"required_roles": ["tenant_admin"]}, "request_id": "req_..."}}

The language of message follows the Accept-Language header (en or fr, default en). The Navin Manager API keeps the same envelope {error: {code, message, message_i18n, details}}.

Troubleshooting​

StatusCodeCauseFix
400invalid_requestinvalid valueread details, fix the value
400invalid_cursordamaged pagination cursorrestart from the first page
401unauthenticatedno credentialsend a token or an API key
401invalid_api_key, api_key_revokedwrong or revoked keycreate or rotate the key (POST /v1/api-keys/{key_id}/rotate)
403forbiddenrole or scope missingask for the role in details.required_roles
404not_foundresource absent or in another tenantcheck the identifier and the credential
409conflict, idempotency_conflict, operation_in_progressduplicate, key reuse or state conflictread details, retry with a new key or later
413payload_too_largebody over the size limitsend at most details.max_bytes
422validation_errorbody or parameters do not match the schemaread details.errors (loc, msg, type)
429rate_limitedrate limit reachedwait Retry-After seconds
502authz_backend_errorthe authorization backend could not answer (fail closed)check OpenFGA and OPA
503service_unavailablea dependency is downcheck the platform status

Next steps​