> ## Documentation Index
> Fetch the complete documentation index at: https://agents.laso.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Get card details

> Returns the current status and details of card orders. If `card_id` is provided, returns a single card, looked up across U.S. non-reloadable, international non-reloadable, and reloadable cards. If omitted, returns all cards of the given `card_type` for the authenticated user; `card_type` defaults to `Non-Reloadable U.S.` when omitted, so existing callers see unchanged behavior. Pass `card_type=Non-Reloadable International` to list international cards, or `card_type=Reloadable` to list reloadable cards.

For U.S. non-reloadable cards, details take ~7-10 seconds to become available after ordering; poll every 2-3 seconds until `status` is `"ready"`, then read `card_details`. For international non-reloadable cards, the order is `queued` until an admin fulfills it (typically within 24 hours), after which `card_details` is populated.

For international cards, the `card_id` returned by `/order-intl-card` is a queue id. After admin fulfillment, the issuer's transaction id becomes the new `card_id` and the original queue id is preserved on the card as `queued_order_card_id`. You can keep polling `/get-card-data?card_id=<original-queue-id>` and it will resolve to the fulfilled card.

**Reloadable cards** are a separate product, set up by the account holder in the Laso dashboard rather than ordered through this API. They are reusable (a `multi_use` card stays open across charges until its limit is spent) and can be topped up, unlike the single-load non-reloadable cards. Listing them returns `balance`, `spend_limit`, `last4`, `expiry`, and `reusable`. If the wallet has no card issuer account linked, the list is empty and a `note` explains how the holder sets one up.

Reading a reloadable card's **number and CVV** is gated by the card issuer, and which gate applies depends on who issued it. Request the card by `card_id`; the response carries exactly one of three fields. `card_details` is the normal result for a card created through `/create-reloadable-card`, which Laso issues on the holder's behalf and can read for them directly — no approval step is involved. `details_approval` with `status: "pending"` and an `approval_id` appears only for a card the holder created in a DIFFERENT app: the issuer has emailed them an approve/deny link, and once they approve you retry as `GET /get-card-data?card_id=<CARD_ID>&approval_id=<APPROVAL_ID>` to receive `card_details`. `details_error` means the issuer could not return the number; retry shortly, and if it persists the holder can read the card in the dashboard. Spend the card by entering its number, expiry, and CVV at the merchant's checkout. `billing_address` is null on these cards and always will be — the issuer holds no billing address for a card. If a merchant requires one, use the address the account holder gave at identity verification (ask them; do not guess), since these cards are AVS-checked against it and a mismatch is the most common decline on a card that has funds. A card with `reusable: true` stays open after an approved charge and can be spent again up to its remaining `balance`; a charge larger than the balance is declined in full, as there are no partial approvals.

Requires a Bearer token from `/auth` or `/get-card`.



## OpenAPI

