Skip to main content
The token exchange endpoint accepts a signed and returns a SIS-signed JWT that third-party services can independently verify. This is the core transactional identity flow — it converts a user’s cryptographic authorisation into a portable, verifiable credential. A Stamped Mandate is delivered over the API as a PINT (header x-sumvin-pint-token). The request body, headers, and error codes on this page all use the PINT identifier verbatim.

Endpoint

Authentication: API key via Authorization: Bearer header. The key must carry the token_exchange scope. API keys are currently provisioned on request — email dan@sumvin.com to get access.

Request

Request Body

The pint object follows the canonical EIP-712 type structure. The scopes array must contain values from the scope catalog.
The SIS automatically determines the signer type based on whether the signing wallet has a registered agent key. You do not need to specify a signer type in the request — it will appear in the JWT claims after verification.

Linking a Stamped Mandate to a Chat Message

To associate a Stamped Mandate with a chat session message (for audit and provenance), include source_chat_message_id:

Processing Pipeline

When you call the token exchange, the SIS runs the following validation checks before issuing a JWT:
  1. Nonce idempotency check — if a PINT already exists for this (wallet, nonce) pair, the exchange short-circuits to the idempotent / multi-audience path (see below).
  2. Audience validation — confirms the audience matches the caller’s registered organisation.
  3. Signature verification — reconstructs the EIP-712 hash and verifies the signature (ECDSA for user keys, EIP-1271 for agent/Safe keys).
  4. Nonce advancement — advances the wallet’s server-side nonce only after the signature is confirmed, so failed attempts do not burn nonces.
  5. Expiry re-check — rejects if expires_at has passed during processing.
  6. Scope parsing and registry validation — parses each scope string, validates it against the registry, and checks parameter types and ranges.
  7. KYC status check — only runs if any requested scope requires KYC. Rejects with PINT-403-002 if the user’s status is not verified.
  8. Chat message validation — if source_chat_message_id is set, confirms the message exists and belongs to this user.
  9. Mandate persistence — stores the PINT with status active.
  10. JWT generation — issues an audience-scoped, SIS-signed JWT and records the issuance.

Response — 201 Created

On success, the endpoint returns the JWT and Stamped Mandate resource details:
The Location header points to the new Stamped Mandate resource: /v0/sis/pint/sr:us:pint:abc123.

Response Fields

Multiple Audiences

A single Stamped Mandate can produce multiple JWTs — one per target service provider. This supports purchase flows that span multiple providers. To issue a JWT for a second audience, call the exchange again with the same mandate but a different audience:
The SIS recognizes the existing PINT (by wallet + nonce), confirms it is still active, and issues a new audience-scoped JWT without re-running the full validation pipeline.

Idempotency — 208 Already Reported

If you call the exchange with the same mandate and the same audience, the endpoint is idempotent. It returns 208 Already Reported with the previously issued token:
This means you can safely retry the exchange without worrying about duplicate JWT issuance.

Error Responses

All errors follow RFC 7807 Problem Details:
See the full error reference at Errors.