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

# Buy

> One conversational endpoint that places real orders. Send the user's request as plain text in `ask`; thread follow-ups with `conversation_id`; place a shown cart by echoing its `hash` in `confirm` (or an array of hashes for several carts). Money only moves on a confirm, and only for exactly the cart the hash describes.



## OpenAPI

````yaml openapi.json POST /buy
openapi: 3.1.0
info:
  title: Agentcard API
  version: 2.0.0
  description: >-
    The Agentcard v2 API — connect your users and verify their identity from
    your own backend. Every call is authenticated with a platform access token
    minted from your `client_id` + `client_secret`.
servers:
  - url: https://api.agentcard.sh
    description: >-
      There is one base URL. Sandbox vs production is decided by the client
      credential you use, never by the host.
security:
  - platformToken: []
tags:
  - name: Authentication
    description: >-
      Exchange your client credentials for a platform access token, and
      introspect what a token acts as.
  - name: Connect
    description: >-
      Connect a user to your platform: send a one-time code, verify it, record
      consent, and keep the connection alive.
  - name: Identity verification
    description: >-
      Verify a connected user's identity: upload their ID, submit any extra
      fields we ask for, then show a short face scan.
  - name: Wallet funding
    description: >-
      Fund a connected user's wallet from your own UI — request a payment link,
      relay the phone verification code, and poll until the funds land.
  - name: Withdrawals
    description: >-
      Move money out of a connected user's wallet — to a saved bank account or a
      crypto address on Base. Transfers are processed manually by the Agentcard
      team, usually within 1-3 business days.
