Create a vault session
string
Omit this for a new user. The session is open: Agentcard creates the user during enrollment and returns their id. If you pass an id you already have, 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.
number
Lifetime in seconds (60 to 172,800). Defaults to 24 hours. Each session is single use.
$ORG_TOKEN must be a client-credentials access token. API keys are rejected with 400 client_credentials_required. Open sessions are limited to 200 per organization per rolling 24 hours.
Which kind of session
Default to an open session (nouser_id). The user sees the card form straight away, with no account to create and no code to type, and a returning user picks “Unlock with your passkey” on the same page. Pass user_id only when you already hold one and want the link bound to that account before the user opens it; that connected session starts with a one-time code to the contact on the account, which is a sign-in step your user has to get through first.
Send the link
Deliverurl to the user in the thread or app you already use with them. Each link is for a single enrollment, so send it to one person and associate the resulting user_id with whoever you sent it to.
Send the URL untouched: on its own line, as the last thing in the message, or as a message of its own. The token after
vs= is signed, and any character glued onto it (a period, a closing bracket, the first word of the next sentence) makes the phone open a different link. That link fails verification and the Vault shows its Sign in page instead of the card form, so your user sees a login step that was never part of the flow. Agents that compose messages with a language model get this wrong easily; have your code send the link rather than the model.Learn when the card is stored
You have two options.Option A: webhooks (recommended)
vault.session_linked
vault.session_linked. It still sends vault.card_stored.
Option B: poll the session
For a CLI or an agent with no public endpoint, read the session until it finishes. Use theid from the create response, never the token inside url.
Honor
poll_interval and you will never hit the read budget (40 reads a minute per session).
Check for an existing card
Never send a returning user through enrollment twice. Ask what they already have first:id, brand, last4, expiry. Never card data. Pass a card’s id as cardId on a checkout when the user should pay with a specific card.
Check for stored cards →
Test mode
A sandbox token creates a sandbox session. The passkey ceremony is real in the browser, and the user it creates is a sandbox user. On a connected session no code is delivered;111111 verifies. Store a test card, any of Stripe’s published test cards, so the purchase flow works against test-mode storefronts.