Authentication
API keys, and why HTTP and WebSocket pass them differently.
Every call to the hosted API is authenticated with an API key. There are no scopes, no expiry, and no rotation policy: a key is either valid or it is not.
Key format
A key looks like idc_live_… or idc_test_…: the idc_ prefix, the
environment (live or test), then the base64url encoding of 32 random
bytes.
The raw key is shown exactly once, at creation. The portal stores only its sha256 hash, never the key itself. If you lose a key, there is no way to retrieve it: revoke it and generate a new one.
HTTP
Send the key in the Authorization header as a bearer token.
curl https://<host>/v1/resolve/did:eid:4tARKz6hK5GuWr9fkdzsG1Bf9X3b3agzh7RPBdjdpLWapHRh \
-H "Authorization: Bearer idc_live_..."WebSocket
Send the key as a ?key= query parameter instead.
const ws = new WebSocket("wss://<host>/v1/ws?key=idc_live_...");Why the two differ
The browser WebSocket constructor takes a URL and an optional list of
subprotocols. There is no argument for headers, so a WebSocket client cannot
set Authorization on the handshake request. The ?key= parameter exists
only to work around that gap.
Prefer the header wherever you have a choice. Logging middleware and reverse
proxies commonly strip Authorization before writing a request log, but a
query string travels with the URL: into access logs, into browser history,
into anything that records the address you connected to. Use ?key= for the
WebSocket handshake because there is no alternative, and use the header
everywhere else.
Revocation
A revoked key stops working on its next request. There is no cache to wait out. If a WebSocket connection was already open under that key, it stays connected, but a reconnect with the same key is refused.
Suspension
Suspension applies to the organisation, not the key. A suspended
organisation gets 403 on every /v1 call, with this exact body:
{"error":"this organisation is suspended","code":"suspended"}This is independent of key revocation: the key itself is still valid, the account behind it is not.
Test versus live keys
idc_test_… and idc_live_… keys are authenticated the same way and hit the
same endpoints. Each key carries its own rate-limit counter, so exhausting a
test key does not affect a live key on the same account. See
Rate limits.