> For the complete documentation index, see [llms.txt](https://docs.toolkit.equs.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.toolkit.equs.ai/standards/presentation/choose-a-flow.md).

# Choose a Flow

Compare the three presentation flows and pick one

Every presentation ends with claim values in your systems, verified. What differs is **the route the `vp_token` takes to get there** - and that route decides which of your components receives it, whether anything personal touches platform storage, and how much the Holder has to do.

## Comparing the flows

<figure><picture><source srcset="https://701364325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFaucIkpW1i4WOAQC06fj%2Fuploads%2FiSquronA04KfUDcT6mgz%2Fvp_token_flows_equs_dark_panel.svg?alt=media&amp;token=7cc0d3bb-7793-444b-a81d-6ee84ee989e0" media="(prefers-color-scheme: dark)"><img src="https://701364325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFaucIkpW1i4WOAQC06fj%2Fuploads%2FTrcrDyargnpP33EJ0qkB%2Fvp_token_flows_equs_panel.svg?alt=media&amp;token=0f1f15f5-7fd5-4d03-839e-25fe505c367b" alt=""></picture><figcaption></figcaption></figure>

<table data-search="false"><thead><tr><th>Flow</th><th>Flow 1 - DC API: Wallet → Frontend</th><th>Flow 2 - Direct Post: Wallet → Platform → Frontend</th><th>Flow 3 - Direct Post: Wallet → Platform → Backend</th></tr></thead><tbody><tr><td><strong>Status</strong></td><td>Available</td><td>Available</td><td><strong>Work in progress</strong></td></tr><tr><td><strong>Protocol</strong></td><td>OID4VP <code>dc_api.jwt</code></td><td>OID4VP <code>direct_post.jwt</code></td><td>OID4VP <code>direct_post.jwt</code></td></tr><tr><td><strong>Route of the <code>vp_token</code></strong></td><td>Wallet → your front end → your back end. The platform never relays it</td><td>Wallet → platform → your front end collects it → your back end</td><td>Wallet → platform → pushed straight to your back end</td></tr><tr><td><strong>Which component receives it</strong></td><td>Front end, then back end</td><td>Front end, then back end</td><td>Back end</td></tr><tr><td><strong>Personal data in platform storage</strong></td><td>None</td><td>The <code>vp_token</code>, encrypted and scoped to your Tenant. Deleted once you verify it, or after 5 minutes if you never do</td><td>None - forwarded in flight, never written</td></tr><tr><td><strong>Holder experience</strong></td><td>The best of the three where it works: the browser and OS broker the exchange, the wallet opens natively on one device, nothing to scan or type</td><td>Scan a QR code. Across devices, also type the one-time code shown on the phone into your page</td><td>Scan a QR code</td></tr><tr><td><strong>You host</strong></td><td>Nothing</td><td>Nothing</td><td>An inbound endpoint that accepts the <code>vp_token</code></td></tr><tr><td><strong>Wallets</strong></td><td>EQUS Wallet, and third-party wallets supporting the DC API with OID4VP</td><td>EQUS Wallet, and third-party wallets supporting OID4VP <code>direct_post.jwt</code></td><td>Same as Flow 2</td></tr><tr><td><strong>Limitation</strong></td><td>The Holder's browser <em>and</em> phone must both support the DC API</td><td>None</td><td>None</td></tr><tr><td><strong>Effort</strong></td><td>Low</td><td>Low</td><td>Medium - you build and expose the receiving endpoint</td></tr></tbody></table>

{% hint style="info" %}
**Every flow ends the same way.** The routes above describe how the token reaches *you*. Verification is a separate call you then make, sending the token to the platform to be checked - identical on all three flows. That call reads the token in memory and stores neither it nor the claim values.
{% endhint %}

{% hint style="info" %}
**Flows 1 and 2 are rarely an either/or.** With the DC API enabled (off by default), Embed UI chooses between them at runtime, and Flow 2 becomes the automatic fallback wherever it isn't available. You only have to choose deliberately when you are building your own UI, or when Flow 2's brief encrypted write is unacceptable to you.
{% endhint %}

## Which one to pick

```mermaid
flowchart LR
    Q1{"Which of your components<br/>should receive the vp_token?"}
    Q1 -->|"My web front end"| Q2{"Can you rely on the DC API in<br/>your users' browsers and phones?"}
    Q2 -->|Yes| F1["<b>Flow 1</b><br/>DC API<br/>Wallet → Frontend"]
    Q2 -->|No| Q3{"Is it acceptable for the platform<br/>to hold the response briefly?"}
    Q3 -->|"Yes, a few minutes is fine"| F2["<b>Flow 2</b><br/>Direct Post<br/>Wallet → Platform → Frontend"]
    Q3 -->|"No, nothing personal at rest"| F3["<b>Flow 3</b><br/>Direct Post<br/>Wallet → Platform → Backend"]
    Q1 -->|"My back end"| F3
    style F1 fill:#e8f0fe,stroke:#4285f4,color:#1a1a1a
    style F2 fill:#e6f4ea,stroke:#34a853,color:#1a1a1a
    style F3 fill:#fff4e5,stroke:#f9ab00,color:#1a1a1a
```

<table data-search="false"><thead><tr><th>I want...</th><th>Use</th></tr></thead><tbody><tr><td>The cleanest Holder experience - nothing to scan, nothing to type</td><td>Flow 1</td></tr><tr><td>One flow that works on every browser and every device</td><td>Flow 2</td></tr><tr><td>A fallback for Holders whose platform lacks the DC API</td><td>Flow 2</td></tr><tr><td>Nothing personal in platform storage, even briefly</td><td>Flow 1 or Flow 3</td></tr><tr><td>The response delivered to my back end with no browser involved</td><td>Flow 3</td></tr><tr><td>No inbound endpoint to host</td><td>Flow 1 or Flow 2</td></tr><tr><td>Machine-to-machine verification</td><td>Flow 3</td></tr></tbody></table>

## The flows in detail

### Flow 1 - DC API: Wallet → Frontend

Your page asks for a presentation and the browser takes over. The operating system opens the wallet as a native prompt, the Holder approves, and the response comes back into your page. No QR code on the same device, no code to type, and nothing personal ever written to platform storage.

The catch is coverage: both the Holder's browser and their phone have to support the Digital Credentials API.

```mermaid
flowchart LR
    A["Your back end gets a<br/>presentation request"] --> B["Your page asks<br/>over the DC API"]
    B --> C["Holder approves<br/>in the wallet"]
    C --> D["vp_token returns to your page,<br/>encrypted for you"]
    D --> E["Your back end has the platform<br/>verify it and return the values"]
    style B fill:#e8f0fe,stroke:#4285f4,color:#1a1a1a
    style D fill:#fce8e6,stroke:#ea4335,color:#1a1a1a
    style E fill:#e6f4ea,stroke:#34a853,color:#1a1a1a
```

**Pick this flow** when the DC API is available to your users, you want the best Holder experience on offer, or nothing personal may be written to platform storage even briefly.

**Watch out** for coverage, which is the whole risk here. Browser and OS support is uneven, so unless you control the device fleet you will need a fallback for the Holders the DC API doesn't reach - Flow 2 is the usual choice, and Embed UI runs both.

**What the Holder does.** On one device, the wallet opens as an operating-system prompt rather than an app switch: they approve, and it's done. Across devices - phone wallet, desktop page - the exchange starts with a QR code, and what happens after that is decided by the browser and the operating system, so it varies by platform.

### Flow 2 - Direct Post: Wallet → Platform → Frontend

Your page shows a QR code. The Holder scans it, approves in their wallet, and the wallet posts an encrypted response to the platform rather than to you. The platform holds it briefly; your front end collects it and hands it to your back end to verify.

Nothing to detect, nothing to host, and no dependency on the Holder's browser or operating system. This is the flow that reaches everyone.

```mermaid
flowchart LR
    A["Your page shows the request<br/>as a QR code"] --> B["Holder scans<br/>and approves"]
    B --> C["Wallet posts to the platform,<br/>vp_token stored"]
    C --> D["Your front end collects it<br/>and hands it to your back end"]
    D --> E["Platform verifies, returns the values,<br/>deletes the token"]
    style C fill:#fce8e6,stroke:#ea4335,color:#1a1a1a
    style E fill:#e6f4ea,stroke:#34a853,color:#1a1a1a
```

**Pick this flow** when you want one flow that covers every Holder on any browser and any device, you don't want to host an inbound endpoint, or a bounded encrypted window on the platform is acceptable.

**Watch out** for the one thing that sets this flow apart: it is the only presentation flow that **writes personal data to platform storage**. The window is short and the token is encrypted under your Tenant key, but the write happens, and if that's unacceptable you want Flow 3.

**What the Holder does** depends on whether the wallet is on the device reading your page:

* **Same device** - the wallet opens, they approve, and the redirect lands back in the same browser. Nothing to type.
* **Across devices** - they scan the QR code with their phone, approve, then type a short one-time code shown on the phone into your page. The code binds the response to the browser session that asked for it: the wallet posts to the platform, and the platform has no way of knowing which browser tab it belongs to. Carrying the code across by hand proves the two are connected, and only then will the platform hand the response over.

Embed UI renders both paths, including the cross-device code entry.

### Flow 3 - Direct Post: Wallet → Platform → Backend

{% hint style="warning" %}
**Work in progress** - this flow is not yet available. It is documented so you can design against it; check with us before building.
{% endhint %}

Same start as Flow 2, different ending. The wallet posts its encrypted response to the platform, and instead of holding it for you to collect, the platform pushes it straight to an endpoint you host. Your back end owns the whole journey; no browser is involved unless you want one.

Nothing personal is written to platform storage at any point, and there's no one-time code for the Holder.

**Pick this flow** when the journey is driven from your back end rather than a browser - including machine-to-machine cases - when even a bounded encrypted window on the platform is unacceptable, or when you want one flow that reaches every Holder on any device.

**Watch out** for what owning an inbound endpoint means: exposing it to the platform, authenticating the callback, and deciding what happens when it's unavailable at the moment a Holder approves. The Holder has already consented by then, so a failed push is a presentation you asked for and can't collect.

## Once you've chosen

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3><i class="fa-display" style="color:$primary;">:display:</i></h3></td><td><strong>Flows 1 and 2 (through Frontend)</strong></td><td>Configuration, the two integration methods, and the verification result.</td><td><a href="/standards/presentation/flows-1-and-2.md">Flows 1 and 2 (through Frontend)</a></td></tr><tr><td><h3><i class="fa-server" style="color:$primary;">:server:</i></h3></td><td><strong>Flow 3 (direct to Backend)</strong></td><td>Work in progress. Configuration, the API, and the verification result for the push flow.</td><td><a href="/standards/presentation/flow-3.md">Flow 3 (direct to Backend)</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.toolkit.equs.ai/standards/presentation/choose-a-flow.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
