Skip to content

Authentication

All API requests are authenticated with an API key that you create on the API Keys page of your dashboard.

API Key Format

Keys are shown with an sk- prefix. The prefix is optional when you send the key — both sk-abc123 and abc123 are accepted — but keep it, since OpenAI SDKs expect it.

Sending Your Key

The standard form is a Bearer token:

Authorization: Bearer sk-YOUR_API_KEY

A bare value without the Bearer word also works: Authorization: sk-YOUR_API_KEY.

Example

curl https://ai.moducompia.com/v1/models \
  -H "Authorization: Bearer sk-YOUR_API_KEY"

Provider-native headers

If you use an SDK that speaks a provider's own protocol, send the key the way that SDK does — the same key works:

Header / parameter Used by Accepted on
Authorization: Bearer sk-… OpenAI-compatible SDKs all endpoints
x-api-key: sk-… Anthropic SDKs /v1/messages, /v1/models
x-goog-api-key: sk-… or ?key=sk-… Google Gemini SDKs /v1beta/models…, /v1/models/…
Sec-WebSocket-Protocol: openai-insecure-api-key.sk-… Realtime WebSocket clients /v1/realtime

Key Settings

When you create a key you can configure:

Setting Description
Name A label for the key (max 50 characters), e.g. "production", "staging".
Quota Spend limit for this key, in credits. Can be set to unlimited, in which case the key draws on your account balance.
Model access Optional allow-list. If enabled, the key may only call the listed models.
Expiration Optional expiry timestamp. A key with no expiry never expires.
IP allow-list Optional list of IP addresses or CIDR ranges. Requests from any other address are rejected.
Group Optional rate/price group the key is pinned to. If empty, your account's group is used.

One key per application

Separate keys for development, staging and production let you track usage and revoke access independently.

Retrieving a Key Later

The key is masked in listings, but it is not lost — you can reveal the full value again from the API Keys page at any time (single key, or several at once). Retrieval is rate limited, so treat it as recovery, not as a routine part of your deploy.

Site Binding

Prices are a property of the site you send the request to, not of your account. A key belongs to the site it was created on and only works there — which is also why a key issued on one site would not give you that site's prices anywhere else. Sending it to a different host returns:

{
  "error": {
    "message": "this API key is not valid on this domain (request id: 20260812...)",
    "type": "new_api_error",
    "code": "access_denied"
  }
}

Every error message carries the request id — quote it when you contact support.

If you see this, you are pointing at the wrong base URL — create a key on the site you are calling, or fix base_url.

Rate Limits

Limit Default Applies to
Per-IP API limit 360 requests / 180 seconds all API endpoints
Per-user model-request limit disabled by default; when enabled, 1000 successful requests per minute model calls (/v1/chat/completions and friends)
Sensitive actions (e.g. revealing a key) 20 requests / 20 minutes dashboard actions

There is no tokens-per-minute (TPM) limit. Operators can change every value above, so treat these as defaults rather than guarantees. On 429 Too Many Requests, back off and retry with exponential delay.

Error Responses

Errors use the OpenAI shape: {"error": {"message": …, "type": "new_api_error", "code": …}}.

Status Meaning
401 API key missing, malformed, disabled, expired, or its own quota is used up
403 Key used on a different site than it was created on (access_denied), requested model not in the key's allow-list, request IP outside the key's allow-list, or the account is banned
402 Insufficient balance to start the request
429 Rate limit exceeded
500 Internal error — retry, and quote the request id if it persists