# Verify the JWT

Digital ID signs the verified-data JWT with EdDSA and Ed25519.

Complete these checks on the merchant backend:

1. Get the public keys from `/.well-known/jwks.json`.
2. Select the key that matches the JWT `kid` header.
3. Verify the EdDSA signature.
4. Confirm that `aud` equals the merchant ID.
5. Confirm that `exp` is in the future.
6. Confirm that `iss` is the expected Privy issuer:
   `https://digitalid.privy.id/`.

The claims have this form:

```json
{
  "iss": "https://digitalid.privy.id/",
  "sub": "<identity ref>",
  "aud": "<merchant_id>",
  "session_id": "9f1c2c8a-2d6f-4d60-9ab1-85a5d4aa93d0",
  "merchant": "<merchant>",
  "data": {
    "my_contact_data": {
      "email": "user@example.com",
      "phone": "+62..."
    },
    "my_identity": "<base64 RSA-4096 ciphertext>"
  },
  "verification": {
    "method": "phone_lookup+liveness_face_match"
  },
  "iat": 1784656800,
  "exp": 1784657100
}
```

`my_identity` is present only with the Identity package. Decrypt it after
signature and claim verification.

> Do not trust the claims before all required checks succeed.

## Claim reference

| Claim | Type | Presence | Description |
| --- | --- | --- | --- |
| `iss` | string | Always | Privy issuer: `https://digitalid.privy.id/`. Verify against this value. |
| `sub` | string | Always | Identity reference for the verified user. |
| `aud` | string | Always | The merchant ID. It must equal your merchant ID. |
| `session_id` | string | Always | The verification session of this result. |
| `merchant` | string | Always | Merchant reference. |
| `data.my_contact_data` | object | Always | Plaintext contact claims: email and phone. |
| `data.my_identity` | string | Identity package | Base64 RSA-4096 ciphertext of the identity JSON. |
| `verification.method` | string | Always | Verification method. Treat this value as opaque, and use it only for audit records. |
| `iat` | number | Always | Issue time, in Unix seconds. |
| `exp` | number | Always | Expiry time, in Unix seconds. It must be in the future. |

If verification fails, reject the result and do not use its data. Get the JWKS
again and repeat the checks. See the
[recovery guide](/digital-id/api-reference/errors#recovery-guide).
