API reference
Knot implements the OpenAI REST API. Point any OpenAI SDK at it and change nothing else. New here? Start with the guide.
Last updated 29 July 2026
Base URL and authentication
All requests go to:
https://tryknot.xyz/v1Authenticate with either header — whichever your client already sends:
Authorization: Bearer knot_live_…
x-api-key: knot_live_…Keys are stored only as a SHA-256 hash, so a database dump does not reveal them, and a lost key cannot be recovered — only replaced.
Endpoints
| Method | Route | Billed on |
|---|---|---|
| POST | /v1/chat/completions | Input + output tokens, cached input discounted |
| POST | /v1/images/generations | Tokens the model reports, so cost tracks image size |
| GET | /v1/models | Free — public, no authentication |
| GET | /v1/credits | Free |
- Method
- POST
- Route
- /v1/chat/completions
- Billed on
- Input + output tokens, cached input discounted
- Method
- POST
- Route
- /v1/images/generations
- Billed on
- Tokens the model reports, so cost tracks image size
- Method
- GET
- Route
- /v1/models
- Billed on
- Free — public, no authentication
- Method
- GET
- Route
- /v1/credits
- Billed on
- Free
Billing formula
All prices are per 1,000,000 tokens.
cost = (prompt_tokens − cached_tokens) × input_price
+ cached_tokens × cached_input_price
+ completion_tokens × output_priceThree conventions are easy to get wrong, so they are stated plainly:
cached_tokensis a subset ofprompt_tokens, not an addition to it. The cached portion is priced once, at the discounted rate.reasoning_tokensis already insidecompletion_tokens. It is shown separately in your usage log but never billed twice.- If a model has no cached rate configured, cached tokens are billed at the full input price — never free.
Images are billed on the token counts the model reports, so cost tracks the size and quality of what was generated rather than a flat per-image fee.
Live prices for every model are on the catalog.
Streaming
Set stream: true for server-sent events in the standard OpenAI chunk format, terminated by data: [DONE].
Knot forces stream_options.include_usage on, so the final chunk carries token counts — that chunk is what the request is billed from, which is why a streamed request costs exactly what a non-streamed one would.
The model field in every chunk is the public ID you asked for. Upstream deployment names are never exposed.
Routing and failover
Each public model is backed by an ordered pool of capacity, usually spanning several accounts and regions.
- 429, 408 and 5xx are retried against the next deployment in the pool.
- Other 4xx return immediately — a malformed request fails identically everywhere, so retrying would only burn quota and delay the error you need to see.
- Failover is decided on response headers, before any body bytes reach you, which is why streamed requests get it too. Once a stream has started it is committed to that deployment.
- The
x-knot-attemptsresponse header reports how many deployments were tried. Greater than 1 means failover happened.
Rate limits
Requests are limited per key. Exceeding the limit returns 429 with a Retry-After header, which the OpenAI SDKs already back off on — so a well-behaved client needs no special handling.
The limit is generous enough that interactive use will not reach it. It exists to stop a runaway retry loop from draining a balance.
Errors
Errors use the OpenAI envelope, so existing SDK error handling works unchanged:
{
"error": {
"message": "…",
"type": "…",
"code": "…",
"param": null
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | — | Malformed body, missing model, or a model used on the wrong endpoint |
| 401 | invalid_api_key | Missing, unknown or revoked key |
| 402 | insufficient_credit | Balance is zero or below |
| 403 | account_disabled | Account disabled by an administrator |
| 404 | model_not_found | No such public model, or it is disabled |
| 429 | rate_limit_exceeded | Too many requests — see Retry-After |
| 503 | no_capacity | Every deployment for that model failed |
- Status
- 400
- Code
- —
- Meaning
- Malformed body, missing model, or a model used on the wrong endpoint
- Status
- 401
- Code
- invalid_api_key
- Meaning
- Missing, unknown or revoked key
- Status
- 402
- Code
- insufficient_credit
- Meaning
- Balance is zero or below
- Status
- 403
- Code
- account_disabled
- Meaning
- Account disabled by an administrator
- Status
- 404
- Code
- model_not_found
- Meaning
- No such public model, or it is disabled
- Status
- 429
- Code
- rate_limit_exceeded
- Meaning
- Too many requests — see Retry-After
- Status
- 503
- Code
- no_capacity
- Meaning
- Every deployment for that model failed
A 4xx from the upstream model is forwarded verbatim, so you see exactly what the model said rather than a paraphrase.
Machine-readable
For agents and assistants: /llms.txt is a short summary with the live catalog, and /llms-full.txt is this reference in full.