> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentcard.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a vault session

> Create a single-use link the user opens to store a card behind their passkey.

Create the session, then deliver `url` to the user in the thread or app you already share with them. One link is one enrollment: send it to one person and bind the `user_id` you receive to them. Send the URL exactly as returned, alone on its line: the token is signed, and a link with anything appended fails verification and opens the Vault's sign-in page instead of the card form.

**user\_id** `string`

Omit for a new user: the session is **open**, the user is created at enrollment, and their id arrives in `vault.session_linked` (or on the session read). Pass an id you already hold and the session is **connected**: opening the link sends a one-time code to the contact on that account and verifying it signs the user in.

**external\_user\_id** `string`

Your own id for the user, 1 to 128 characters. Echoed on `vault.session_linked` and on the session read. On an open session for a user who already has a vault, the link asks for that user's passkey and links to their existing `user_id`; it never sets up a second vault.

**steps** `string[]`

`["card"]` opens the card form even when the user has a card on file: the link for adding another card.

**phone** `string`

Connected sessions only, E.164. Used only when the account has no contact on file at all. Refused on open sessions.

**expires\_in** `number`

Lifetime in seconds, 60 to 172800. Default 24 hours. Sessions are single use.

**approval\_mode** `string`

`partner` asks the user to let your app pay with the card they save or pick, without an approval link for each purchase. `customer` leaves the choice to the user. Omit it to use your app's default from Settings → Vault → Customize in the dashboard, which is `customer` until you change it. Only production client credentials can send `partner`: under sandbox credentials, `partner` is refused with `403 partner_enrollment_disabled`. See [Enable auto-approval](/vault/app-auto-approval).

```bash cURL theme={null}
curl -X POST https://api.agentcard.sh/api/v2/vault_sessions \
  -H "Authorization: Bearer $ORG_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

```json 201 theme={null}
{
  "object": "vault_session",
  "id": "vs_2q9d1x8f3k2m4t7w",
  "user_id": null,
  "url": "https://vault.agentcard.sh/v?vs=vs_2q9d1x8f3k2m4t7w.3k1v…",
  "channel": null,
  "destination": null,
  "expires_at": "2026-08-28T21:00:00Z",
  "poll_interval": 3,
  "test_mode": false
}
```

**id** `string`

Read the session by this id, never by the token inside `url`.

**url** `string`

The link to send the user.

**user\_id** `string | null`

Null on an open session until it links.

**poll\_interval** `number`

Seconds to wait between reads if you poll.

**Errors.** `400 client_credentials_required` (API key used), `422 contact_missing` (connected session, nothing to send a code to), `403 partner_enrollment_disabled` (app auto-approval isn't available to this app in this mode: send `approval_mode: "customer"`), `429 rate_limited` (open sessions are budgeted at 200 per organization per rolling 24 hours).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.