agent.model_credential_id on every session
you created and had no API route to the thing it names — the first step of using
an API-first product could only be taken in the Console.
Connect
Requires the
credentials:write scope. A token minted before this endpoint
existed does not carry it — mint a new one in the Console under Build with
API › API keys.
What you can connect
id is what you send as provider, default_model is what you
get by omitting model, and key_prefix is how you work out which ids share a
prefix — before sending a secret to anyone.
Provider detection
sk-ant- belongs to exactly one vendor, so nothing needs saying. sk- does
not — OpenAI, DeepSeek, Qwen and Kimi all issue keys that start with it — and
in that case you are asked rather than tried:
GET /v1/model-connectors is where those ids come from; you do not have to
read them out of this refusal.
We never find out by asking the vendors. The obvious implementation of
“work out who issued this” is to try the candidates until one accepts — which
means sending your secret to vendors you never named. A failed authentication is
still a disclosure: the key has left you and its real owner and arrived
somewhere neither of you chose. One extra field is the price of that not
happening, and a test asserts this endpoint makes zero outbound calls before it
knows who the key belongs to.
The response
The plaintext key appears in your request and nowhere afterwards: not in the response, not in the list, not in a log line.last4 is the only part of it
that is ever returned.
GET /v1/model-credentials reports ids, names and models — no key, and no
base_url either, because that is deployment topology rather than something to
build against.
Verification
The key is tried against the provider once, with the model it will run, before anything is written. A connection that does not work is worse than no connection at all: it becomes the organization’s default and every session afterwards fails somewhere far from here.
The rejection is quoted rather than rewritten because the one sentence that
matters — expired, revoked, out of quota, wrong account — is in it, and
“invalid key” throws all four away.
Disconnect
sessions_moved says how many. If there is
nothing left to move them to, they are left with no model and moved_to is
null; their next turn will say so.
What to know
One connection runs one model. Moving between two models from the same vendor means two connections, andagent.model must match the one you name.
Connecting is not switching. A new connection does not move existing
sessions by itself — PATCH /v1/sessions/{id} does, in place. See
Switching model providers.
Creating one needs a scope that creating sessions does not. The powers are
not alike: a session spends sandbox minutes, while a provider key decides whose
bill every future turn lands on.
A refused connection, a model that is not the one a credential runs, and an id
that is not yours are three different refusals with three different fixes —
they are laid out side by side in
troubleshooting.md.
Next
- quickstart — use the connection
- switching model providers — run the same task on another provider