Authentication and rate limits

Every verification route requires the Authorization: Bearer <token> header. A missing, invalid, revoked, or expired token returns 401. Beyond your plan's limit (30 requests/second on Starter, 60 on Standard), a request returns 429.

Who decides what gets disclosed

Each attribute of an SD-JWT VC presentation (age, a degree, a status) is protected by its own salted digest in the signed JWT. The wallet only attaches to its presentation the value and salt for the attributes the user agreed to reveal: everything else stays as an irreversible hash. Todis technically only has access to what's actually disclosed in the presentation it receives, never more.

With POST /verify/sessions, the claims field of your request becomes a DCQL query embedded in the authorization request sent to the wallet: the user sees and approves exactly that list before their wallet builds the presentation. With POST /verify/sd-jwt-vc, that step has already happened before you obtained the presentation: Todis verifies it and returns its content as is.

POST /verify/sd-jwt-vc

Verifies an SD-JWT VC presentation. Two modes in the request body: issuer_public_key_pem (the issuer's key supplied directly) or country_code (automatic resolution via the EU's official registry) ; issuer_public_key_pem takes priority if both are present.

  • 200: presentation verified, claims populated.
  • 400: neither issuer_public_key_pem nor country_code supplied.
  • 401: missing, invalid, revoked, or expired license token.
  • 422: malformed presentation or signature not verified (verified: false, detail in error).
  • 429: plan request quota exceeded.
  • 502: issuer trust registry resolution failed (country_code mode only, e.g. the European registry is temporarily unavailable).

POST /verify/mdoc

Verifies an mdoc presentation (ISO/IEC 18013-5, notably mobile driving licenses). The issuer's trust anchor (issuer_trust_anchor_pem) must be supplied explicitly in the request body: there's no automatic per-country resolution yet for this format (contact us if a specific mdoc issuer matters to you).

  • 200: presentation verified, doc_type and namespaces populated.
  • 401: missing, invalid, revoked, or expired license token.
  • 422: malformed presentation, wrong trust anchor, or signature not verified.
  • 429: plan request quota exceeded.

POST /verify/sessions

Creates an OpenID4VP verification session. The request body lists the requested credential type (vct) and the requested attributes (claims, simple paths, e.g. "age_over_18"), with the same issuer_public_key_pem/country_code choice as direct verification. The response contains an OpenID4VP authorization request to present to the user's wallet (QR code or deep link). The session expires 15 minutes after creation, whether it received a response or not.

curl -X POST https://verify.todis.eu/verify/sessions \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vct": "https://example.eu/credentials/pid",
    "claims": ["age_over_18"],
    "country_code": "FR"
  }'
  • 201: session created, with session_id and authorization_request.
  • 400: claims empty, or neither issuer_public_key_pem nor country_code supplied.
  • 401: missing, invalid, revoked, or expired license token.
  • 429: plan request quota exceeded.

GET /verify/sessions/{id}

Retrieves the result of a session created by POST /verify/sessions, to poll after the user has responded with their wallet (or periodically while waiting).

curl https://verify.todis.eu/verify/sessions/<session_id> \
  -H "Authorization: Bearer YOUR_TOKEN"
  • 200: three possible statuses, {"status": "pending"}, {"status": "verified", "claims": {...}}, or {"status": "failed", "error": "..."}.
  • 401: missing, invalid, revoked, or expired license token.
  • 404: unknown session (invalid identifier, or session expired after 15 minutes).
  • 429: plan request quota exceeded.

Response format (direct verification)

For /verify/sd-jwt-vc and /verify/mdoc: a verified boolean and, depending on the outcome, either the disclosed information (claims for SD-JWT VC, doc_type/namespaces for mdoc) or a text error field. Never the full identity document, only the attributes actually disclosed (see above).

Going further

For the overview (authentication, two ways to integrate, a curl example), see How the API works. For the exact request/response schema, todis.eu/en/docs (Swagger). Have a question not covered here? contact@todis.eu.