Skip to main content
Ottili AI API

Ottili AI API

The public, OpenAI-compatible API for programmatic access to Ottili AI — authentication, tenant context, models, credits, rate limits, streaming, tool calls, structured outputs, errors, usage and caching.

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 against api.ai.ottili.one/v1; the Unified API serves console/dashboard data and, today, a legacy, non-canonical /chat/completions adapter.

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/v1

It 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_xxx

Two 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 on api.ai.ottili.one/v1 (router mounted via T-Q3-AI-0013). If an older deployment returns 404 for /v1/gateway/status, it predates that mount — the core inference boundary (auth, idempotency, blocked-key enforcement on /v1/chat/completions and /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?