Skip to content
Heimdallm
Marketplace/Documentation
Documentation · Get started

Authentication

Every API request carries a bearer key:

Authorization: Bearer sk-hd-v1-...

A key is sk-hd-v1- followed by 64 hex characters. Keys issued before the prefix change begin with sk-or-v1- and keep working; new keys always use sk-hd-v1-. Keys are created in your account and shown once — only a hash is stored, so a lost key cannot be recovered, only replaced. Treat a key like a password: keep it in a secret manager or an environment variable, never in client-side code or a repository. A leaked key can be revoked from your account at any time without affecting your other keys.

Keys, workspaces and limits

Keys belong to a workspace. Each key can carry its own spending limit with an optional reset window (daily, weekly or monthly, in UTC), an expiry date, and an assigned organization member so usage is attributed to the person holding it. When a key's limit is exhausted, requests with that key are rejected with status 402 until the window resets or the limit is raised — other keys are unaffected. The full account model is described in Organizations, workspaces & keys.

Inspecting a key

GET /key returns the key you authenticate with — its label, limit and usage:

{
  "data": {
    "label": "sk-hd-v1-3f9a...",
    "name": "production",
    "limit": 10,
    "limit_remaining": 4.5,
    "limit_reset": "monthly",
    "usage": 5.5,
    "usage_daily": 0.61,
    "usage_weekly": 2.4,
    "usage_monthly": 5.5,
    "is_free_tier": false,
    "expires_at": null
  }
}

Field-by-field reference: Key & activity.

Getting a key without asking for one

An application can obtain a key for a person's account without ever seeing their password, using the OAuth PKCE flow. The person approves on this site; the application receives a key it can use and the person can revoke.

Generate a random code_verifier (43 to 128 characters from A-Z a-z 0-9 - . _ ~), keep it, and send the browser to the authorization page with its SHA-256:

https://staging.impossiblecarrot.cc/auth?callback_url=https://yourapp.example/callback&code_challenge=<S256 of the verifier>&code_challenge_method=S256

code_challenge_method is S256 and nothing else — a plain challenge travels in the address bar as the very secret the exchange asks for. limit is optional: an exact decimal string of dollars, which becomes the key's spending ceiling.

Approving returns the browser to callback_url with a one-time code on it. Declining returns to the same address with error=access_denied. For a localhost callback, approval stays on this page and shows a copyable code. Paste it into the CLI's waiting terminal, which may be on another computer. heimdall-staging login --manual prints the approval URL without opening a browser or local port. The optional response_mode=manual query parameter selects code display without a callback action. A local or manual decline stays on the page with instructions to cancel the waiting terminal. Trade the code for a key within ten minutes:

curl https://api-staging.impossiblecarrot.cc/api/v1/auth/keys \
-H "Content-Type: application/json" \
-d '{"code": "<the code>", "code_verifier": "<the verifier>", "code_challenge_method": "S256"}'
{
  "key": "sk-hd-v1-...",
  "user_id": "usr_01J8Z0X2QZ"
}

The code is consumed as it is read, so a second attempt with the same one is refused whether it is a retry or a replay, as are a code past its ten minutes and a verifier that does not hash to the challenge. All of them answer 400 with one message, because telling them apart would say which codes exist. The key that comes back is listed on the person's account under the callback's origin and can be revoked there like any other.

When a key is refused

A missing, malformed, unknown, revoked or expired key — or one whose owner is suspended — always gets the same response, so the error cannot be used to probe which keys exist:

{
  "error": {
    "code": 401,
    "message": "Missing or invalid API key",
    "metadata": { "error_type": "authentication" }
  }
}

Trying it

curl https://api-staging.impossiblecarrot.cc/api/v1/key \
-H "Authorization: Bearer $HEIMDALL_API_KEY"

The catalogue endpoints — GET /models, GET /models/:author/:slug/endpoints, GET /providers, GET /families and GET /stats/public — require no authentication. Unauthenticated requests are rate-limited by client address; see Errors & rate limits.

DiscoverFind your next modelModel libraryAll models, versions, prices and capabilitiesBenchmarksMeasured quality, cost and time by serving configurationShowcaseImages, video and 3D made on the marketplaceProvidersCompare independent inference providersActivityMarketplace traffic and usageNetwork statusAvailability, latency and endpoint healthChatConversations, model settings and filesImage, video & 3DGenerate images, video and 3D assetsScene studioStage a shot in 3D, direct it and render it as a videoCoding playgroundBuild software with an AI agent on a machine of your ownOverview & routingIdentity, workspaces and routing preferencesCredits & billingBalance, deposits, ledger and reserved fundsAPI keysKeys scoped to workspaces, limits and expirationOrganizationsTeams, members and shared workspacesRequest historyRequests, receipts, sandbox sessions and account historyReferralsInvitations and referral earningsPrivacyData settings, exports and deletionDocumentationQuickstart, SDKs, pricing and guidesAPI referenceInteractive endpoint reference