Retired endpoints (410 Gone)
The following surfaces are retired. A request to any of them — any method, any sub-path — returns410 with a JSON error body whose message names the replacement, plus a
link: <...>; rel="help" header pointing here. A 410 is permanent: don’t retry it, move
the call.
Example 410 body
GET /v1/models and
Idempotency-Key. The per-endpoint notes are on
Retired endpoints.
One public id per model
Every model has one public id. Closed-weight models are called by their plain name (gpt-6.1-sol, sonnet-4.6); open-weight models are called @sdn/<name>
(@sdn/glm-5.3). The older spellings (sdn-glm-5.3 and the bare glm-5.3)
keep resolving to the same model, and the response echoes the id you sent; canonical
ids appear in x-sideren-requested-model. You don’t have to change anything day one —
but new tooling should write public ids, and GET /v1/models lists them that way, with
the older spellings under each entry’s aliases. In YAML, quote an id that starts with
@: model: "@sdn/glm-5.3".
If the model you ask for can’t be served (a disabled id, for example), Sideren serves a
similar available model and discloses it — unless exact mode is on. With exact mode
(per key, or the
x-sideren-exact header below), you instead get a 404 model_unavailable:
non-retryable, with an alternatives list containing only models your plan can actually
serve. Don’t auto-retry it — pick an alternative. The same 404 is also returned without
exact mode when no usable alternative exists (every candidate is unavailable or outside your
plan) — there is nothing to fall back to, so refusing is the honest answer.Errors say why, by cause
Statuses map to causes, so your existing retry logic keeps working without configuration — but only retry what can succeed:
The 16 MiB limit applies to Chat Completions, Responses, and Messages request bodies before
upstream dispatch. The error message names the limit.
Two behaviors worth knowing beyond the table:
- No hung connections. Before admitting a request, Sideren predicts whether it can start
(and finish, for non-streaming) inside the time your client will actually wait. When it
can’t, you get the immediate
429/503withretry-afterfrom the table — not a connection that dies later. See Reliability. - Streams keepalive. While a queued stream waits, Sideren sends SSE keepalive traffic so client idle timeouts don’t fire; first-byte timing is bounded per client profile.
retry-after semantics:
Headers.
Disclosure headers on the response
The v2 core tells you what actually happened. All are read-only facts, all documented on Headers:
The rate-limit headers replaced the ad-hoc
x-sideren-rpm-* names: those are still sent as
deprecated aliases for one release, then removed — move parsers to the names above.
Opt-in request headers
Three switches are off by default and opt-in per request (or per key, in your dashboard’s key settings):
Session affinity headers are optional and separate —
x-sideren-session (your stable id for
one conversation), x-sideren-principal (your id for the end user, when one key serves many),
x-sideren-branch (a fork of a conversation) and x-sideren-client (name/version). They
keep an agent loop’s turns on a warm cache. The
setup helper stamps them for you in the tools it configures.
Idempotency-Key
Send anIdempotency-Key (a fresh UUID per logical request) on any POST, and a retried
request is answered from the first attempt instead of running the model — and billing it —
twice. Keys are remembered for 24 hours, scoped to your API key and matched against a
canonical hash of the body:
Details, edge cases and what idempotency can’t undo: Idempotency.
Stateful Responses
POST /v1/responses with store: true persists the response under your key; later turns
chain on it with previous_response_id and send only the new input. Stored responses — and
only those you asked to store — are kept for up to 1 year, scoped to the key that created
them, and you can delete them at any time from the dashboard. Request/response content
retention, deletion and zero-retention keys are covered in our
privacy policy; the API surface on Responses.
For work that should outlive its connection without holding one open, use
background: true and read the result back with GET /v1/responses/{id} — the replacement
pattern for the retired batches surface.
A five-point client checklist
1
Grep for retired paths
grep -rn 'v1/completions\|/batches\|agent-runs\|/states\|/artifacts\|tool-connectors\|tool-catalog' src/ — anything that hits these needs the replacements above before v2, and gets a helpful 410 after.2
Retry only what can succeed
429 and 503/529 with retry-after yes; 400, 402, 403, 404 and every 410 no. The official SDKs already follow this — hand-rolled clients should match Errors.3
Read the disclosure headers
Log
x-sideren-served-model next to the id you sent; branch on x-sideren-dropped-tools and x-sideren-reasoning-continuity when they appear.4
Put idempotency keys on every POST
Especially agent loops and payment-adjacent calls. One UUID per logical request.
5
Prefer public model ids
Older spellings still resolve, but write public ids (
@sdn/glm-5.3, gpt-6.1-sol) in new configs and read the catalog at runtime with GET /v1/models.