Skip to main content

Overview

This is the state reference behind both card products. How to order each one lives on its own page: USA prepaid card and international prepaid card. What follows is what the states mean and what /get-card-data returns at each one. Non-reloadable cards go through a simple lifecycle: order, wait for details, spend, and deplete. Once the balance is used up the card is done, but you can make multiple purchases until it hits zero.

Lifecycle stages

1. Order

Call GET /get-card?amount=50 with an x402 payment. The amount you pay in USDC is the amount loaded onto the card (between $5 and $1,000). The response returns immediately with:
  • card.card_id — Unique identifier for this card
  • card.status — Always "pending" at this point
  • auth.id_token — Bearer token for polling

2. Pending

The card has been ordered but the details aren’t ready yet. This stage lasts ~7-10 seconds while the card is being issued by the card network. During this time, poll GET /get-card-data?card_id=X with your Bearer token every 2-3 seconds (the examples write it as $LASO_ID_TOKEN, exported from your saved credentials).
International cards insert a queued state here instead of pending. The order waits for manual admin fulfillment, typically up to 24 hours, and can be cancelled while it is queued. See the international prepaid card page.

3. Ready

Once status changes to "ready", the response includes full card details:

4. Spending

Use the card number, expiry, and CVV to make purchases. The card works at any US-based merchant — online, in-store, or via mobile wallets. When a merchant asks for a billing address or ZIP code, use the billing_address from card_details. The billing name is always Laso Finance. For USA cards no specific address is enforced, so any valid U.S. billing address works and the returned address is a known-good default (ZIP 91723). International non-reloadable cards are different: their billing_address has required: true and the merchant AVS check is validated against exactly that address, so use it as-is. You can make multiple purchases until the balance is depleted. Each purchase reduces the available_balance.

5. Depleted

When the balance reaches zero, the card can no longer be used. Order a new card with another /get-card call.

6. Expired

Cards expire 6 months after issuance. After the expiration date the card stops working even if it still has a balance, and any remaining funds are forfeited. Forfeited funds are retained by the card issuer and cannot be recovered or returned by Laso Finance. Spend the full balance before the expiration date.
Expiration is independent of the balance. A card with money still on it becomes unusable once it expires, and that remaining balance is lost permanently. Always spend a card down to zero well before its 6-month expiration.

Reloadable cards

Reloadable cards are a different product from the two above, and they have no order step in this API. The account holder sets one up in the Laso dashboard, links their card issuer account, and funds it. An agent’s job is to find the card and spend it. This is the one card product that requires identity verification. The dashboard flow at https://laso.finance/agent/dashboard/verified/card is reachable only once the holder has completed Laso’s identity verification, and the issuer then gates card creation on that verification being shared with it. GET /get-kyc-status reports whether the holder has completed it, and GET /get-kyc-link returns the link to hand them. The two non-reloadable cards read no verification status at order time.
The key difference from non-reloadable cards: one card serves many purchases. A multi_use card (reusable: true) stays open across charges until its spend limit is consumed, and the holder can top it up rather than issuing a new card each time. If a holder has a reloadable card, prefer it over ordering a fresh single-load card per checkout.

Listing them

Each card returns card_id, last4, expiry, balance, spend_limit, reusable, and status (open, paused, or closed). Spend against a card whose status is open and whose balance covers the purchase. If the wallet has no card issuer account linked, the list comes back empty with a note. That is not an error — it means the account holder has not set up a reloadable card. Hand them the dashboard link rather than retrying.

Creating one

Once the holder has linked their card issuer account, you create cards yourself against a funded balance (see Topping up below to fund it):
This is free, with no x402 payment: the card draws on the holder’s own balance rather than anything Laso fronts. Cards are reusable by default; pass "reusable": false for one that closes after its first approved charge. A 402 means the balance is short: fund it as below, then retry. A 400 means no card issuer account is linked yet, which the holder fixes in the dashboard.

Getting the card number requires the holder’s approval

This is the one place a reloadable card differs sharply from the non-reloadable flow. Card numbers are not returned on demand:
If the response contains details_approval with status: "pending", the card issuer has emailed the account holder an approve/deny link. There is no way to bypass this, and retrying without an approval only mints another request. Tell your human that an approval is waiting in their email, then retry with the approval_id once they have approved:
card_details (card number, CVV, expiry) is populated in that second response.

Spending it

Pay the merchant exactly as you would with any card: enter the number, expiry, and CVV at checkout, and enter the returned billing_address exactly as given. That address comes from the account holder’s identity verification and is AVS-checked at checkout — a mismatch as small as St versus Street is the most common decline on a card that has enough money on it. A reloadable card with reusable: true stays open after an approved charge, so the same card can be spent again up to its remaining balance. Re-read balance before each purchase instead of assuming it still covers the total: there are no partial approvals, so a charge larger than the balance is declined in full rather than partly filled. If a charge is declined, check in order: status is still open; balance covers the full amount including tax and shipping; and the billing address was entered exactly as returned. If all three hold, the decline is merchant-side, some merchants reject prepaid or debit cards, and some non-U.S. merchants decline U.S.-issued cards.

Topping up

You can top the balance up yourself. The simplest way is GET /fund-card-balance?amount=X, a paid route that loads the balance directly: pay from Base or Solana and Laso bridges the payment to the holder’s deposit address at the card issuer, so a managed agent wallet holding USDC on Solana can fund a card without any chain juggling. The price is exactly the amount loaded. To move the USDC yourself instead, GET /get-card-deposit-address returns the holder’s own deposit address at the card issuer, and USDC on Base sent there credits their balance. The holder can also pay in with Apple or Google Pay in the dashboard, which settles against their own payment method. Either way, top up rather than ordering a replacement non-reloadable card. Base only, if you send it yourself. The deposit address takes USDC on Base, and USDC sent on another chain is unrecoverable. A Laso managed agent wallet holds USDC on Solana, so do not transfer straight from one to that address. Use GET /fund-card-balance instead, which bridges for you. Deposits usually confirm within a couple of minutes; poll GET /get-card-deposit-address until balance reflects the deposit, then create the card.

Reading the history

GET /list-card-transactions returns transactions on the holder’s reloadable cards, newest first:
Omit card_id for every reloadable card on the account, and narrow with limit and status. Each row carries merchant, amount in US dollars, status, and created_at in milliseconds. This covers reloadable cards only — non-reloadable history stays in /get-card-data. The same response carries card_events, which is the rest of the story. The card issuer reports spends and nothing else, so a list of purchases alone shows money leaving a balance that grows for no visible reason. Each event has an event_type of deposit, limitChange, or cardCreated, plus amount and balance for a deposit and previous_spend_limit/new_spend_limit for a limit change. Merge the two lists by created_at and you have the account holder’s own view of the card. A third list, top_ups, follows each GET /fund-card-balance payment across its legs (paid, bridging, delivered, credited, or failed) with the transaction hash behind each one, which is the same tracker the holder sees in the dashboard after adding money.