Skip to content
Docs navigation: Open models / Open-model authentication

Open-model authentication

Open modelsOpen-model authentication Updated

On this page

Use a workspace API key in an Authorization: Bearer header on every endpoint. The Messages-compatible routes, /v1/messages and /v1/messages/count_tokens, also accept x-api-key. So do GET /v1/models and GET /v1/models/{model}. A non-blank x-api-key wins when both headers are present on those routes.

ConnectionValue
API basehttps://api.runinfra.ai/v1
Workspace keyrp_...
Process variableRUNINFRA_GATEWAY_KEY
BillingThe existing funding rules of your open-model account.

Replace MODEL_ID with an available id from Open models; read current capabilities, limits and prices from GET /v1/models.

For authentication troubleshooting, share the response's request id, status and error code with support. Keep the API key and authorization headers out of logs, screenshots and support messages. A connection failure before the gateway handles a request may have no request id.

Get a key

Open the model page, or Settings

Select Get API key on a page in the Model Library, or select Create API key in Settings > API keys. Both paths give you a workspace key for the open models API.

Copy the key

Copy it from the dialog. You can copy it again whenever you need it with the copy button on its row in Settings > API keys. The member who created a key and the workspace owner can copy it, other members and viewers cannot, and every copy is recorded in the audit log.

Keys made before copying existed show a disabled copy button. Create a new key, or Rotate this one, to get a copyable key; after a rotation the old key keeps working for up to 24 hours.

Set a spending limit or an expiration under Limits, or accept the defaults

A key follows your workspace's current rate allocation, including later upgrades. A key that already carries a custom per-key rate limit keeps it, clamped to the workspace maximum.

A monthly spending limit is off until you set one (minimum $1.00). Once the key's settled spend in the UTC month (it resets on the 1st) reaches it, pay-as-you-go requests on that key get 402 spend_limit_reached with the limit, the spend and the reset time. Other keys and the credit balance are unaffected; change it with Set limit in the key's row menu.

New keys have no scheduled expiry by default, but rotating a key gives the previous key a limited grace period. When you do turn expiration on the form starts at 90 days, and you can choose 30, 60, 90 days or 1 year.

Coding plan and Credits only

A serving retired plan covers chat (chat completions, messages and responses) from every workspace key except keys marked Credits only, and embeddings and rerank whenever those models are available.

An owner can set Credits only at Settings > API keys. The setting is off by default and survives rotation. It bypasses the coding plan, Standby, and the credits cap after plan limits. Normal wallet and key controls still apply.

On a serving coding plan, a per-key spending limit blocks credits after plan limits. It does not stop requests paid by the plan or eligible Standby usage. Use Credits only when a key must always follow pay-as-you-go credit controls. See Coding plan.

Send it

Shell
curl https://api.runinfra.ai/v1/chat/completions \
  -H "Authorization: Bearer $RUNINFRA_GATEWAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MODEL_ID",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Key format

Every key is rp_ followed by 40 lowercase letters or digits.

Text
rp_abcdefghijklmnopqrstuvwxyz0123456789abcd
└┬┘└──────────── 40 chars, a-z and 0-9 ───┘
prefix

The stored digest and encrypted copy both depend on a secret held outside the database, so a copy of the database alone cannot reveal a usable key. Revoking a key erases its encrypted copy. If Settings marks a key as an older format, rotate it from that row and the replacement uses the current one.

Workspace keys

Use a workspace-scoped key with https://api.runinfra.ai/v1 and select a hosted model with the model field.

A legacy key scoped to one deployment returns 400 auth_error here. Replace it with a workspace key.

Rotate, revoke, expire

The API key lifecycle: create a key and copy it whenever you need it, rotate to issue a new one, run both while traffic drains, then revoke the old key which answers 403; expiration separately makes a key answer 401 after the expiry you set.

  • Key lifecycle
  • no downtime to replace a key
  • copy it again any time
  • a new secret is issued
  • both valid
  • deploy and drain traffic
  • revoke old
  • 403 on the old key
  • runs on its own clock. After the expiry you set, the key answers 401.

