Skip to main content
Private preview: this is rolling out and may not be available on your account yet.
An agent asks your site to do something and shows you a Stamped Mandate as proof that a verified person allowed it. The agent sends it as a token addressed to your site’s hostname. You check it on your own server, offline, against Sumvin’s published keys: the token never leaves your server, and you need no API key. A passing check tells you the token is genuine, addressed to you and unexpired, and that the person approved exactly its scopes. A token addressed to a hostname carries identity attestations only: proof of personhood, verification status, over 18. It never tells you the person’s name or contact details. See What a verifier checks. These checks use plain HTTP and a standard JWT library. The SDK has no verification function yet.

What the agent sends

The agent sends the token in the x-sumvin-pint-token request header. The value is the bare token, with no Bearer prefix:
The token is addressed to one hostname, such as reservations.example.com. Accept only a token addressed to your own.

Before you start

  • A JWT library. This page uses jose: bun add jose or npm install jose.
1

Read the token from the request

A request without the header carries no mandate. Treat it as any other unauthenticated request.
2

Check it offline

Verify the token against Sumvin’s published key set, with your hostname as the audience. The keys rotate, so let your library fetch and cache them rather than copying them.
Pin the algorithm to ES256, the only one Sumvin signs with, so a token signed any other way is refused rather than trusted.jwtVerify throws if the token was altered, wasn’t issued by Sumvin, isn’t addressed to you, or has expired. Treat any throw as a refusal.
Coming soon: an online check for tokens addressed to a website. Until then, the offline check is the whole check: it tells you the token is genuine, addressed to you and unexpired, but not whether the person has revoked it since.
3

Act only within its scopes

A token that passes its check still permits only what its scopes say. Compare them with what the agent is asking for, and act on nothing more.
Any refusal means don’t act.

Services that already hold the signed request

This section is for a service that already holds the signed request a person approved, for example because the person approved it for the service’s own app. It is not how an agent presents a mandate to a site: an agent sends the hostname token above. A service in this position can exchange the signed request for a token addressed to its organisation, then check online whether the mandate still stands. It needs an API key and your Organisation ID. See Get a key.
Developer dashboard access is by invitation during the preview. You can’t sign up yourself yet.
1

Exchange the signed request

Send the signed request the person approved, unchanged, with audience set to your Organisation ID. You get back a token addressed only to your organisation.
201 means a new token was issued. 208 means this request was already exchanged for your organisation, and you get the same token back. Keep mandateId: you need it for the online check.During the preview, some mandates can’t be exchanged yet; the exchange refuses them with PINT-403-009. See Checks and errors.
2

Check the token offline

Run the same offline check as above, with your Organisation ID as the audience:
3

Check it still stands

Ask Sumvin whether the mandate is still valid:
valid is true when the mandate is neither revoked nor expired. Otherwise reason says which. See the online check.
4

Act only within its scopes

Compare the scopes with what is being asked for, and read any spending ceiling with readScopeCeiling.
Any refusal, from any step, means don’t act.

Next

Checks and errors

Every response, error code and limit of the two checks.

Read a mandate's scopes

Turn scopes into amounts you can compare.