StackYakdocs

Authentication

Every call to the API carries an API key as a bearer token.

curl https://api.stackyak.ai/v1/chat/completions \
  -H "Authorization: Bearer $STACKYAK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "lfm2-5-2-6b",
    "messages": [{"role": "user", "content": "hello"}]
  }'

Keys begin with yki_, followed by a fixed-length body ending in a checksum. A key that has been mistyped or truncated fails the checksum and is rejected without a lookup, though you cannot tell that from the response.

On a dedicated stack serving the Anthropic API, the same key may be sent as x-api-key instead. Everywhere else it is the bearer.

Creating a key

Keys are created in the product, under Inference → API keys. Give the key a name describing where it will be used, and choose whether it expires: never, or in 30 days, 90 days, or a year.

Copy the key when it is created. It is not shown again, and we cannot recover it for you. If you lose it, revoke it and create another.

Owners, admins, approvers and members can create and revoke keys. Viewers cannot.

What a key is scoped to

A key resolves to an organisation, and nothing narrower.

It carries no user identity: a key created by one person is indistinguishable from a key created by another, and revoking a person's access does not revoke keys they made. It carries no scopes, and there is no read-only key. Anything the API can do for that organisation, a holder of the key can do.

Treat one as you would a password for the whole organisation's inference, because that is what it is.

Which calls need a key

Completions and embeddings always need one.

The model listing on the shared host does not. An unauthenticated GET https://api.stackyak.ai/v1/models returns the models loaded on shared compute right now, with their identifiers, families, and when they were added. It reveals nothing about any organisation: not who is calling, not what any plan includes, and not what anyone is running. On a dedicated stack's own hostname the listing does require a key, because there it describes your stack.

When authentication fails

A key that is missing, malformed, revoked, expired, or simply not ours returns 401 Unauthorized. All of those answer identically and deliberately, so a rejected caller learns only that the key was not accepted.

A revoked key can keep working for up to a minute. Revocation is not instant across the fleet, so treat it as taking effect shortly rather than immediately, and do not use it to stop an attack in progress on its own.

Entitlement failures are not authentication failures, and this is the distinction that wastes the most debugging time. A perfectly valid key belonging to an organisation whose plan does not cover the model you asked for authenticates fine and is refused later, at routing, with 403 ModelNotInPlanError. If you are debugging access, the status tells you which half failed: 401 is the key, 403 is the plan. Errors covers both.

Handling keys

Keep them out of source. Read the key from an environment variable or your secret manager. A key committed to a repository is a key you have published.

One key per deployment target. Separate keys for production, staging, and each developer mean revoking one does not take down the others. It also makes the name you gave the key the answer to "what did we just break".

Rotate on suspicion, not on schedule alone. Create the replacement, deploy it, then revoke the old one. There is no overlap window built into a key, so the order matters.

On this page