API reference / Partner

post/v2/keys

Issue an API key

Operation
issueKey
Authentication
API key

Creates a key for the calling tenant. A key may only grant scopes its own holder holds — otherwise `keys:write` becomes a privilege-escalation primitive.

Request

Body

namestringrequired
environmentstring

one of: livetest

kindstring

one of: secretpublishable

allowed_originsstring[]

Browser origins this key may be used from. A publishable key with none permits nothing — it fails closed, because forgetting to configure this must not produce a key usable anywhere.

scopesstring[]

Omit to inherit every scope the calling key holds. You may only grant scopes you hold yourself — requesting anything else is a 403, because a key that could widen its own scopes would be a privilege-escalation primitive.

Responses

201The key. **Returned once and never again.**
keystringrequired

The full key. Returned exactly once — we store only a SHA-256 digest, so it cannot be recovered or re-displayed, including by us.

prefixstringrequired
environmentstring

one of: livetest

kindstringrequired

Which kind of key this is, and the field to branch on. `publishable` keys are capped to a scope ceiling and rejected outside their origin allowlist; `secret` keys are not.

one of: secretpublishable

scopesstring[]
dropped_scopesstring[]

Requested and not granted. Present only when something was dropped, and named rather than silently omitted so nobody builds against a capability they were refused.

dropped_reasonstring

Why anything in `dropped_scopes` was dropped. Present only alongside it.

warningstringrequired
400The request body or query failed validation.
errorobjectrequired
401No key, an unknown key, a revoked key, or a key whose tenant is not active. All four return an identical body on purpose: distinguishing them would let a caller discover which partners we have.
errorobjectrequired
403The key is valid but lacks the scope, or it asked for a scope it does not itself hold.
errorobjectrequired
404Not found, or not yours. A resource belonging to another tenant answers 404 rather than 403, because 403 would confirm the record exists.
errorobjectrequired

Example

curl
curl -X POST https://api.haavisa.com/v2/keys \
  -H "Authorization: Bearer $HAAVISA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'

More in Partner

Something unclear? The eligibility guide explains the model behind the answers; the errors guide covers the envelope.