The Ottili AI API is the public, OpenAI-compatible inference surface for building on
top of Ottili AI. It lets your backend call the same models, routing, tool
execution and credit accounting that power the in-product assistant — without
touching the dashboard.
Surface & accuracy note.* This reference documents the canonical OpenAI-compatible public surface*https://api.ai.ottili.one/v1(endpoints/v1/models,/v1/chat/completions,/v1/responses). It is API-key authenticated and company-scoped. The full request/response contract, streaming, billing enforcement, migration and rollback guidance are maintained as part of the public API contract — the live API metadata endpoint is the authoritative source of truth for the current schema. The public request boundary (authentication, idempotency, blocked-key fail-closed, tenant resolution and the customer-safe status surface) is documented in this reference. Build new integrations againstapi.ai.ottili.one/v1; the Unified API serves console/dashboard data and, today, a legacy, non-canonical/chat/completionsadapter.
This is the entry point for the AI API documentation. Each section below links
to a focused reference.
Base URL and compatibility
The AI API is served from the public Ottili ONE developer host:
https://api.ai.ottili.one/v1It is OpenAI-compatible: the OpenAI SDK and any OpenAI-style client work
unchanged with base_url = https://api.ai.ottili.one/v1. It shares
Ottili ONE conventions:
- Bearer authentication (service API key or JWT).
- Scoped access (
ai:chat,ai:models, …). - Company and workspace context resolved from the verified API key or JWT — never*
from a raw tenant-id header.
- Standard HTTP status codes with machine-readable error bodies.
- Per-window rate limits returned in response headers.
The authoritative list of available AI endpoints for your company and plan is
returned by the live API metadata endpoint. Internal Unified API routes and
dashboard routes are intentionally not documented here.
Authentication
Every request authenticates with the Authorization header:
Authorization: Bearer otk_live_xxxTwo credential types are accepted:
- Service API keys* — created in Ottili Auth, prefixed with
otk_, shown
only once at creation, stored hashed at rest.
- JWT bearer tokens* — issued by Ottili Auth for user sessions.
API keys are bound to a verified user membership and carry scopes. A missing
or insufficient scope fails closed.
Tenant context
AI requests always run inside a company. That context is resolved automatically*
from the verified membership of the API key or JWT you send — you do not*
provide X-Platform-Company, X-Platform-Workspace, or any company_id
header. Raw company-ID headers are ignored on the public surface. Inactive,
suspended or archived companies are rejected, which returns
model_not_found / permission_error (HTTP 403/404) via the normalized
error envelope.
Gateway status & diagnostics
Once authenticated, you can inspect your own boundary state without making an
inference call. The customer-safe status surface returns only your company's
context — never provider secrets, raw upstream slugs, or other tenants' data:
curl "https://api.ai.ottili.one/v1/gateway/status" \
-H "Authorization: Bearer otk_live_xxx"The response carries a single state (configured | degraded | blocked |
error), your available credit (balance − reserved, never the raw reserved
internals), the model catalog with per-model availability, your key's own policy
(scopes, allowed models, rpm/tpm, monthly budget), and pricing freshness
(pricing_version). A blocked state means your key was blocked or revoked by an
administrator; an error state means the credit lookup failed and should be
retried.
You can also probe whether an Idempotency-Key is still claimed (operational
visibility only — it never returns request bodies, prompts, or provider internals):
curl "https://api.ai.ottili.one/v1/gateway/idempotency/<your-idempotency-key>" \
-H "Authorization: Bearer otk_live_xxx"These diagnostic endpoints are part of the public boundary documented in this reference and are live onapi.ai.ottili.one/v1(router mounted via T-Q3-AI-0013). If an older deployment returns404for/v1/gateway/status, it predates that mount — the core inference boundary (auth, idempotency, blocked-key enforcement on/v1/chat/completionsand/v1/responses) is live regardless.
Quick start
curl -X POST "https://api.ai.ottili.one/v1/chat/completions" \
-H "Authorization: Bearer otk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "ottili/vale-1.2",
"messages": [
{ "role": "user", "content": "Summarise this customer's open orders." }
]
}'The model field accepts a model id (ottili/vale-1.2,
ottili/cairn-1.2) or the ottili/auto adaptive router, which
selects a model based on the request, plan and availability.
Examples in this reference
The following references go deeper on each part of the contract:
- Models & availability* — how routing and availability work.
- Credits & usage fields* — how AI spend is metered and reported.
- Rate limits* — windows, headers and backoff.
- Streaming* — server-sent token streaming.
- Tool calls* — how the assistant requests platform actions.
- Structured outputs* — JSON-schema-constrained responses.
- Errors* — status codes and machine-readable error codes.
- Caching* — what is safe to cache.
Status
The Ottili AI API is in public beta. Capabilities, fields and limits may evolve;
the live API metadata endpoint is the source of truth for the current contract.
Was this article helpful?
