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:string
required
Public identifier for your client.
string
required
Secret for your client. Store it as you would a database password — never in frontend code or a
public repository.
string
required
Your tenant identifier. It also appears in your authorization server URL.
Request an access token
Korint uses the OAuth 2.0 client credentials grant. Each tenant has its own authorization server: replacetenant in the host below with your tenant identifier.
Call the API
Send the token as a bearer token and name your tenant:Environments
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.
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 withinvalid_scope if any requested scope is not allowed, rather than issuing a token with the rest.
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/billing to read invoices or balances, and korint.io/invitations to run anonymous
quoting sessions.
Which token acts on what
There is more than one kind of token, and they are not interchangeable. Choosing the wrong one produces errors that look like permission bugs.your integration
What the flow above issues. Carries a
scope claim and identifies your client, not a person. Use
it to read configuration and to start anonymous sessions.a person signed in
Issued when a human signs in. Identifies a user, so record-level permissions resolve against them.Signing in returns both an id token and an access token, and the API accepts only the access
token — send
AccessToken, not IdToken. The id token is the intuitive choice, since it is the one
carrying the email and profile, and it is rejected with 401 INVALID_CREDENTIALS, which reads as though
the credentials were wrong rather than the token being the wrong kind.A user access token carries no korint.io/* scope; its authority comes from the user’s permissions, not
from scopes. The scope table above applies to client-credentials tokens.a visitor in a public funnel
Returned by
POST /anonymous-session as accessToken. Not a Cognito token and it carries no
scope claim at all — its claims are { tenantId, sub: <sessionId>, type: "SESSION", iat, exp },
and it lasts 24 hours. Only the permission check applies to it.What needs no credentials at all
A few routes take noAuthorization 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 /configandGET /config/{productId}— read the tenant and product configuration.
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 ownhttps://*.korint.io subdomains, an entry per partner front end, and — in the sandbox and development
environments only — localhost. So:
- Developing locally against sandbox: your
localhostdev 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.
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.
What an anonymous session may do
Measured against a session token:
So a public funnel can take a visitor all the way to a priced, payable contract, but confirmation and
company search need a different actor. Plan for a hand-off — see
Anonymous quoting.
How a request is authorized
A valid token is necessary but not sufficient. Korint evaluates permissions on the record you named — the policy, customer or firm — for the identity behind the token. See Permissions. Some endpoints also require your token to carry the scope covering the area you are calling. That check runs after the permission check, and endpoints declaring no scope never run it. A 403 therefore means one of two things: your identity may not act on that record, or your token lacks a scope the endpoint requires.Troubleshooting
401 on every request
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
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
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.
invalid_scope from the token endpoint
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.