````yaml /api-reference/openapi.json get /get-card-data
openapi: 3.1.0
info:
  title: Laso Finance x402 API
  version: 1.0.0
  x-docs-revision: 2c5778b5ce19
  x-docs-manifest: https://laso.finance/.well-known/docs-version.json
  contact:
    email: agents+support@laso.finance
  x-guidance: >-
    Laso Finance is a payment-gated (x402) API that lets an AI agent spend USDC
    on real-world financial products: prepaid cards (U.S. and international),
    gift cards, push-to-card transfers to USD/EUR/GBP debit cards, and
    Venmo/PayPal payouts.


    Payment: every paid route is an x402 v2 endpoint. Call it with no payment
    header to receive a 402 challenge listing the accepted networks, then replay
    with a signed USDC payment. Both Base (eip155:8453) and Solana
    (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) are accepted on every paid route;
    the caller picks either chain.


    Identity: `GET /auth` is free and identity-only. Prove wallet ownership with
    a `SIGN-IN-WITH-X` (CAIP-122) header to receive a Firebase id_token, then
    send that token as a Bearer credential to the authenticated read routes
    (`get-card-data`, `get-account-balance`, `get-kyc-status`, etc.). Paid
    routes also return fresh auth credentials in their response, so a payment is
    never required just to obtain a token.


    Recommended flow: (1) `GET /auth` to establish identity, (2) call a paid
    route (e.g. `GET /get-card`) to purchase a product, paying USDC on Base or
    Solana, (3) poll the authenticated read routes with the returned Bearer
    token to fetch the resulting card/transfer details. Full machine-readable
    instructions live at https://laso.finance/SKILL.md.
  description: >-
    Payment-gated API for Laso Finance. All paywalled routes use the x402
    protocol — the caller includes a USDC payment header on Base (eip155:8453)
    or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) and the server verifies
    payment before processing. Free routes require no payment header. The same
    402 also carries an MPP (Machine Payments Protocol) challenge in
    WWW-Authenticate; an MPP client pays with USDC on Base by replaying with
    `Authorization: Payment ...`, and routes, prices, and responses are
    identical.


    ## Getting started


    To set up a wallet for making x402 payments, choose a provider:


    - **Locus** (default): https://paywithlocus.com/SKILL.md

    - **Sponge**: https://wallet.paysponge.com/skill.md — automatic x402 service
    discovery

    - **Ampersend**: https://www.ampersend.ai/getting-started.md — self-custody
    on Base or Solana with dual-approval spending limits. Laso Finance is a
    default skill, so no manual endpoint registration is needed.


    ## How x402 works


    1. Call a paywalled endpoint without a payment header → receive a `402
    Payment Required` response containing payment details (price, recipient
    address, network).

    2. Construct an x402 payment header using the details from the 402 response.

    3. Replay the request with the payment header → the server verifies payment
    and processes the request.


    ## Authentication flow


    `GET /auth` is free: callers prove wallet ownership by sending a
    `SIGN-IN-WITH-X` header (CAIP-122 wallet signature). Paywalled routes
    (`/get-card`, `/order-gift-card`, `/get-push-to-card`, `/order-intl-card`)
    also return fresh auth credentials in their responses, so a payment is never
    required just to obtain a token.


    Most routes return auth credentials (`id_token`, `refresh_token`,
    `expires_in`). Use the `id_token` as a Bearer token to call authenticated
    Laso Finance endpoints like `/get-card-data`. When the `id_token` expires,
    use `POST /auth` with `grant_type: refresh_token` to get a new one.


    ## Important notes


    The `/get-card` USA prepaid card endpoint is U.S. only — issued in USD,
    usable at U.S.-based merchants only, and physical goods must ship to a U.S.
    address. For non-U.S. merchants or non-USD currencies, use `GET
    /order-intl-card` instead (international prepaid card, admin-fulfilled
    within 24 hours). All cards are intended for the caller's own use.


    ## Rate limits


    Every response carries the request budget so you can pace yourself without
    probing for a limit:


    | Header | Meaning |

    | --- | --- |

    | `RateLimit-Limit` | Requests permitted per window |

    | `RateLimit-Remaining` | Requests still available |

    | `RateLimit-Reset` | Seconds until the window rolls over |

    | `RateLimit-Policy` | The policy these numbers describe, as
    `limit;w=seconds` |


    The same values are repeated as `X-RateLimit-*` for clients that only parse
    that spelling.


    Most routes advertise the service-wide ceiling. `POST /signup` enforces its
    own per-IP budget on top of it and overwrites these headers with its own
    numbers. `POST /refresh-card-data` is limited per card rather than per
    caller, so its headers keep the service-wide values and the per-card budget
    is reported only on rejection.


    Every rejection is a `429` carrying `Retry-After` in seconds and a matching
    `retry_after_seconds` field in the body, computed from the limit that
    actually rejected the request. Wait that long and retry once. Do not retry
    in a tight loop.


    For step-by-step instructions, read https://laso.finance/SKILL.md
servers:
  - url: https://laso.finance
    description: Production
