Inyo

Authentication

The KYC API uses the OAuth 2.0 client-credentials grant (RFC 6749 §4.4). Your backend exchanges a client_id and client_secret for a short-lived Bearer token, then presents that token on every /v1/* call.

Credentials are server-side only. Never ship a client_secret — or an access token — to a browser or mobile app. Your customers interact with the widget, never with the API.


Request a Token

Endpoint: POST /oauth/token
Content-Type: application/x-www-form-urlencoded

curl --request POST \
  --url https://{FQDN}/oauth/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data grant_type=client_credentials \
  --data client_id=$KYC_CLIENT_ID \
  --data client_secret=$KYC_CLIENT_SECRET

Credentials may also be sent as HTTP Basic authentication (client_secret_basic) instead of in the body:

curl --request POST \
  --url https://{FQDN}/oauth/token \
  --user "$KYC_CLIENT_ID:$KYC_CLIENT_SECRET" \
  --data grant_type=client_credentials

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIs…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "sessions verifications"
}

grant_type must be client_credentials — it is the only grant this endpoint supports.


Scopes

Each endpoint requires a specific scope. Tokens are issued with the scopes granted to your client; request a narrower set with an optional scope parameter when a component of your system only needs one of them.

ScopeGrants access to
sessionsPOST /v1/sessions, GET /v1/sessions/{session_id}
verificationsPOST /v1/verifications
--data scope=sessions

Requesting an unknown scope is rejected rather than silently ignored. A token that lacks the scope an endpoint requires returns 403, not 401 — the token is valid, it just is not authorized for that call.


Using the Token

Present the token as a Bearer credential:

curl --request POST \
  --url https://{FQDN}/v1/sessions \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --header 'Content-Type: application/json' \
  --data '{"user_ref": "user-123"}'

The document-number format validator is the one exceptionPOST /v1/validators/document-number is a stateless format check and needs no token.


Token Lifetime and Refresh

Tokens are RS256-signed JWTs and expire — expires_in tells you when, in seconds. Cache the token and refresh it before expiry; do not request a new token per API call, and do not hardcode a token anywhere.

A robust client:

  1. Caches the token in memory with its expiry timestamp.
  2. Refreshes when the remaining lifetime drops below a small margin (30-60 seconds).
  3. Retries once on a 401, in case the token expired between the check and the call.

Error Responses

Token endpoint errors follow RFC 6749 §5.2 — an error code with a human-readable error_description:

StatuserrorCause
400unsupported_grant_typegrant_type was absent or not client_credentials
400invalid_scopeThe requested scope contains an unknown value
401invalid_clientMissing, unknown, or incorrect client credentials. The response carries a WWW-Authenticate: Basic challenge
{
  "error": "invalid_client",
  "error_description": "Missing client credentials"
}

Errors on /v1/* calls:

StatusCauseHow to fix
401No Authorization: Bearer headerSend the header; obtain a token at POST /oauth/token
401Token expiredRefresh the token and retry
401Token invalid or unverifiableConfirm you are using the token verbatim, and against the matching environment
403Token is valid but lacks the endpoint's scopeRequest a token carrying the required scope

The 403 response includes WWW-Authenticate: Bearer error="insufficient_scope" naming the scope that was required.


Environment Isolation

Sandbox and production issue separate credentials, and each token is valid only in the environment that issued it. Sessions are strictly scoped to the tenant that created them: a token can never read another tenant's session, and a request for one returns 404.


Rotating Your Secret

Client secrets are rotated by Inyo on request — contact your Inyo representative rather than attempting rotation through the API. Rotate immediately if a secret may have been exposed.


Next Steps