Authentication
Server-to-server calls authenticate with an API key in the X-API-Key header. A key is bound to one organization and to exactly one issuer or one verifier — there are no OAuth-style scopes.
Request
curl "$LUTRAID_API/v1/organizations/$ORG/issuers/$ISSUER/create-credential-offer" \
-H "X-API-Key: $LUTRAID_KEY" \
-H "Content-Type: application/json" \
-d '{ "issuanceProfileId": "...", "data": [] }'
Key types
| Prefix | Grants | Use with |
|---|---|---|
iss_<keyId>_<secret> | one issuer | offer creation, issuance status |
ver_<keyId>_<secret> | one verifier | verification requests and results |
A key never grants access to a second issuer, verifier or organization. Calling an endpoint with a key that doesn't match the organizationId/issuerId/verifierId in the path fails closed with PERMISSION_DENIED (403) — the key simply isn't authorized for that resource, not that the resource doesn't exist.
Managing keys
Keys are created and revoked in the dashboard — there is no API to create or manage keys, and no additional scopes to configure. The secret is returned once, at creation; it is stored only as a hash and cannot be read back.
There is no rotation endpoint. To rotate, create a replacement key, deploy it, then revoke the old one.
Errors
| Status | Code | Cause |
|---|---|---|
401 | INVALID_API_KEY | missing key, malformed key, wrong secret, revoked key |
401 | API_KEY_EXPIRED | key had a configured expiry that has passed |
403 | PERMISSION_DENIED | key valid but scoped to a different issuer, verifier or organization |
See Errors for the full response shape.