security: []
paths:
  /get-card-data:
    get:
      summary: Get card details
      description: >-
        Returns the current status and details of card orders. If `card_id` is
        provided, returns a single card, looked up across U.S. non-reloadable,
        international non-reloadable, and reloadable cards. If omitted, returns
        all cards of the given `card_type` for the authenticated user;
        `card_type` defaults to `Non-Reloadable U.S.` when omitted, so existing
        callers see unchanged behavior. Pass `card_type=Non-Reloadable
        International` to list international cards, or `card_type=Reloadable` to
        list reloadable cards.


        For U.S. non-reloadable cards, details take ~7-10 seconds to become
        available after ordering; poll every 2-3 seconds until `status` is
        `"ready"`, then read `card_details`. For international non-reloadable
        cards, the order is `queued` until an admin fulfills it (typically
        within 24 hours), after which `card_details` is populated.


        For international cards, the `card_id` returned by `/order-intl-card` is
        a queue id. After admin fulfillment, the issuer's transaction id becomes
        the new `card_id` and the original queue id is preserved on the card as
        `queued_order_card_id`. You can keep polling
        `/get-card-data?card_id=<original-queue-id>` and it will resolve to the
        fulfilled card.


        **Reloadable cards** are a separate product, set up by the account
        holder in the Laso dashboard rather than ordered through this API. They
        are reusable (a `multi_use` card stays open across charges until its
        limit is spent) and can be topped up, unlike the single-load
        non-reloadable cards. Listing them returns `balance`, `spend_limit`,
        `last4`, `expiry`, and `reusable`. If the wallet has no card issuer
        account linked, the list is empty and a `note` explains how the holder
        sets one up.


        Reading a reloadable card's **number and CVV** is gated by the card
        issuer, and which gate applies depends on who issued it. Request the
        card by `card_id`; the response carries exactly one of three fields.
        `card_details` is the normal result for a card created through
        `/create-reloadable-card`, which Laso issues on the holder's behalf and
        can read for them directly — no approval step is involved.
        `details_approval` with `status: "pending"` and an `approval_id` appears
        only for a card the holder created in a DIFFERENT app: the issuer has
        emailed them an approve/deny link, and once they approve you retry as
        `GET /get-card-data?card_id=<CARD_ID>&approval_id=<APPROVAL_ID>` to
        receive `card_details`. `details_error` means the issuer could not
        return the number; retry shortly, and if it persists the holder can read
        the card in the dashboard. Spend the card by entering its number,
        expiry, and CVV at the merchant's checkout. `billing_address` is null on
        these cards and always will be — the issuer holds no billing address for
        a card. If a merchant requires one, use the address the account holder
        gave at identity verification (ask them; do not guess), since these
        cards are AVS-checked against it and a mismatch is the most common
        decline on a card that has funds. A card with `reusable: true` stays
        open after an approved charge and can be spent again up to its remaining
        `balance`; a charge larger than the balance is declined in full, as
        there are no partial approvals.


        Requires a Bearer token from `/auth` or `/get-card`.
      operationId: getCardData
      parameters:
        - name: card_id
          in: query
          required: false
          description: >-
            The card ID returned from `/get-card` or `/order-intl-card`, or a
            reloadable card's id from `card_type=Reloadable`. Looked up across
            all three card types. If omitted, returns all cards of `card_type`.
          schema:
            type: string
        - name: card_type
          in: query
          required: false
          description: >-
            When listing all cards (no `card_id`), filters by card type.
            Defaults to `Non-Reloadable U.S.` if omitted (preserves existing
            client behavior). Pass `Non-Reloadable International` to list
            international cards, or `Reloadable` to list reloadable cards.
          schema:
            type: string
            enum:
              - Non-Reloadable U.S.
              - Non-Reloadable International
              - Reloadable
            default: Non-Reloadable U.S.
        - name: approval_id
          in: query
          required: false
          description: >-
            Reloadable cards only, and only for a card the account holder
            created in a DIFFERENT app: pass the approval_id from a prior
            details_approval response once they have approved it. Cards created
            through /create-reloadable-card are Laso-issued and never require
            this.
          schema:
            type: string
      responses:
        '200':
          description: >-
            Card status and details. Returns a single `CardData` object when
            `card_id` is provided, or `{ "cards": CardData[] }` when omitted.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/CardData'
                  - type: object
                    properties:
                      cards:
                        type: array
                        items:
                          $ref: '#/components/schemas/CardData'
        '400':
          description: >-
            Invalid card_type. Must be "Non-Reloadable" or "Non-Reloadable
            International" when provided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: >-
                  card_type must be "Non-Reloadable" or "Non-Reloadable
                  International" when provided. Received: foo
        '401':
          description: Missing or invalid Bearer token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Missing or invalid Authorization header
        '403':
          description: >-
            Not authorized to view this card, or the account is frozen (frozen
            responses include a `frozen_message` field).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Not authorized to view this card
        '404':
          description: Card not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Card not found
      security:
        - BearerAuth: []
