Skip to main content
An agent that lives in iMessage has nothing to embed. Your agent texts the user a link, they tap it, Safari opens the Vault, and they are back in the thread when they are done. If you send through Linq, its native integration can render the same steps as bubbles in the thread instead. Create a vault session on your server and send its url in the conversation. Say whatever your agent would say, but keep the URL alone on the last line, or send it as its own message: anything glued onto the token turns it into a broken link, and a broken link lands the user on the Vault’s sign-in page instead of the card form.
The user taps the link, types their card, and saves it with Face ID or Touch ID. There is no account to create and no code to enter: an open session (no user_id) is card-first, and a returning user taps “Unlock with your passkey” on the same page. One link is one enrollment: send it to one person, and bind the user_id you receive to that phone number. Sessions last 24 hours by default; if the user comes back later, create a new one rather than resending an old link. If you would rather not build the message, have Agentcard deliver it. POST /api/v2/checkout/vault_link texts or emails a connected user their link from Agentcard. When your agent reaches the payment form, onApprovalUrl fires with a link. Text it with what the user is approving:
The user taps it, sees the merchant and the amount, confirms with their passkey, and the purchase completes. Nobody approving within 15 minutes expires the authorization, and your agent learns that over checkout_authorization.expired.

Send through a provider

If your agent texts through an iMessage provider, the link is the message body and nothing more. Two providers, same message:
Linq also ships a native Agentcard integration, where the card enrollment and the approval render as bubbles drawn in the thread and Linq hands your agent the card to check out with. If you send through Linq, read the Linq page. Photon and Blooio carry the texted link as a plain message today.

Confirm with webhooks

The user saying “done” is a claim. The webhook is the fact:
  • vault.session_linked carries the user_id to bind to the phone number. It fires the moment the passkey binds the session, before any card is stored.
  • vault.card_stored when the card lands in the vault, in practice ten to twenty seconds after session_linked. It fires once per card, including a second card added through the same link. A returning user who only unlocks an existing vault never produces it, so treat session_linked as the sign they are in and card_stored as the sign a new card exists.
  • checkout_authorization.approved, checkout_authorization.declined and checkout_authorization.expired for each purchase.
Without a public endpoint, poll the session until its status is linked.

Test it

A sandbox token creates a sandbox session. Text the link to your own phone, store any of Stripe’s published test cards, and rehearse a purchase against shop.agentcard.sh, a demo store on Stripe test mode. Next: Create a cart.