paths:
  /buy:
    post:
      tags:
        - Purchase
      summary: Buy
      description: >-
        One conversational endpoint that places real orders. Send the user's
        request as plain text in `ask`; thread follow-ups with
        `conversation_id`; place a shown cart by echoing its `hash` in `confirm`
        (or an array of hashes for several carts). Money only moves on a
        confirm, and only for exactly the cart the hash describes.
      operationId: buy
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ask:
                  type: string
                  description: >-
                    What the user wants, in plain language. Required unless the
                    call is a confirm.
                  minLength: 1
                  pattern: \S
                conversation_id:
                  type: string
                  description: The thread to continue. A confirm always requires it.
                  minLength: 1
                confirm:
                  description: >-
                    A cart hash from a previous response (16 hex characters), or
                    an array of hashes to place several carts. An array confirm
                    cannot carry an ask in the same call.
                  oneOf:
                    - type: string
                      pattern: ^[0-9a-f]{16}$
                    - type: array
                      items:
                        type: string
                        pattern: ^[0-9a-f]{16}$
                      minItems: 1
                      maxItems: 8
                payment_source:
                  type: string
                  enum:
                    - vault
                  description: >-
                    Pay the confirmed cart(s) with the user's own vaulted card,
                    whatever the user's wording: the confirm pauses with
                    decline_code vault_approval_required and an approval_url,
                    the user approves on their device, and the same confirm
                    places the order. Confirm-only. Omit it and the loop keeps
                    its default source.
              anyOf:
                - required:
                    - ask
                - required:
                    - confirm
              dependentRequired:
                confirm:
                  - conversation_id
                payment_source:
                  - confirm
              not:
                required:
                  - ask
                  - confirm
                properties:
                  confirm:
                    type: array
            examples:
              ask:
                summary: Start a purchase
                value:
                  ask: >-
                    a 16 oz bag of Colombian ground coffee from Amazon, ship it
                    to 1900 Jefferson St, San Francisco
              confirm:
                summary: Place a shown cart
                value:
                  conversation_id: cmsq18x2m00a1
                  confirm: 9f2c4a1b8e3d5f07
              multiCartConfirm:
                summary: Place several carts
                value:
                  conversation_id: cmsq18x2m00a1
                  confirm:
                    - 9f2c4a1b8e3d5f07
                    - 31d8a6e0c47b92f5
      responses:
        '200':
          description: One turn of the purchase conversation, in the fixed envelope.
          content:
            application/json:
              schema:
                type: object
                description: >-
                  The fixed response envelope. Every field is present on every
                  response, null when empty.
                properties:
                  conversation_id:
                    type: string
                    description: >-
                      Thread it back on every follow-up. Returned on the first
                      call too.
                  status:
                    type: string
                    enum:
                      - needs_input
                      - order_placed
                      - partially_placed
                      - declined
                    description: >-
                      needs_input is progress, not failure: the reply is a
                      question or a cart waiting on confirmation.
                  reply:
                    type: string
                    description: The assistant's turn as prose, ready to show a human.
                  messages:
                    type: array
                    items:
                      type: string
                    description: >-
                      The same turn split into ordered bubbles for chat
                      surfaces.
                  message_id:
                    type: string
                  cart:
                    type:
                      - object
                      - 'null'
                    description: >-
                      The most recently shown cart. Null when no cart is on the
                      table.
                    properties:
                      merchant:
                        type: string
                        description: Public merchant id, e.g. retail, doordash, goodeggs.
                      merchant_name:
                        type: string
                        description: >-
                          Display name for the merchant, or the store when one
                          is selected (Amazon, Walmart).
                      items:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                            qty:
                              type: integer
                            priceCents:
                              type: integer
                            product_id:
                              type:
                                - string
                                - 'null'
                              description: >-
                                The merchant's id for the line; tells two
                                same-name lines apart. Null on carts shown
                                before it was captured.
                          required:
                            - name
                            - qty
                            - product_id
                      serviceFeesCents:
                        type: integer
                        description: >-
                          All fees combined, including the Agentcard service
                          fee.
                      tipCents:
                        type: integer
                      totalCents:
                        type: integer
                        description: >-
                          The all-in amount a confirm authorizes: merchandise,
                          fees, and tip.
                      hash:
                        type: string
                        description: >-
                          Identity of exactly this cart. Echo it back as confirm
                          to place the order.
                    required:
                      - merchant
                      - merchant_name
                      - items
                      - serviceFeesCents
                      - tipCents
                      - totalCents
                      - hash
                  carts:
                    type: array
                    items:
                      type: object
                      description: >-
                        The most recently shown cart. Null when no cart is on
                        the table.
                      properties:
                        merchant:
                          type: string
                          description: Public merchant id, e.g. retail, doordash, goodeggs.
                        merchant_name:
                          type: string
                          description: >-
                            Display name for the merchant, or the store when one
                            is selected (Amazon, Walmart).
                        items:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                              qty:
                                type: integer
                              priceCents:
                                type: integer
                              product_id:
                                type:
                                  - string
                                  - 'null'
                                description: >-
                                  The merchant's id for the line; tells two
                                  same-name lines apart. Null on carts shown
                                  before it was captured.
                            required:
                              - name
                              - qty
                              - product_id
                        serviceFeesCents:
                          type: integer
                          description: >-
                            All fees combined, including the Agentcard service
                            fee.
                        tipCents:
                          type: integer
                        totalCents:
                          type: integer
                          description: >-
                            The all-in amount a confirm authorizes: merchandise,
                            fees, and tip.
                        hash:
                          type: string
                          description: >-
                            Identity of exactly this cart. Echo it back as
                            confirm to place the order.
                      required:
                        - merchant
                        - merchant_name
                        - items
                        - serviceFeesCents
                        - tipCents
                        - totalCents
                        - hash
                    description: >-
                      Every open cart in the conversation, oldest first. A
                      conversation can hold carts at several merchants.
                  placements:
                    type:
                      - array
                      - 'null'
                    description: >-
                      Per-cart outcomes of a multi-cart confirm; null on every
                      other call. Partial success is representable here.
                    items:
                      type: object
                      properties:
                        merchant:
                          type: string
                        merchant_name:
                          type: string
                        status:
                          type: string
                          enum:
                            - needs_input
                            - order_placed
                            - partially_placed
                            - declined
                        reply:
                          type: string
                        error_code:
                          type:
                            - string
                            - 'null'
                        order_id:
                          type:
                            - string
                            - 'null'
                          description: This cart's order id when it placed.
                        payment_source:
                          $ref: '#/components/schemas/PaymentSource'
                        decline_code:
                          type:
                            - string
                            - 'null'
                        approval_url:
                          type:
                            - string
                            - 'null'
                        charge_status:
                          type:
                            - string
                            - 'null'
                          enum:
                            - none
                            - confirming
                            - settled
                            - unknown
                            - null
                      required:
                        - merchant
                        - merchant_name
                        - status
                        - reply
                        - order_id
                        - payment_source
                        - decline_code
                        - approval_url
                        - charge_status
                  catalog:
                    type:
                      - object
                      - 'null'
                    description: >-
                      The last product search as data, with a freshness stamp.
                      Null when nothing fresh was searched.
                    properties:
                      merchant:
                        type: string
                      merchant_name:
                        type: string
                      store:
                        type:
                          - object
                          - 'null'
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                      items:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            name:
                              type: string
                            priceCents:
                              type: integer
                          required:
                            - id
                      as_of:
                        type: string
                        format: date-time
                  error_code:
                    type:
                      - string
                      - 'null'
                    description: Machine-readable failure code when something went wrong.
                  order_id:
                    type:
                      - string
                      - 'null'
                    description: >-
                      Set when this call placed an order: the merchant's order
                      id, or Agentcard's when the merchant returns none. The
                      same key as order.orderId in GET
                      /cards/transactions/by-payment-method and order_id on
                      order.placed. Null on a multi-cart confirm (see
                      placements).
                  payment_source:
                    $ref: '#/components/schemas/PaymentSource'
                  decline_code:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The machine code behind a declined: a gate reason
                      (byoc_approval_required, vault_approval_required,
                      sandbox_mode, per_txn_max_exceeded, card_limit_reached,
                      ...) or a merchant code (items_unavailable,
                      pos_cart_validation). Null on success and on recoverable
                      errors.
                  approval_url:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The link to send the user when the attempt paused for
                      their bank's or Vault's approval. Send the same confirm
                      again once they approve.
                  charge_status:
                    type:
                      - string
                      - 'null'
                    enum:
                      - none
                      - confirming
                      - settled
                      - unknown
                      - null
                    description: >-
                      Whether money moved on this call's checkout: none (nothing
                      charged, nothing pending: every decline, approval pause
                      and refusal answered before money moved), confirming
                      (placed, charge still confirming), settled, or unknown
                      (the attempt may have moved money and Agentcard cannot yet
                      say; do not retry, read the conversation's orders, then
                      support). Null when no checkout ran.
                  unmatched:
                    type: array
                    description: >-
                      Asks that did not make it into a cart, cumulative for the
                      conversation, with machine-derived reasons and the moment
                      each happened. An entry leaves only when the same line
                      later lands in a cart; placing an order does not clear it.
                      Never inferred from the reply. Always an array.
                    items:
                      type: object
                      properties:
                        merchant:
                          type: string
                        requested:
                          type: string
                          description: The query or line name that was asked for.
                        reason:
                          type: string
                          enum:
                            - not_found
                            - unavailable
                        detail:
                          type:
                            - string
                            - 'null'
                          description: >-
                            The merchant's own words when it refused, dropped,
                            or delisted the line.
                        at:
                          type: string
                          format: date-time
                          description: When it happened; identifies the turn it came from.
                      required:
                        - merchant
                        - requested
                        - reason
                        - detail
                        - at
                required:
                  - conversation_id
                  - status
                  - reply
                  - messages
                  - message_id
                  - cart
                  - carts
                  - placements
                  - catalog
                  - error_code
                  - order_id
                  - payment_source
                  - decline_code
                  - approval_url
                  - charge_status
                  - unmatched
        '400':
          description: Invalid request body.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  hint:
                    type: string
        '404':
          description: conversation_id not found for this user and connection.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
        '409':
          description: >-
            The call could not run: the cart changed since that hash was issued
            (the body carries the fresh carts), nothing has been shown to
            confirm yet, the conversation is closed, or another turn is still
            running on this conversation (code turn_in_progress: wait for GET
            /buy/conversations/:id to report turn_in_progress false, then send
            again). Never a charge.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                    description: 'Present on the turn conflict: turn_in_progress.'
                  conversation_id:
                    type: string
                  cart:
                    type:
                      - object
                      - 'null'
                    description: >-
                      The most recently shown cart. Null when no cart is on the
                      table.
                    properties:
                      merchant:
                        type: string
                        description: Public merchant id, e.g. retail, doordash, goodeggs.
                      merchant_name:
                        type: string
                        description: >-
                          Display name for the merchant, or the store when one
                          is selected (Amazon, Walmart).
                      items:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                            qty:
                              type: integer
                            priceCents:
                              type: integer
                            product_id:
                              type:
                                - string
                                - 'null'
                              description: >-
                                The merchant's id for the line; tells two
                                same-name lines apart. Null on carts shown
                                before it was captured.
                          required:
                            - name
                            - qty
                            - product_id
                      serviceFeesCents:
                        type: integer
                        description: >-
                          All fees combined, including the Agentcard service
                          fee.
                      tipCents:
                        type: integer
                      totalCents:
                        type: integer
                        description: >-
                          The all-in amount a confirm authorizes: merchandise,
                          fees, and tip.
                      hash:
                        type: string
                        description: >-
                          Identity of exactly this cart. Echo it back as confirm
                          to place the order.
                    required:
                      - merchant
                      - merchant_name
                      - items
                      - serviceFeesCents
                      - tipCents
                      - totalCents
                      - hash
                  carts:
                    type: array
                    items:
                      type: object
                      description: >-
                        The most recently shown cart. Null when no cart is on
                        the table.
                      properties:
                        merchant:
                          type: string
                          description: Public merchant id, e.g. retail, doordash, goodeggs.
                        merchant_name:
                          type: string
                          description: >-
                            Display name for the merchant, or the store when one
                            is selected (Amazon, Walmart).
                        items:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                              qty:
                                type: integer
                              priceCents:
                                type: integer
                              product_id:
                                type:
                                  - string
                                  - 'null'
                                description: >-
                                  The merchant's id for the line; tells two
                                  same-name lines apart. Null on carts shown
                                  before it was captured.
                            required:
                              - name
                              - qty
                              - product_id
                        serviceFeesCents:
                          type: integer
                          description: >-
                            All fees combined, including the Agentcard service
                            fee.
                        tipCents:
                          type: integer
                        totalCents:
                          type: integer
                          description: >-
                            The all-in amount a confirm authorizes: merchandise,
                            fees, and tip.
                        hash:
                          type: string
                          description: >-
                            Identity of exactly this cart. Echo it back as
                            confirm to place the order.
                      required:
                        - merchant
                        - merchant_name
                        - items
                        - serviceFeesCents
                        - tipCents
                        - totalCents
                        - hash
              example:
                error: >-
                  cart changed since that hash was issued — verify the current
                  carts and confirm their hashes
                conversation_id: cmsq18x2m00a1
                cart:
                  merchant: retail
                  merchant_name: Amazon
                  items:
                    - name: Cafe Mesa de los Santos Colombian Ground Coffee, 16 oz
                      qty: 1
                      priceCents: 2450
                  serviceFeesCents: 61
                  tipCents: 0
                  totalCents: 2511
                  hash: 31d8a6e0c47b92f5
                carts:
                  - merchant: retail
                    merchant_name: Amazon
                    items:
                      - name: Cafe Mesa de los Santos Colombian Ground Coffee, 16 oz
                        qty: 1
                        priceCents: 2450
                    serviceFeesCents: 61
                    tipCents: 0
                    totalCents: 2511
                    hash: 31d8a6e0c47b92f5
        '502':
          description: >-
            The shopping agent could not complete this turn. On a multi-cart
            confirm the body still carries placements for the orders that
            already went through.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  conversation_id:
                    type: string
                  placements:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                  error_code:
                    type:
                      - string
                      - 'null'
        '503':
          description: >-
            Agentcard could not take the per-conversation turn lock (an
            infrastructure fault, not contention). Nothing ran; retry in a few
            seconds. Body: { error, code: "turn_lock_unavailable",
            conversation_id }.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                    enum:
                      - turn_lock_unavailable
                  conversation_id:
                    type: string
      security:
        - userAccessToken: []
components:
  schemas:
    PaymentSource:
      type:
        - object
        - 'null'
      description: >-
        What paid, or what would have paid. brand and last4 are the user's own
        card for added_card, vault and stored_payment_method; null for balance
        and company_balance, where no card of theirs is in the flow. Null when
        no checkout ran or it refused before resolving the source.
      properties:
        source:
          type: string
          enum:
            - balance
            - added_card
            - vault
            - company_balance
            - stored_payment_method
        brand:
          type:
            - string
            - 'null'
        last4:
          type:
            - string
            - 'null'
      required:
        - source
        - brand
        - last4
  securitySchemes:
    platformToken:
      type: http
      scheme: bearer
      description: >-
        A platform access token. Get one on the **Create an access token**
        endpoint by exchanging your `client_id` + `client_secret`, then send it
        as `Authorization: Bearer <token>`. Tokens live one hour.
    userAccessToken:
      type: http
      scheme: bearer
      description: >-
        The user's connection access_token (user authentication), or an
        org-minted buy_token for org-owned accounts.

````