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

# Create a checkout authorization

> Pause a captured processor request until the user approves it with their passkey.

Post the request your browser captured when the agent submitted a placeholder card to a recognized payment processor. Agentcard returns an `approvalUrl` for the user. When they approve, their device sends the real card to the processor and the authorization carries the processor `response` you replay into the paused request.

The SDK makes this call for you. Call it directly only if you run your own interception.

When the user gave your app permission to pay without asking, Agentcard pays for a supported purchase with no approval: the authorization carries `execution_mode: "autopilot"` and no `approvalUrl`. See [Enable auto-approval](/vault/app-auto-approval).

<ParamField body="user" type="string" required>The connected user whose vaulted card pays.</ParamField>
<ParamField body="merchant" type="string" required>Shown to the user on the approval screen. Up to 120 printable characters. Judged by nothing: your presets judge the merchant Agentcard names from `checkout_origin` and the payment request.</ParamField>
<ParamField body="checkout_origin" type="string">The origin of the checkout page the payment form was on, such as `https://shop.example.com`: `https://`, the host in lower case, and no path, trailing slash or `:443`. Any other value is refused with `400 invalid_request`. The SDK sends it from version 0.7.0. With the merchant identity inside `request`, this names the merchant your presets judge. Without it, a merchant, category, or place rule refuses the purchase as unknown, and the purchase always waits for the user's approval.</ParamField>
<ParamField body="amount" type="integer | string">Your hint at the amount: an integer in the currency's smallest unit (2306 for \$23.06), or a decimal string in normal units (`"23.06"`). Caps use the amount the processor charges. Send `amount` to have a purchase judged the moment your agent opens it. A hint more than one smallest unit away from the processor's amount is refused with `amount_mismatch` and nothing is charged.</ParamField>
<ParamField body="currency" type="string">ISO 4217 code for `amount`. Both together or neither. Older checkout SDKs (0.5.0 and 0.6.0) send the integer as `amount_cents`; it is still accepted and means the same as an integer `amount`.</ParamField>
<ParamField body="page_amount" type="integer">The total your browser read off the checkout page, in the smallest unit, with `page_currency`. The SDK sends it when you give it a reader. Used only when neither the processor's request nor `amount` names an amount.</ParamField>
<ParamField body="psp" type="string" required>The payment processor: `stripe`, `shopify`, `square`, `recurly`, `razorpay`, `adyen`, `tranzila`.</ParamField>
<ParamField body="mode" type="string">`token` (default), `cse` (Adyen), or `hosted_form` (Tranzila). Required for `cse` and `hosted_form`.</ParamField>
<ParamField body="card_id" type="string">Which of the user's vaulted cards should pay. Defaults to the most recently added. The user can still pick another. When the user gave your app permission on more than one card, a purchase without `card_id` waits for the user's approval.</ParamField>
<ParamField body="request" type="object" required>The captured processor request: `url`, `method`, `headers`, `body`.</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.agentcard.sh/api/v2/checkout/authorizations \
    -H "Authorization: Bearer $ORG_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "user": "usr_8f3k2m",
      "merchant": "Example Shop",
      "checkout_origin": "https://shop.example.com",
      "amount": 2306,
      "currency": "usd",
      "psp": "stripe",
      "request": {
        "url": "https://api.stripe.com/v1/tokens",
        "method": "POST",
        "headers": { "content-type": "application/x-www-form-urlencoded" },
        "body": "card[number]=<card number>&..."
      }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "id": "cauth_2q9d1x8f3k2m4t7w",
    "object": "checkout_authorization",
    "status": "awaiting_approval",
    "mode": "token",
    "amount": 2306,
    "currency": "usd",
    "amount_display": "$23.06",
    "amount_authority": "agent",
    "amount_verified": null,
    "charged_amount": null,
    "charged_currency": null,
    "replay_attempted": false,
    "approvalUrl": "https://vault.agentcard.sh/authorize?id=cauth_2q9d1x8f3k2m4t7w",
    "expiresAt": "2026-08-27T21:15:00Z"
  }
  ```
</ResponseExample>

**Errors.** `400 mode_required`, `400 mode_mismatch`, `400 currency_required` / `amount_required` (half a pair), `400 amount_invalid` (a non-integer number, or more decimals than the currency has), `400 amount_ambiguous` (a string without a decimal point), `404 card_not_found`, `409 amount_mismatch` (the processor's amount disagrees with `amount`; carries `expected_cents` and `actual_cents`), `409 intent_not_confirmable`, `502 amount_unverifiable`. `403` with a rule's code (`merchant_denied`, `category_unknown`, `geo_unknown`, `currency_denied`, `spend_rate_exceeded`, and the others) when one of your attached presets refuses the purchase; the body carries `preset`, `attachment`, `rule`, `message`, `stage: "create"`, and `refusals`, every preset that refused with its `preset`, `attachment`, and `rule` (the fields before it are the first entry), and no authorization is created.

Authorizations expire after 15 minutes without approval. When you fulfill the paused browser request with the approved `response`, add `access-control-allow-origin` echoing the request's `Origin` and `access-control-allow-credentials: true`, or the page rejects it.


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