# Agent Checkouts Quickstart ⚡ Source: https://docs.crossmint.com/agents/agent-checkouts-quickstart Start a checkout, answer buyer requests, and read the result Send the agent a product URL and a task. It navigates the merchant's checkout, asks your application for missing inputs or payment authorization, and returns the purchase result. Explore the complete experience in a working app Use the full integration as a reference for your app ## Prerequisites * **API key**: A production server-side key with `agent-checkouts.create`, `agent-checkouts.read`, `agent-checkouts.update`, and `agent-checkouts.cancel` scopes from the Crossmint Console * **Buyer identity**: A stable identifier for your user, sent as `x-crossmint-user-id` on every request * **Purchase task**: A product URL, the variant and quantity to buy, and a spending cap * **Card authorization**: To complete a card purchase, a [saved](/agents/payment-methods/cards/save-card) and [registered](/agents/payment-methods/cards/register-card) card, plus a client-side key and buyer JWT as described in [Authorize Payments](/agents/checkouts/payments) Use the same user ID as your JWT's configured user ID claim (`sub` by default), so the checkout and its card authorization belong to the same buyer. Agent Checkouts does not support staging. These examples run on your backend; keep the server key out of browser code. For direct browser calls, see [Authenticate Each Request](/agents/checkouts/follow-run#authenticate-each-request). Agent Checkouts and the live demo can place real orders. Use a task and spending cap that you intend to authorize. ## Run a Checkout Set these variables in your terminal. Reuse them in the following steps: ```bash theme={null} export CROSSMINT_API_KEY="YOUR_SERVER_API_KEY" export CROSSMINT_USER_ID="YOUR_USER_ID" export CHECKOUT_API="https://www.crossmint.com/api/unstable/agent-checkouts" ``` Replace the sample URL and task with your intended purchase, then create a run: ```bash cURL theme={null} curl --fail-with-body --request POST "$CHECKOUT_API" \ --header "X-API-KEY: $CROSSMINT_API_KEY" \ --header "x-crossmint-user-id: $CROSSMINT_USER_ID" \ --header "Content-Type: application/json" \ --data '{ "request": { "startUrl": "https://merchant.example/products/classic-tee", "task": "Buy one black Classic Tee in size medium. Use standard delivery and pay by card." }, "constraints": { "maxCost": { "amount": "100.00", "currency": "USD" } } }' ``` The response contains a `runId`. Save it for subsequent calls: ```bash theme={null} export RUN_ID="YOUR_RETURNED_RUN_ID" ``` To prefill shipping details or set the browser country, see [Configure a Checkout](/agents/checkouts/configure). Read its current status and any request waiting for your application: ```bash cURL theme={null} curl --fail-with-body "$CHECKOUT_API/$RUN_ID" \ --header "X-API-KEY: $CROSSMINT_API_KEY" \ --header "x-crossmint-user-id: $CROSSMINT_USER_ID" ``` While the run is active, repeat this read every 2 seconds. When `status` is `"awaiting_input"`, handle `requiredAction`. Your application chooses how to present the request: in a web page, a native app, or a conversation. | `requiredAction.request.interaction.kind` | What your application does | | - | - | | `form` | Collect the requested fields. Use ordinary controls for `handling: "standard"` and `CrossmintProtectedInput` for `handling: "protected"`. | | `payment` | For `method: "card"`, authorize the buyer's saved card with an order intent. For `method: "klarna"`, show the buyer the request's `authorizationUrl` and send no answer. | For live updates and conversation history, see [Follow a Run](/agents/checkouts/follow-run). You can optionally display the agent's browser using `run.browser.embedUrl` once `run.browser` is available. Copy `requiredAction.requestId` into your response. For example, if a form requests a standard field whose `key` is `email`, send the buyer's answer: ```bash cURL theme={null} curl --fail-with-body --request POST "$CHECKOUT_API/$RUN_ID/messages" \ --header "X-API-KEY: $CROSSMINT_API_KEY" \ --header "x-crossmint-user-id: $CROSSMINT_USER_ID" \ --header "Content-Type: application/json" \ --data '{ "id": "answer_email_001", "parts": [{ "type": "input_response", "requestId": "YOUR_FORM_REQUEST_ID", "action": "submit", "response": { "kind": "form", "answers": { "email": "buyer@example.com" } } }] }' ``` Each submission answers the complete request: include all required fields, and omit optional fields left unanswered. [Handle Buyer Inputs](/agents/checkouts/buyer-inputs) shows the field types, ordinary rendering, and protected collection. When the agent asks for a card payment, follow [Authorize Payments](/agents/checkouts/payments) to create an order intent for the request's amount and merchant using the same buyer's saved card. Complete any verification, then submit this body to the same messages endpoint: ```json theme={null} { "id": "answer_payment_001", "parts": [{ "type": "input_response", "requestId": "YOUR_PAYMENT_REQUEST_ID", "action": "submit", "response": { "kind": "payment", "orderIntentId": "YOUR_ORDER_INTENT_ID" } }] } ``` Use a unique message `id` for each answer. If you retry after a lost acknowledgement, resend the same ID and body. A payment answer contains the order intent ID; it never contains card details. After each answer, resume reading the run and handle further requests until it finishes. A read can briefly show a request you already answered; handle each `requestId` only once, retrying its original message if needed. At a terminal status, read the result: | Status | What to read | | - | - | | `succeeded` | `result.summary` describes the purchase. If `result.purchase.kind` is `"receipt_captured"`, read `result.purchase.receipt`. | | `blocked` | `result.code` and `result.summary` explain why the agent stopped. | | `failed` | `reason` explains the failure. | | `cancelled` | Cancellation has completed. | An accepted answer resumes the agent. The final run status tells you whether the purchase succeeded. To stop an active run, request cancellation and keep reading until it reaches a terminal status: ```bash cURL theme={null} curl --fail-with-body --request POST "$CHECKOUT_API/$RUN_ID/cancel" \ --header "X-API-KEY: $CROSSMINT_API_KEY" \ --header "x-crossmint-user-id: $CROSSMINT_USER_ID" ``` See [Finish or Cancel](/agents/checkouts/follow-run#finish-or-cancel) for the complete result behavior. ## Launching in Production Agent Checkouts already uses production credentials. Before serving buyers, add [streaming and recovery](/agents/checkouts/follow-run), [buyer input handling](/agents/checkouts/buyer-inputs), and [payment authorization](/agents/checkouts/payments) for your application's user experience. The sample app above shows how these pieces fit together. If a create-run acknowledgement is lost, inspect [List Checkouts](/api-reference/agent-checkouts/list-agent-checkouts) before creating another run. ## Learn More Prefill buyer details and set merchant guidance Stream updates, steer the agent, and recover after disconnects # Agent Cards Quickstart ⚡ Source: https://docs.crossmint.com/agents/cards-quickstart Get your agent paying with agent cards in 15 minutes Give agents permission to pay with a user's card using Crossmint's Agentic Payments API. This quickstart runs the [agent cards reference app](https://github.com/Crossmint/card-permissions-quickstart). By the end you will have a running app where a user can sign in, save a card, register its supported rails, authorize an order intent, and mint secure card credentials. See the full flow in action without setting anything up locally. Explore the full reference implementation for agents, payment methods, and agent cards. ## Prerequisites * Node.js 20+ and pnpm * A [Stytch](https://stytch.com) account (used as the auth provider in this example) **Eligible Cards** Agent cards work with any credit or debit card. What varies by card is who issues the agent's credential: a card-network program, or Crossmint's encrypted card fallback. Card-network rails — Visa Intelligent Commerce and Mastercard Agent Pay — support a subset of cards, and Visa and Mastercard keep expanding that coverage: * **Mastercard Agent Pay:** Mastercard credit and debit cards * **Visa Intelligent Commerce:** U.S.-issued Visa credit and debit cards, except business cards, prepaid cards, Chase cards, and Fidelity cards Cards that no card-network rail supports yet, such as AMEX, Ramp, or non-US Visa cards, use the [encrypted card rail](/agents/payment-methods/cards/retrieve-agent-card). To enable it in production, contact us. ## Setup You can ask your agent to walk you through the setup to run this quickstart. ```bash theme={null} git clone https://github.com/Crossmint/card-permissions-quickstart.git cd card-permissions-quickstart pnpm install ``` Copy the example file and fill in the keys from the previous steps: ```bash theme={null} cp .env.example .env.local ``` ```bash .env.local theme={null} NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN=your-stytch-public-token NEXT_PUBLIC_CROSSMINT_CLIENT_API_KEY=your-crossmint-client-api-key ``` Sign in to the Crossmint Staging Console and create a project. Staging keys come with **all scopes enabled by default**, so you don't need to configure anything else for the quickstart. Copy the key and paste it into your `.env.local`. In the Stytch dashboard, in the **Test** environment of a **B2C** project: 1. **Configuration → SDK Configuration → OAuth** — enable **Google** (Stytch's shared test client works, no Google Cloud setup needed). 2. **Configuration → Redirect URLs** — add `http://localhost:3000` as both **Login** and **Signup**. Use exactly that, no trailing slash or `/callback`. 3. **Project Settings → API Keys** — copy the **Public token** (`public-token-test-...`) into `NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN` in your `.env.local`. In the Crossmint Staging Console, under **3P Auth providers**: 1. Select **Stytch** from the provider dropdown. 2. Paste your Stytch **Project ID** (`project-test-...`, found in Stytch under **Project Settings → Project ID**). 3. Leave **Verifier Id** as `sub` (default). Crossmint will start trusting JWTs minted by your Stytch project on subsequent SDK calls. ```bash theme={null} pnpm dev ``` Open [http://localhost:3000](http://localhost:3000). ## Understanding the user flow Once running, the app walks the user through six steps: 1. **Authenticate.** Sign in with Google via Stytch. The session JWT is bridged into the Crossmint SDK so every API call is scoped to the user. 2. **Save a card.** The `CrossmintPaymentMethodManagement` component collects the card in a PCI-compliant iframe and returns a `paymentMethodId`. 3. **Register the card.** Registration discovers the card's supported rails, such as Visa Intelligent Commerce or Mastercard Agent Pay. It grants no spending permission and requires no verification. 4. **Create an order intent.** The app creates an allowance with an amount, description, expiration, and—when already known—the merchant. The response can contain multiple rails, each with its own verification status and credential formats. If no card-network rail is usable, the response also includes an `encrypted-card` rail that is active immediately (in production, only for projects with encrypted card access enabled). 5. **Verify the rail you want to use.** If the selected rail has `status: "pending_verification"`, the `OrderIntentVerification` component runs its provider ceremony. Other rails do not need to be verified and can remain pending. A returning Visa user authenticates with the passkey already bound to the device. 6. **Mint credentials.** The app uses the selected rail's `rail` and `provider` and requests a credential for a specific amount. If the merchant was not set on the order intent, the app supplies it now. The response contains the secure one-time card number, expiration, and CVC. For the `encrypted-card` rail, minting takes an RSA public key instead and returns the saved card as a JWE for the agent to decrypt locally. Treat `rails` as a menu, not a checklist. Only the rail used to mint the credential must be `active`; unrelated rails do not block it. ## Next Steps Style the card and passkey verification modals to match your brand. Let Crossmint drive a real browser and complete checkout on any site. # Agent Cards Source: https://docs.crossmint.com/agents/cards/overview Save a user's card once, then issue as many scoped, revocable agent cards from it as your agents need Save a real card once, Crossmint tokenizes it, and you create virtual cards with their own limits for your agents Save a real card once, Crossmint tokenizes it, and you create virtual cards with their own limits for your agents Your user saves their real card once. From that card, you create as many **scoped authorizations** as your agents need, each with its own limit, purpose, and expiration. Crossmint calls these order intents. From an order intent, the agent mints a credential on whichever rail the purchase needs, and pays without ever seeing the real card number. For the problem this solves and how it compares to other approaches, read [How Agents Pay](/agents/how-agents-pay).