/v1/chat/completions requests through
your own model-provider account using the @provider/model syntax. These
seven endpoints are how the credentials behind that syntax are managed.
They live under https://dash.square1.dev/api/user/me/byok.
Everything here concerns credentials you registered on your own
account. Provider names appear in these responses because you are the
source of that information — they say nothing about how the shared model
pool is served.
Gates
This router applies three checks in order, ahead of every endpoint below:- Active session or key — an
unlinkedorrevokedaccount is rejected here even though it can reach the rest of/api/user/*. - No guests — guest accounts expire, and an expired guest would orphan stored ciphertext.
- Feature enabled — BYOK is an operator switch, and it additionally requires the server’s credential-encryption secret to be configured.
403 byok_disabled:
게스트 계정에서는 사용할 수 없습니다.). Branch on the code, not the text.
Field naming
List credentials — GET /api/user/me/byok
credentials[]
The secret is write-only. There is no reveal endpoint, no unmasked
field, and no way to read it back. Replace it by saving a new credential.
providers[]
The catalog of provider types you may register, one row per
(provider, auth scheme) pair. A provider that supports two schemes
appears twice — because the per-provider cap is counted per scheme, so
collapsing them would make the count wrong.
Each row carries id, label, auth_scheme, required_fields,
optional_fields, supports_models_list, and multi_scheme.
Drive your UI from this array rather than hardcoding a list — which
providers are offered, and which fields each needs, is server-side data. The
label values are the human-readable provider names shown in the dashboard.
The three fallback fields
They look redundant and are not:
Sending only the last one would make “following the default” and
“explicitly chose the same value” indistinguishable, and there would be no
way back to
null.
Set the fallback toggle — PUT /api/user/me/byok/fallback
enabled accepts true, false, or null. null is a value, not a
deletion — it means “follow the operator default again”, which is why
there is no DELETE on this path. Omitting enabled entirely is a
400 invalid_request.
A 404 with no code is possible but rare — it means the account row
vanished between authentication and the write.
Verify without saving — POST /api/user/me/byok/verify
The “test” button. Runs a live probe against the provider and reports the
result, storing nothing.
base_url, a successful response also
carries resolved_base_url — the URL the server actually assembled from
your input. Show it: pasting a full endpoint path (rather than a base) is a
common mistake that otherwise surfaces only as an opaque failure.
Save a credential — POST /api/user/me/byok
Same body as verify. The server re-runs the identical probe first and
only stores a credential that passed — there is no unverified state.
labelis optional (max 40 characters). Omit it and the server assigns the lowest unusedkey-Nfor that provider and scheme.- The label is immutable after creation — it is bound into the encryption of the secret.
- The first credential saved for a provider becomes
is_primary.
byok_credential_conflict covers both the cap and a duplicate label. If
you need to tell them apart, compare your active count against
max_per_provider from the list response.Update a credential — PATCH /api/user/me/byok/:id
label and secret are not accepted. The label is part of the secret’s
encryption, and secrets are replaced by saving a new credential.
fallback_model_id must name a model in the shared catalog — a BYOK
(@provider/...) id is rejected, because falling back from your key to your
key defeats the point. An unknown id is
400 byok_credential_missing.
404 byok_credential_missing if the id isn’t yours. A non-integer id is a
400 with the same code.
Delete a credential — DELETE /api/user/me/byok/:id
404 byok_credential_missing if it isn’t yours. The label frees up for
reuse.
List a credential’s models — GET /api/user/me/byok/:id/models
A server-side proxy that asks your provider what models your credential
can see. Your secret never leaves the server.
cachedtells you whether the answer came from the short-lived per-credential cache. A cache hit never skips the ownership check.- A successful fetch marks the credential verified — a
rejectedcredential returns toactive.
The ids returned here are your provider’s ids — use them verbatim after
the
@provider/ prefix. BYOK models never appear in
GET /v1/models.
Calling a BYOK model
Registration is only half of it; the request syntax, the@provider/model
forms, and the dispatch-time error surface are covered in
BYOK.