> ## 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

> Connect a test user, open the wallet, add a test card, and make a payment. Everything runs in sandbox.

This takes about fifteen minutes. Everything happens in sandbox, so no email gets sent, no money moves, and the verification code is always `111111`.

Before you start, open the [dashboard](https://app.agentcard.sh) and go to **Settings → Developers → Credentials**. That's where your sandbox `client_id` and `client_secret` live; if you don't have a client yet, **Implement Agentcard** in the same menu creates one.

<Steps>
  <Step title="Authenticate your server">
    Exchange your credentials for a bearer token. The request is form-encoded, per OAuth.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.agentcard.sh/api/v2/oauth/token \
        -d grant_type=client_credentials \
        -d client_id=YOUR_CLIENT_ID \
        -d client_secret=YOUR_CLIENT_SECRET
      ```

      ```javascript Node theme={null}
      const res = await fetch("https://api.agentcard.sh/api/v2/oauth/token", {
        method: "POST",
        body: new URLSearchParams({
          grant_type: "client_credentials",
          client_id: "YOUR_CLIENT_ID",
          client_secret: "YOUR_CLIENT_SECRET",
        }),
      });
      const { access_token } = await res.json();
      ```

      ```python Python theme={null}
      import requests

      res = requests.post(
          "https://api.agentcard.sh/api/v2/oauth/token",
          data={
              "grant_type": "client_credentials",
              "client_id": "YOUR_CLIENT_ID",
              "client_secret": "YOUR_CLIENT_SECRET",
          },
      )
      access_token = res.json()["access_token"]
      ```
    </CodeGroup>

    You get back an `access_token`. Use it as `Authorization: Bearer` on every call below.
  </Step>

  <Step title="Connect a test user">
    Start a connection. In sandbox nothing is actually sent, so any email works.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.agentcard.sh/api/v2/connect/start \
        -H "Authorization: Bearer $ORG_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"email": "testuser@example.com"}'
      ```

      ```javascript Node theme={null}
      const res = await fetch("https://api.agentcard.sh/api/v2/connect/start", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${ORG_TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ email: "testuser@example.com" }),
      });
      const attempt = await res.json();
      ```

      ```python Python theme={null}
      import requests

      res = requests.post(
          "https://api.agentcard.sh/api/v2/connect/start",
          headers={"Authorization": f"Bearer {ORG_TOKEN}"},
          json={"email": "testuser@example.com"},
      )
      attempt = res.json()
      ```
    </CodeGroup>

    Verify with the sandbox code:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.agentcard.sh/api/v2/connect/verify \
        -H "Authorization: Bearer $ORG_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"connect_id": "CONNECT_ATTEMPT_ID", "code": "111111"}'
      ```

      ```javascript Node theme={null}
      const res = await fetch("https://api.agentcard.sh/api/v2/connect/verify", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${ORG_TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ connect_id: "CONNECT_ATTEMPT_ID", code: "111111" }),
      });
      const connection = await res.json();
      ```

      ```python Python theme={null}
      import requests

      res = requests.post(
          "https://api.agentcard.sh/api/v2/connect/verify",
          headers={"Authorization": f"Bearer {ORG_TOKEN}"},
          json={"connect_id": "CONNECT_ATTEMPT_ID", "code": "111111"},
      )
      connection = res.json()
      ```
    </CodeGroup>

    The response includes the user's `user_id` and a connection token. Save both. This also fires your first webhook, `connection.created`.

    Then record the user's authorization. This is the consent step: it registers that the user agreed to let your product and their agent use their wallet, and wallet links can't be created for them until it's on file. In your product the wallet shows the user a consent screen; in this tutorial you record it directly:

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

      ```javascript Node theme={null}
      const res = await fetch("https://api.agentcard.sh/api/v2/connect/consent", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${ORG_TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ user_id: "USER_ID" }),
      });
      const data = await res.json();
      ```

      ```python Python theme={null}
      import requests

      res = requests.post(
          "https://api.agentcard.sh/api/v2/connect/consent",
          headers={"Authorization": f"Bearer {ORG_TOKEN}"},
          json={"user_id": "USER_ID"},
      )
      data = res.json()
      ```
    </CodeGroup>
  </Step>

  <Step title="Create a wallet link">
    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.agentcard.sh/api/v2/wallet_links \
        -H "Authorization: Bearer $ORG_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"user_id": "USER_ID"}'
      ```

      ```javascript Node theme={null}
      const res = await fetch("https://api.agentcard.sh/api/v2/wallet_links", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${ORG_TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ user_id: "USER_ID" }),
      });
      const link = await res.json();
      ```

      ```python Python theme={null}
      import requests

      res = requests.post(
          "https://api.agentcard.sh/api/v2/wallet_links",
          headers={"Authorization": f"Bearer {ORG_TOKEN}"},
          json={"user_id": "USER_ID"},
      )
      link = res.json()
      ```
    </CodeGroup>

    The response includes a `url`. This is what you hand to the wallet in the next step. The same link works on any platform.
  </Step>

  <Step title="Open the wallet">
    Put this on any page:

    ```html theme={null}
    <script src="https://app.agentcard.sh/js/v1/agentcard.js"></script>
    <script>
      const wallet = AgentCard.create({
        token: "WALLET_LINK_URL",
        onSuccess: (data) => console.log(data.type),
      });
      wallet.open();
    </script>
    ```

    The wallet opens as a sheet. Add a card with the test number `4242 4242 4242 4242`, any future expiry, any CVC. `onSuccess` fires with `card_attached`, and the `connected_card.updated` webhook goes out.
  </Step>

  <Step title="Make the first payment">
    Open the wallet again, this time asking for a payment:

    ```html theme={null}
    <script>
      AgentCard.create({
        token: "WALLET_LINK_URL",
        pay: { amountCents: 500 },
        onSuccess: (data) => console.log(data.type),
      }).open();
    </script>
    ```

    The user approves, and `onSuccess` fires with `payment_completed`. And that's it. You connected a user, they added a card, and a payment went through.
  </Step>

  <Step title="See what happened">
    Open the [dashboard](https://app.agentcard.sh) and check **Webhooks → Deliveries**. Every event from this tutorial is in there, with its payload: `connection.created`, `connected_card.updated`, and the payment events.
  </Step>
</Steps>

## Where next

In production your server should be listening for those events instead of reading them in the dashboard. The [Webhooks](/wallet/webhooks) page shows how.

To put the wallet in your actual product, go to [Choose your platform](/platforms/choose-your-platform). And when you want your agent to actually buy things, that's the [Purchase API](/purchase/purchase-api).
