The two settings
Point your existing OpenAI client athttps://ai.uniblock.dev and give it a
Uniblock API key. Nothing else about your code changes.
Base URL
The one change that is not optional
Every model id gains a provider in front of it.gpt-4o-mini becomes
openai/gpt-4o-mini. This is the change that breaks an otherwise untouched
application, and it breaks loudly rather than quietly: a bare id is refused with
400 and the code model_id_not_pinned, naming the forms it will accept.
That refusal is deliberate. A bare id would have to be resolved to some provider
we happen to carry it under, and picking one for you is a decision about price
and about who sees your prompt that we are not willing to make on your behalf.
Find the ids you can call with GET /v1/models, or on the Models screen in the
dashboard. Do not assemble them by hand from a provider’s own naming. See
Models.
What carries over untouched
What is different
Endpoints. The operations this site documents arePOST /v1/chat/completions, GET /v1/models and GET /v1/models/{id}. That is
the inventory to port against: if your application calls anything else, this site
does not yet describe what it does here, so treat those call sites as unanswered
rather than as either working or refused. See
OpenAI compatibility.
Headers you send. Only Authorization and Content-Type are read. Nothing
else you send reaches the provider, because the upstream request is built from
your body and our own credential with a fresh header set. Organisation and
project headers, and anything in the x-uniblock-* namespace, do not travel.
Headers you receive. Provider rate-limit headers are not forwarded, so if you
currently read remaining-requests and reset headers to pace yourself, that input
is gone. Your own limits arrive as 429 responses carrying codes you can branch
on, and the per-key one carries Retry-After. See
Rate limits and spend controls.
One extra line on a stream. A streamed reply carries a
:x-uniblock-usage comment line immediately before data: [DONE]. The
server-sent events specification requires a parser to ignore a line starting
with a colon, so a conforming client never sees it. See
Streaming.
One extra field in an error. The error object carries request_id alongside
the fields OpenAI defines. It is inside error rather than beside it so that a
client reading only the fields it knows ignores it safely.
Billing. Credit is prepaid and the platform fee is added when you buy credit,
not when you spend it, so a request deducts the provider’s own rate with nothing
on top. A zero balance refuses new requests with 402 and ends in-flight ones.
See Credits and billing.
max_tokens is worth sending even where you left it out before. It sizes
what we hold against your balance while a request runs, so a request without it
is held at the model’s published maximum output and reaches your account spend
rate cap sooner.
A checklist
1
Prefix every model id
Search your code for model names and put the provider in front of each one.
This is the step that fails the first request if you skip it.
2
Point the client at the base URL and swap the key
Two settings, both above. Keep the key in the environment rather than in
source.
3
Find any call to an endpoint this site does not document
Anything beyond chat completions and the two catalog reads is undocumented
here. Decide what those call sites do before you cut over rather than after.
4
Stop reading provider rate-limit headers
If your pacing depends on them, move it onto
429 codes and Retry-After.5
Send max_tokens
Especially on any call path that currently omits it.
6
Log the request id
x-request-id is the header the official SDKs already surface on their error
objects, so this is usually a one-line change. Without it, a support
conversation starts from a description rather than from a request.7
Buy credit before you cut over
A verified account with a zero balance refuses every request, which is a
confusing first result if you were not expecting it.