Authentication
Every request to the Disputes API is authenticated over TLS by a credential that belongs to one organization in one environment. Casap accepts two kinds. Both travel on the same header and resolve to the same identity: your organization, acting through the guest user Casap provisions for it.
Two credentials
| Credential | What it is | When to use it |
|---|---|---|
| API key | A static secret Casap issues at onboarding. | The simplest path. Most integrations use it. |
| Signed token | A JWT your identity provider signs. Casap verifies it against the provider's published keys. | When your policy rules out long-lived shared secrets. |
Using an API key
Send it unchanged on every request:
Authorization: Bearer N2M0ZjJlOTEtNWQ4My00YTZiLTlmMDEtMmI4ZTZjM2Q1YTc0OktxMy1abTlUcFI0dlQ4c0tkSjF5V2JONmVIM3VBOWZDZ1hvVl9QMHJTdDU=
curl 'https://api-sandbox.casaphq.com/v1/accounts?customerUuid=2f6d8b14-70a3-4c92-8de5-61b4a0c37e28' \
-H 'Authorization: Bearer N2M0ZjJlOTEtNWQ4My00YTZiLTlmMDEtMmI4ZTZjM2Q1YTc0OktxMy1abTlUcFI0dlQ4c0tkSjF5V2JONmVIM3VBOWZDZ1hvVl9QMHJTdDU='
The key above is an example. It has the same shape as yours and does not authenticate. Copy it whole, and set the header yourself: the scheme is Bearer, and an HTTP client's basic-auth helper sends the wrong one.
Using a signed token
Mint a JWT with the key your identity provider already holds and send it on the same header. Casap fetches the provider's signing keys from the JWKS URL registered at onboarding, verifies the signature, then checks the claims.
| Claim | Requirement |
|---|---|
iss |
The issuer Casap registered for your organization. |
aud |
Casap's API audience value, given at onboarding. |
iat |
Required. Casap measures the token's lifetime from it. |
exp |
Required, and at most five minutes after iat. Mint a token per request or per short batch. |
orgId |
Your organization's UUID, when one issuer serves several organizations. |
Tokens must be signed with RS256 or PS256; other algorithms are refused. Rotate signing keys on your own schedule; Casap picks the new key up from JWKS. Signed tokens are accepted on every endpoint.
How Casap protects the credential
- API keys live in a managed secrets store, encrypted at rest. The API service and a small number of Casap engineers can read them, under access control, and every read is logged.
- Rotation is yearly. Casap issues a new key, and the old one stops working the moment the new one is in place.
- API keys are issued per environment, and one never authenticates in the other. For signed tokens, Casap issues an audience value per environment, and a token must carry the value for the environment it calls.
- Signed tokens are never stored. Casap holds only your public keys.
Your side
Keep the credential server-side. It authenticates as your whole organization, so it does not belong in a browser, a mobile app, or anything a member can read. Rotate it when the people who could have seen it change.
When authentication fails
Authentication runs before routing, so a rejected request never reaches the JSON envelope described in Errors. The response is 401 with a plain-text body of one line and no WWW-Authenticate header:
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
auth failed: failed to authenticate user: invalid secret
The body names the stage that rejected the request. A problem with the header is reported as is; a problem with the credential is prefixed auth failed: and then names the check, so match on the prefix below, not the whole line.
| Body starts with | Stage | Cause |
|---|---|---|
authorization header required |
Header | No Authorization header. |
bad authorization string |
Header | No space between the scheme and the credential. |
request unauthenticated with bearer |
Header | The scheme is not Bearer. |
auth failed: failed to get key and secret from token |
API key, decoding | The key is not valid base64 or has lost its structure. Almost always a truncated or re-typed copy. |
auth failed: failed to authenticate user: unable to get secret for org |
API key, lookup | The key names an organization this environment does not know. Usually a sandbox key sent to production, or the reverse. |
auth failed: failed to authenticate user: invalid secret |
API key, comparison | The organization exists here but the secret is not the one on file. The key was rotated, or it belongs to another organization. |
auth failed: failed to authenticate api token |
Signed token | A claim or the signature failed: iss, aud, missing iat or exp, a lifetime over five minutes, or an algorithm other than RS256 or PS256. The rest of the line names which. |
auth failed: no guest user provisioned |
Identity | The credential is valid but your organization's setup is incomplete. Contact Casap. |
Never retry a 401 unchanged. A 403 means the credential authenticated but may not perform that operation.