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

# Card attachment

> The user attaches their own Visa card so their agent's purchases charge it directly — no KYC, no balance funding.

Let the user bring their own card. Your backend asks Agentcard for a secure
link; the user opens it and adds their Visa in about a minute — a one-time
code from their bank plus a passkey. From then on, every single-use card the
agent creates charges the user's own card directly: no identity verification
(KYC) and no balance to fund, which is what makes this the fastest path to
production. Multi-use cards are the one exception — they stay balance-funded
(and `multi_use` + `connected_card_id` is rejected), so keep the balance/KYC
flow if your integration issues them.

The card number is entered on the hosted page only — it never passes through
your servers.

<Note>
  **Over MCP:** once the user is connected, their agent can run this same flow
  itself with the [attach\_card](/companies/mcp/tools/attach_card) tool;
  [list\_attached\_cards](/companies/mcp/tools/list_attached_cards) and
  [remove\_attached\_card](/companies/mcp/tools/remove_attached_card) manage the
  enrollments, and [create\_card](/companies/mcp/tools/create_card) picks one
  with `connected_card_id`.
</Note>

## Instructions for your agent

Paste this into your coding agent to implement the attach flow. It assumes
the user is already connected (you have their `user_id` — see
[user authentication](/companies/api/user-authentication)).

```text Instructions for your agent theme={null}
You are adding "attach your own card" for a user who has already connected
(you have their user_id). The user attaches their own Visa card so their
agent's purchases charge that card directly — no identity verification (KYC)
and no wallet funding. Implement server-side with your platform token
(Authorization: Bearer <token>); base URL https://api.agentcard.sh.

1. START
POST /api/v2/attach  { "user_id": "<id>" }
-> 201 { id, status: "pending", attach_url, expires_at }   // link lives 48h
Send the user the attach_url. The hosted page takes about a minute: their
card details (entered there only — never through our servers), a one-time
code from their bank, and a passkey.
-> 200 { status: "active", card: { brand, last4 } } means a card is already
attached — nothing to do.

2. CONFIRM
When the user says they finished (or a minute or two later):
GET /api/v2/attach?user_id=<id>
-> { status: "active", card: { brand, last4 } }: done. Cards created over MCP
   now mint against the attached card; purchases charge it directly.
-> { status: "pending" }: the user hasn't finished the link — ask them to
   complete it, then check again.
-> { status: "ineligible", reason, message }: this card can't be attached
   (e.g. reason "issuer_excluded", "commercial_card"). Fall back to wallet
   funding (POST /api/v2/wallet/fund) + create_card over MCP.
-> 404 no_attachment: nothing in progress — start again with step 1.
If the user lost the link, POST /api/v2/attach again for a fresh one.

3. HANDLE THE ERRORS
-> 422 user_info_required: missing_fields names what to collect first —
   "phone_number": verify one via POST /api/v2/wallet/phone/start + /verify;
   "consent": record it via POST /api/v2/connect/consent.
-> 403/503 attach_unavailable: attaching is off right now — fall back to
   wallet funding + create_card over MCP.
ERRORS: { error: { code, message, docs } } — branch on code.
```

## How it works

1. Your backend calls `POST /api/v2/attach` for the connected user and gets
   back a secure, single-purpose link (valid 48 hours).
2. The user opens the link and adds their card on the hosted page — card
   details, a one-time code from their bank, then a passkey. You build
   nothing for this step.
3. Your backend polls `GET /api/v2/attach` until it reads `active`, with the
   card's brand and last4.
4. From then on, [create\_card](/companies/mcp/tools/create_card) automatically
   mints against the attached card — purchases charge the user's own card, and
   the KYC and balance-funding steps never come up.

## The flow

<Steps>
  <Step title="Start the attachment">
    `POST /api/v2/attach` with the `user_id`. You get `pending` with an
    `attach_url` — hand that link to the user.

    → [Start a card attachment](/companies/api/reference/attach-start)
  </Step>

  <Step title="The user completes the link">
    About a minute in their browser: card details (entered on the hosted page
    only), a one-time code from their bank, and a passkey. The page is hosted
    by Agentcard — you build nothing.
  </Step>

  <Step title="Confirm">
    `GET /api/v2/attach?user_id=…`. `active` means done; `pending` means
    nudge the user to finish the link.

    → [Get the attachment status](/companies/api/reference/attach-status)
  </Step>

  <Step title="Spend">
    `create_card` now mints against the attached card automatically — continue
    to [MCP integration](/companies/guides/mcp-server) to give your agent the
    full toolset.
  </Step>
</Steps>

<Note>
  **Eligibility.** Attachment supports the user's own consumer cards: US-issued
  Visa cards, and Mastercard from any country. Some issuers and all business
  cards are excluded, and a card's issuing bank must support the network's agent
  verification. When a card is ineligible or attachment is unavailable, fall
  back to the card creation flow — balance funding plus
  [create\_card](/companies/mcp/tools/create_card).
</Note>

<Note>
  **No KYC, but not anonymous.** The issuing bank already verified the user, so
  Agentcard runs no identity check — but a phone number and recorded consent are
  still required once (`user_info_required` names the missing pieces, each with
  a v2 endpoint to collect it).
</Note>
