Your First API Call (Verification Gateway)
Verification Gateway was formerly VaaS (Verification as a Service). Only the name changed: keep using your existing hostname (for example vaas.stg.iden2.app) and API paths.
This walkthrough takes you from zero to a 201 Created verification session, and then to your first verified credential presentation.
Prerequisites
- An OAuth access token with the
verification.session.createandverification.session.readscopes (Authentication) - Staging environment access
- A wallet app holding a credential (issue one first via Credential Factory if needed)
The examples below assume you have already acquired a token and stored it in $ACCESS_TOKEN — see Authentication.
1. Create a verification session
All request fields are optional — the minimal request is an empty object {}. Here we set a TTL and a correlation ID:
curl -X POST https://vaas.stg.iden2.app/api/v1/verifier/sessions \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ttlSeconds": 120,
"externalId": "my-first-verification"
}'
A successful call returns 201 Created:
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"authorizationUrl": "openid4vp://authorize?response_type=vp_token&client_id=...&client_metadata=...",
"qrCodeDataUrl": "data:image/png;base64,iVBORw0KGgo...",
"status": "pending",
"createdAt": "2025-01-15T10:00:00Z",
"expiresAt": "2025-01-15T10:02:00Z",
"externalId": "my-first-verification",
"credentialType": "VerifiedPerson"
}
2. Show the QR code
<img src="data:image/png;base64,iVBORw0KGgo..." alt="Scan with your wallet to share your credential" />
The holder scans the QR with their wallet, reviews which fields are requested, and consents to share them. You don't need to parse the authorizationUrl — just display it. (Curious what's inside it? See client_metadata vs. client_id.)
3. Poll for the result
curl https://vaas.stg.iden2.app/api/v1/verifier/sessions/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $ACCESS_TOKEN"
Poll every 3–5 seconds until status is terminal:
| Status | Terminal? | Meaning |
|---|---|---|
pending | No | Waiting for the holder to present |
completed | Yes | Verification passed — credentialData contains the disclosed claims |
failed | Yes | Verification failed — failureReason explains why |
On completed, the response includes the extracted claims and detailed check results:
{
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"credentialData": {
"givenName": "Alice",
"dateOfBirth": "1990-01-15"
},
"verificationResult": {
"signatureValid": true,
"issuerTrusted": true,
"policyCompliant": true,
"revocationStatus": "not_revoked",
"issuerMemberId": "urn:uuid:3c4d5e6f-...",
"checks": [
{ "type": "signature", "status": "success", "algorithm": "ES256" },
{ "type": "revocation", "status": "success", "mechanism": "BitstringStatusList" },
{ "type": "issuer_trust", "status": "success" }
]
}
}
Don't just check status === "completed". Always also verify verificationResult.signatureValid, issuerTrusted, and that revocationStatus !== "revoked". See Security Best Practices.
Troubleshooting
| Response / result | Likely cause |
|---|---|
401 | Missing, invalid, or expired access token |
403 | Your token lacks the required scope, or your configuration isn't permitted to request this credential type |
failed with issuer_not_trusted | The credential's issuer isn't in your trust network — contact iDen2 |
failed with expired | Holder didn't present in time — create a new session |
Next steps
- Verification Integration Guide — production-grade integration
- OpenID4VP (Credential Verification) — how the protocol works
POST /api/v1/verifier/sessionsAPI reference — full schema