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

# Quickstart

> Store a user's card once, then complete a first purchase from an agent browser in about fifteen minutes.

This guide takes you from zero to a first purchase with the Vault. You will store a test card, attach Agentcard to an agent browser, and let the user approve a payment with their passkey.

**The flow in one line:** the user stores a card once → your agent shops in a browser and submits a placeholder card → Agentcard pauses the payment → the user approves on their device → that device pays with the real card → your agent confirms the order.

Step 1 happens once per user. Steps 2 to 4 happen on every purchase. Presets are optional: once it works, you can attach a preset to one of a user's cards, and only that card's purchases are filtered.

## 1. Get your credentials

You need an Agentcard organization `client_id` and `client_secret`. Create them in the [dashboard](https://app.agentcard.sh) and exchange them for an access token:

```bash theme={null}
curl -X POST https://api.agentcard.sh/api/v2/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=$AGENTCARD_CLIENT_ID \
  -d client_secret=$AGENTCARD_CLIENT_SECRET
```

Use the returned token as `$ORG_TOKEN` below. Sandbox credentials create sandbox sessions and sandbox authorizations, so start there.

## 2. Store a card

Create a vault session and send the user the link wherever you already talk to them: iMessage, WhatsApp, your app.

```bash 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 theme={null}
{
  "id": "vs_2q9d1x8f3k2m4t7w",
  "url": "https://vault.agentcard.sh/v?vs=vs_2q9d1x8f3k2m4t7w.3k1v…",
  "poll_interval": 3,
  "expires_at": "2026-08-28T21:00:00Z"
}
```

The user opens the link, types their card, and saves it with a passkey (Face ID, Touch ID, or fingerprint). A master password is offered afterwards as a backup. The page asks for a master password before the card is stored when the card will open only in this browser. The card is encrypted on their device before it leaves. When they finish, you receive a `vault.session_linked` webhook with their `user_id`, or you poll the session until its `status` is `linked`. Store that `user_id`, you need it on every purchase.

For a test run, store a test card: any of [Stripe's published test cards](https://docs.stripe.com/testing), any future expiry, any CVC.

[More on adding cards →](/vault/adding-a-card)

## 3. Attach Agentcard to your browser

Install the SDK next to your browser provider. This example uses KERNEL; Browserbase and any CDP browser work the same way.

```bash theme={null}
npm i @agent-cards/checkout @onkernel/sdk playwright-core
```

Attach **before** your agent reaches the payment form. The SDK watches the page for the payment processor's request.

```ts theme={null}
import Kernel from '@onkernel/sdk';
import { chromium } from 'playwright-core';
import { VaultClient, attachToPlaywright } from '@agent-cards/checkout';

const vault = new VaultClient({
  clientId: process.env.AGENTCARD_CLIENT_ID!,
  clientSecret: process.env.AGENTCARD_CLIENT_SECRET!,
});
await vault.syncRegistry();

const kernel = new Kernel({ apiKey: process.env.KERNEL_API_KEY! });
const kernelBrowser = await kernel.browsers.create({ stealth: true });
const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
const context = browser.contexts()[0] ?? (await browser.newContext({ serviceWorkers: 'block' }));
const page = context.pages()[0] ?? (await context.newPage());

const checkout = await attachToPlaywright(page, {
  vault,
  user: 'usr_8f3k2m',            // from step 2
  merchant: 'shop.agentcard.sh', // what the user sees on the approval screen
  amount: 2306,
  currency: 'usd',
  onApprovalUrl: (url) => sendToUser(url), // deliver over your channel
});
```

[More on creating a cart →](/vault/creating-a-cart)

## 4. Complete the purchase

Let your agent shop as usual. At checkout it should fill the card form with placeholder data, any of [Stripe's published test cards](https://docs.stripe.com/testing), and submit. The Agentcard SDK intercepts the processor request and pauses it. `onApprovalUrl` fires with a link; send it to the user. They approve with their passkey, their device sends the real card to the processor, and the paused request resumes with the real response.

Then confirm the order with the merchant before you tell the user anything:

```ts theme={null}
await page.goto('https://shop.agentcard.sh');
await runAgentCheckout(page);   // your agent: add to cart, fill the form, submit

const result = await checkout.reconcile();
if (result.status === 'completed') {
  await notifyUser(`Order ${result.orderId} confirmed`);
}
```

[More on completing a purchase →](/vault/completing-a-purchase)

## Try it against a store that always works

[shop.agentcard.sh](https://shop.agentcard.sh) is a demo store on Stripe test mode, kept running for exactly this rehearsal. Add a product, submit the card form with the placeholder card, approve on the device that holds your passkey, and the order completes with a real test-mode charge.

## Keep going

<CardGroup cols={2}>
  <Card title="Adding a card" href="/vault/adding-a-card">
    Open vs connected sessions, webhooks vs polling, returning users.
  </Card>

  <Card title="Creating a cart" href="/vault/creating-a-cart">
    Browsers, SDK options, and the Purchase API alternative.
  </Card>

  <Card title="Completing a purchase" href="/vault/completing-a-purchase">
    Approval, reconciliation, webhooks, supported processors.
  </Card>
</CardGroup>


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