components:
  schemas:
    CardData:
      type: object
      description: >-
        Response from `/get-card-data`. Three card types share this shape and
        each populates a different subset.


        **Non-reloadable (U.S. and International):** when `status` is `ready`,
        `card_details` carries the number, CVV, and expiry. International cards
        add `label`, `charged_usd_amount`, `fees_paid`, `state`,
        `balance_update_requested_timestamp`, and `queued_order_card_id`.


        **Reloadable:** returns `last4`, `expiry`, `balance`, `spend_limit`,
        `reusable`, `issuer_status`, `created_at`, and `expires_at` instead of
        the `usd_amount`/`timestamp` fields above. Reading its number and CVV is
        gated by the card issuer, so exactly one of `card_details`,
        `details_approval`, or `details_error` is present on a single-card
        lookup.
      properties:
        card_id:
          type: string
        card_type:
          type: string
          enum:
            - Non-Reloadable U.S.
            - Non-Reloadable International
            - Reloadable
        usd_amount:
          type: number
        country:
          type: string
          description: U.S. cards only.
          example: US
        label:
          type: string
          description: International cards only. User-supplied label, may be empty.
          nullable: true
        charged_usd_amount:
          type: number
          description: >-
            International cards only. Amount the user was charged including
            fees.
        fees_paid:
          type: number
          description: International cards only. Fees paid for this card.
        state:
          type: string
          description: International cards only. Raw card state.
          enum:
            - queued
            - redeemable
            - complete
            - refund-requested
            - refund-requested-approved-for-queue
            - archived
            - refunded
        balance_update_requested_timestamp:
          type: number
          nullable: true
          description: >-
            International cards only. Unix timestamp (ms) of an outstanding
            admin balance update request, or null if none is pending.
        queued_order_card_id:
          type: string
          nullable: true
          description: >-
            International cards only. The original `card_id` returned by
            `/order-intl-card`. After admin fulfillment the card is reissued
            with a new `card_id` (the issuer's transaction id); querying
            `/get-card-data?card_id=<original>` continues to resolve to the
            fulfilled card via this field.
        timestamp:
          type: number
        timestamp_readable:
          type: string
        last_updated_timestamp:
          type: number
          description: >-
            U.S. cards only. Unix timestamp (ms) of the last time card data was
            refreshed.
        status:
          type: string
          enum:
            - pending
            - ready
            - queued
            - complete
            - refund-requested
            - refunded
            - archived
        card_details:
          type: object
          description: >-
            Only present when status is `ready` (U.S.) or `complete`
            (international).
          properties:
            card_number:
              type: string
            exp_month:
              type: string
            exp_year:
              type: string
            cvv:
              type: string
            available_balance:
              type: number
            billing_address:
              type: object
              description: >-
                The card billing address to enter when a merchant asks for one
                at checkout. The billing name is always `Laso Finance`. For USA
                non-reloadable cards `required` is `false` (any valid U.S.
                billing address works; this is a known-good default). For
                international non-reloadable cards `required` is `true` and the
                merchant AVS check is validated against exactly this address. On
                reloadable cards this is always null: the card issuer holds no
                billing address for a card, and they are AVS-checked against the
                address the account holder gave at their own identity
                verification. Ask the holder for it; do not substitute Laso's
                address.
              properties:
                name:
                  type: string
                  description: Always `Laso Finance`.
                line_1:
                  type: string
                line_2:
                  type: string
                city:
                  type: string
                state:
                  type: string
                zip:
                  type: string
                country:
                  type: string
                required:
                  type: boolean
                  description: >-
                    `true` if the card enforces AVS against this exact address
                    (international cards); `false` if any valid U.S. address
                    works (USA cards).
                note:
                  type: string
              nullable: true
        transactions:
          type: array
          description: >-
            Card transaction history. U.S. and international cards use slightly
            different shapes — see `CardTransaction` and `IntlCardTransaction`.
          items:
            oneOf:
              - $ref: '#/components/schemas/CardTransaction'
              - $ref: '#/components/schemas/IntlCardTransaction'
        last4:
          type: string
          description: Reloadable cards only. Last four digits.
          example: '8260'
        expiry:
          type: string
          description: Reloadable cards only. MM/YY.
          example: 07/31
        balance:
          type: number
          description: Reloadable cards only. Spendable balance in dollars.
          example: 208
        spend_limit:
          type: number
          description: Reloadable cards only. Spend cap in dollars.
          example: 208
        reusable:
          type: boolean
          description: Reloadable cards only. True for a multi-use card.
        issuer_status:
          type: string
          description: >-
            Reloadable cards only. The issuer's own status string, kept
            verbatim.
          example: OPEN
        created_at:
          type: number
          description: Reloadable cards only. Epoch milliseconds.
        expires_at:
          type: number
          nullable: true
          description: >-
            Reloadable cards only. Epoch milliseconds, or null when the card
            does not expire.
        details_approval:
          type: object
          nullable: true
          description: >-
            Reloadable cards only, and only for a card the holder created in
            ANOTHER app. The issuer has emailed them an approve/deny link; retry
            with `approval_id` once they approve. Cards created through
            `/create-reloadable-card` are Laso-issued and never take this path.
          properties:
            status:
              type: string
              enum:
                - pending
            approval_id:
              type: string
              nullable: true
            note:
              type: string
        details_error:
          type: string
          nullable: true
          description: >-
            Reloadable cards only. Present when the issuer could not return the
            number, so a card with no `card_details` is never silently
            indistinguishable from one whose details are pending.
    Error:
      type: object
      properties:
        error:
          type: string
    CardTransaction:
      type: object
      description: U.S. prepaid card transaction.
      properties:
        amount:
          type: number
        date:
          type: string
        description:
          type: string
        is_credit:
          type: boolean
    IntlCardTransaction:
      type: object
      description: International prepaid card transaction.
      properties:
        amount:
          type: number
          description: Transaction amount in USD.
        date:
          type: number
          nullable: true
          description: Unix timestamp (ms) of the transaction.
        merchant:
          type: string
        status:
          type: string
          nullable: true
          description: Optional status, e.g. `pending`.
  securitySchemes:
    BearerAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Firebase ID token from `/auth` or any paid route, sent as a Bearer
        token: `Authorization: Bearer <id_token>` (the `Bearer ` prefix is
        required).

````