# Data Delivery

Privy sends verified data as a Privy-signed JWT. This behavior is the same for
both data packages.

Digital ID provides two delivery channels.

## Exchange code

The `privy:success` event contains a single-use `exchange_code`. Send this code
to the merchant backend. The backend exchanges it at
`POST /v1/sessions/exchange`.

The exchange code expires after approximately five minutes. Privy does not
keep the exchange data in long-term storage.

The exchange-code flow prevents the JWT from traveling through the browser
front channel.

## Server-to-server callback

Privy sends the same JWT to the configured merchant `callback_url`:

```json
{
  "session_id": "9f1c2c8a-2d6f-4d60-9ab1-85a5d4aa93d0",
  "event": "identity.verified",
  "token": "eyJ..."
}
```

See [Server Callback](/digital-id/guides/server-callback) for the receiver
contract.

> The authoritative result is the Privy-signed JWT after the merchant backend
> verifies it. The exchange and the callback are two delivery channels for the
> same result. The result can arrive through both channels, so make processing
> idempotent with `session_id`. The optional `sections` value in
> `privy:success` is a front-channel preview. Do not use it as the
> authoritative result.

## What each package delivers

With the Contact package, `data` contains `my_contact_data` as plaintext
claims. The claims are readable, and the signature prevents changes.

With the Identity package, `data` also contains `my_identity`. Privy encrypts
it for the merchant with RSA-4096 and encodes it in base64. See
[Encrypted Identity Data](/digital-id/guides/encrypted-identity-data).
