Skip to main content

Authentication

Every request to the Korint API carries an access token identifying your client. Requests that act on a tenant's data — nearly all of them — also carry a tenant header naming that tenant. A few endpoints are tenant-agnostic and take no tenant header; the reference shows which by not listing it under Headers.

Get your credentials

Korint provisions a machine-to-machine client for your tenant and gives you:

client_idstringrequired

Public identifier for your client.

client_secretstringrequired

Secret for your client. Store it as you would a database password — never in frontend code or a public repository.

tenantstringrequired

Your tenant identifier. It also appears in your authorization server URL.

Ask your Korint contact if you don't have these yet. Credentials are issued per environment, so your sandbox client is not your production client.

Request an access token

Korint uses the OAuth 2.0 client credentials grant. Each tenant has its own authorization server: replace tenant in the host below with your tenant identifier.

curl -X POST 'https://korint-tenant.auth.eu-west-3.amazoncognito.com/oauth2/token' \
--fail-with-body \
--user '<client_id>:<client_secret>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=korint.io/policies korint.io/customers'
Response
{
"access_token": "eyJraWQiOiJ...",
"token_type": "Bearer",
"expires_in": 3600
}

Cache the token and reuse it until it expires — read expires_in rather than assuming a lifetime, and request a new token shortly before it runs out. Requesting one per API call will get you rate limited by the authorization server.

Call the API

Send the token as a bearer token and name your tenant:

curl -X GET 'https://api.sandbox.korint.io/policies/{policyId}' \
--header 'Authorization: Bearer <access_token>' \
--header 'tenant: <your-tenant>'

Environments

HostUse
https://api.sandbox.korint.ioBuild and test your integration. Credentials are issued per environment, so your sandbox client is not your production client.
https://api.korint.ioProduction.

Examples throughout this guide use the sandbox host. Korint also runs internal environments that are not part of the published surface; if you have been pointed at one, treat its host as given to you rather than inferred.

The tenant header is required on every endpoint that operates on tenant data — without it the request fails with MISSING_TENANT, even when your token is valid. A few endpoints are tenant-agnostic and take no tenant header: the reference marks them by not listing it.

Scopes

Ask only for the scopes your integration needs. Every scope you request must be one your client was granted when it was provisioned: the authorization server rejects the whole token request with invalid_scope if any requested scope is not allowed, rather than issuing a token with the rest.

ScopeGrants access to
korint.io/accountAccount information for the caller
korint.io/customersCustomer endpoints
korint.io/policiesPolicy endpoints
korint.io/assetsAsset endpoints
korint.io/branchesBranch endpoints
korint.io/quotesQuote endpoints
korint.io/documentsDocument endpoints
korint.io/signatureSignature endpoints
korint.io/billingBilling endpoints
korint.io/paymentsPayment endpoints
korint.io/claimsClaim endpoints
korint.io/invitationsInvitation and anonymous-session endpoints
korint.io/permissionsPermission management endpoints
korint.io/brokerBroker endpoints
korint.io/reportingsReporting endpoints
korint.io/analyticsAnalytics endpoints
korint.io/metricsMetrics endpoints
korint.io/externalExternal lookups (vehicle, company, address)

Those are the scopes an integration client is normally granted. Some clients are provisioned with korint.io/admin in addition, which unlocks administrative routes; check the scope claim of a token you have been issued to see what yours actually carries. A few scopes exist only for Korint's own applications and are never granted to integration clients.

A new-business integration typically needs:

korint.io/customers korint.io/policies korint.io/assets korint.io/quotes
korint.io/branches korint.io/documents korint.io/signature korint.io/payments

Add korint.io/billing to read invoices or balances, and korint.io/invitations to run anonymous quoting sessions.

The scope table above applies to client-credentials tokens. A user access token carries no korint.io/* scope at all — its authority comes from the user's permissions — and neither does an anonymous session token. Which token identifies whom, and what each may act on, is covered in Authentication.

What needs no credentials at all

A few routes take no Authorization header, and they are exactly the ones a public funnel needs before it has an actor:

  • POST /anonymous-session — start a session. Rate limited to 100 per hour.
  • GET /config and GET /config/{productId} — read the tenant and product configuration.

The tenant header is still required. Everything else needs one of the three tokens above.

Calling the API from a browser

Whether your funnel needs a backend comes down to CORS, and the answer is not "any origin works".

The API allows a configured list of origins per environment. That list holds Korint's own https://*.korint.io subdomains, an entry per partner front end, and — in the sandbox and development environments only — localhost. So:

  • Developing locally against sandbox: your localhost dev server is already allowed. This is why a browser-only funnel appears to work from the start.
  • Deploying your own front end: your production origin is not allowed until it is added. Ask Korint to allowlist it, exactly, before you ship — a browser request from an unlisted origin is refused by the browser regardless of whether your token is valid.

Allowed requests may send authorization, tenant and content-type.

If you would rather not depend on an allowlist, put a thin server of your own in front: it holds no secrets for the unauthenticated routes above, and it removes the origin question entirely.

Troubleshooting

401 on every request

The token is missing, malformed, expired, or was issued by a different tenant's authorization server than the tenant header names. Confirm the host in your token URL matches the tenant you are calling.

MISSING_TENANT

The tenant header is absent. Every endpoint that touches tenant data requires it, reads included; check the endpoint's Headers section if you are unsure.

403 although the token is valid

Either the token lacks the scope for that area, or the identity behind it has no permission on the record you named. Compare the scopes you requested against the table above first — that is the cheaper of the two to rule out. Which check refused you, and in what order they run, is in How a request is checked.

404 USER_NOT_FOUND on a policy operation

Your client-credentials token is valid, but record-level permissions resolve against a user and your client is not one. Widening scopes does not help — act as a signed-in user, or mint an anonymous session for the visitor. See The three kinds of token.

invalid_scope from the token endpoint

You requested a scope your client is not allowed. Request only the scopes your integration needs, or ask your Korint contact to widen the client.