Rotation keeps the previous key working for up to 24 hours by default, or until its own expiry if that comes sooner, and Revoke ends that grace period. For no downtime, choose Rotate from the key's row menu with Revoke previous key immediately clear, deploy the new key, let traffic drain, then choose Revoke on the previous key. Check Revoke previous key immediately when the previous key must stop at once.

To revoke or delete several keys at once, tick them in Settings > API keys, or tick the box above the list to select them all, then choose Revoke or Delete. A revoked key cannot be turned back on. Delete revokes a key that is still active first, and its usage history stays.

ResponseMeaningWhat to do
403 API key is deactivatedThe key was revoked. It stays deactivated after archival.Use the new key.
401 Invalid API keyThe key is unknown or permanently deleted.Create a key.
401 API key has expiredThe key passed the expiry you set.Rotate it or create a new key.
400 api_key_rotation_overlap_limitThe rotation would leave more than 20 live keys, twice the cap of 10. Nothing changed.Revoke an unused key, then retry.
503 api_key_mint_busy with Retry-After: 2Another key operation is still running. Nothing changed.Wait 2 seconds and send the same request again.

Branch on codes, never on message text: the 401 and 403 carry error.type and error.code, the 400 and 503 key operations a top-level code. During a rate-limit store outage, a revoked key can keep working for up to about 30 seconds. A rotation also revokes the earlier keys in its own rotation history that are still live; other older keys stay live and count toward the 20. Expiration is checked on every request, so an expired key stops working the moment it expires.

Environment variables

Shell
export RUNINFRA_GATEWAY_KEY=rp_...
export RUNINFRA_API_KEY=$RUNINFRA_GATEWAY_KEY
export RUNINFRA_BASE_URL=https://api.runinfra.ai/v1
export OPENAI_API_KEY=$RUNINFRA_GATEWAY_KEY
export OPENAI_BASE_URL=$RUNINFRA_BASE_URL
export ANTHROPIC_BASE_URL=https://api.runinfra.ai
export ANTHROPIC_AUTH_TOKEN=$RUNINFRA_GATEWAY_KEY

RUNINFRA_API_KEY is the name the open models CLI and most coding-agent integrations read. Mistral Vibe, Oh My Pi and Goose read their own variable instead, such as RUNINFRA_GOOSE_API_KEY, and so does Crush set up with --key-source env; setup writes it for you. It is not an alias for RUNINFRA_GATEWAY_KEY, so set both, as the block above does.

Most clients compatible with this chat-completions protocol pick up OPENAI_API_KEY on their own, so the block above maps it, with OPENAI_BASE_URL, to the open-models service. Messages protocol clients use the bare host because they append /v1. ANTHROPIC_AUTH_TOKEN sends Bearer auth. ANTHROPIC_API_KEY also works through x-api-key on the Messages routes and GET /v1/models. Use a separate key per environment so one leak has a bounded blast radius.

Security posture

These key-handling and security statements describe the open-models service.

Hashed and encrypted at rest

A versioned HMAC-SHA-256 digest authenticates requests, and an AES-256-GCM copy bound to its key lets you copy it again. The plaintext is never stored unencrypted.

Constant-time compare

Lookup is by indexed hash and the match is constant-time, so timing cannot enumerate keys.

Audit log

Key lifecycle changes, every copy of a key, and attributable authentication failures are logged for SOC 2 CC6.6.

Per-key rate limit

A sliding 60 second window per key, or a fixed 60 second window on each server during a rate-limit store outage. If the rate-limit store is not configured, the request is refused with 503 limiter_unavailable rather than admitted, and nothing is charged.

Per-key spending limit

An optional monthly budget on one key, enforced on settled spend and reset on the first of the month (UTC). The refusal is 402 spend_limit_reached with the limit, the spend, and the reset instant.

Source reference