Overview
The public API* is the only documented, external entry point for Ottili ONE. It runs at the base URL https://api.ottili.one and is built as a deny-by-default boundary*: only the paths explicitly listed in the public allowlist are reachable. Everything else is answered by the edge (Caddy) with 403 Forbidden.
The boundary forwards allowed requests to the Unified API (backend, port 8100). Internal, admin, debug, database and local routes are removed from the public contract.
Public API status
Ottili ONE labels every route and feature with a maturity level. For the public API:
- Live* — reachable via
api.ottili.onetoday and supported. - Beta* — available in preview (e.g. the Python SDK
ottili-sdk). - In development / Planned* — described in the sanitized OpenAPI contract, but not yet fully served from the public gateway.
Reachable endpoints (Live)
Today the following routes are released on the public edge:
| Method | Path | Auth | Note |
|---|---|---|---|
GET | /api/v1/status | none | Public status endpoint (e.g. for Worker health checks). |
POST | /api/v1/platform/public/contact | none | Contact / demo / sales forms from the website Worker; rate-limited. |
POST | /api/v1/platform/billing/webhooks/stripe | signature | Inbound Stripe billing webhook (signature-verified). |
POST | /api/v1/platform/billing/stripe/webhook | signature | Alternative Stripe webhook path; marked deprecated. |
POST | /coder/token | JWT (OIDC) | Ottili Coder OIDC broker: exchanges a GitHub OIDC token for platform model credentials. |
POST | /coder/progress | JWT (OIDC) | Progress callback of the Coder OIDC broker (GitHub Actions). |
The webhook and OIDC routes are internal* routes (inbound webhooks and runner broker), not developer-facing endpoints. The publicly callable, unauthenticated endpoints are GET /api/v1/status and POST /api/v1/platform/public/contact.
Authentication
The boundary supports three auth modes:
- None (public)* — public endpoints such as status and contact require no token.
- Signature* — Stripe signs webhook payloads; the signature is verified in the handler.
- JWT (OIDC)* — the Coder OIDC broker exchanges a GitHub OIDC token for platform credentials; the JWT is the authorization.
For the planned developer-facing API calls, authentication via BearerAuth (JWT/OAuth2) and ApiKeyAuth (developer API keys) is documented in the OpenAPI contract — see [Public API authentication](/docs/public-api-authentication).
Rate limits
The boundary applies rate limits per client IP (rolling 60-second window) and advertises them via the X-RateLimit-Limit, X-RateLimit-Remaining and Retry-After headers:
- Default:* 600 requests / 60 s per IP.
- Contact endpoint:* 10 requests / 60 s per IP (spam protection).
Error format
Every error response from the boundary uses a structured envelope:
{
"ok": false,
"error": { "code": "VALIDATION_ERROR", "message": "…", "status": 422 },
"request_id": "req_…"
}Client errors return 4xx, server errors 5xx; request_id makes tracing easier.
Documented OpenAPI contract
Besides the routes live today, Ottili ONE publishes a sanitized OpenAPI contract* describing the surfaces approved for external developers (developer API, content, platform, business, module and integration). Internal, admin, debug and database routes are removed. The structure and regeneration of the contract are described in [Public API Contract](/docs/public-api-contract).
Serving only* this contract from the public gateway (instead of the full internal Unified API) is a separate deployment task. Until then, api.ottili.one follows the deny-by-default model with the live allowlist listed above.
Where to go next
- Read the [Public API Contract](/docs/public-api-contract) for the contract structure and regeneration.
- Use the [Python SDK
ottili-sdk](/docs/sdk-and-client-libraries) (Beta, from source). - Understand [authentication](/docs/public-api-authentication) for upcoming developer API calls.
- See the [Cloud APIs](/docs/cloud-apis) for hosting-adjacent interfaces.
- Get an overview of [Ottili ONE](/docs/what-is-ottili-one).
Was this article helpful?
