cards

Shop and pay with the holder's saved card

Buys from online merchants (Amazon, Walmart, Target, Best Buy, DoorDash and more) and pays with the card the account holder saved themselves (see GET /get-saved-cards). One conversation per purchase:

  1. Send what to buy as ask, in plain language. Pass delivery_address on this first call when you know it.
  2. Relay reply to the holder and send their answers back as ask with the same conversation_id, until a cart comes back.
  3. Show the holder the cart. Once they agree, send its hash as confirm with the conversation_id. Nothing can be charged before this.
  4. The confirm answers awaiting_approval with an approval_url. Send it to your human; never open it yourself. They approve on their own device with their passkey. Then send the same confirm again to get order_placed.

A turn runs against a live merchant and can take up to two minutes. This call waits about 45 seconds: a turn that finishes in time comes back complete (state: done); a slower one comes back as state: running with a turn_id to poll with GET /get-purchase-turn.

This route is free. The holder's own card pays the merchant, and no identity verification is needed.

post/buy-with-saved-card

Request

  • Base URL: https://laso.finance
  • URL: https://laso.finance/buy-with-saved-card
  • Auth: API key in header Authorization

Headers

Idempotency-Keystring

Optional client-generated unique key (a UUID works) that makes this write safe to retry. A retry with the same key within 24 hours returns the recorded response of the original request, marked with an Idempotency-Replayed: true header, instead of performing the write again. Reusing a key with a different body or route is rejected with 422 (code: idempotency_key_reused); a retry that arrives while the original is still running gets 409 (code: idempotency_key_in_progress), so wait a moment and retry with the same key. Keys are scoped to the authenticated account.

Request body

askstring

What the holder wants, in plain language. Required unless confirming.

conversation_idstring

The conversation to continue. Required with confirm.

confirmstring

A cart's hash from an earlier turn, to place exactly that cart.

Response

The turn, complete or still running.

turn_idstring

This turn's id. Poll GET /get-purchase-turn with it while state is running.

state'running' | 'done' | 'failed'

running means the turn is still talking to the merchant; the fields below appear once it is done.

created_atinteger

Milliseconds since the epoch.

conversation_idstring

Send it back on every follow-up and on the confirm.

status'needs_input' | 'awaiting_approval' | 'in_progress' | 'order_placed' | 'declined' | 'conflict'

What to do next. needs_input: a question or a cart waiting on a confirm. awaiting_approval: send approval_url to the holder, then repeat the same confirm. in_progress: the order is already being placed; read GET /get-purchase-conversation instead of confirming again. order_placed. declined: see decline_code. conflict: nothing ran, see error_code and confirm the fresh cart's hash. Never branch on reply.

replystring

The shopping assistant's turn as prose, ready to show the holder.

order_idstring nullable

Set when this turn placed an order.

decline_codestring nullable

The machine reason behind declined, e.g. items_unavailable.

approval_urlstring nullable

Send to the holder when status is awaiting_approval. Never open it yourself.

charge_status'none' | 'confirming' | 'settled' | 'unknown' | 'null' nullable

Whether money moved: none, confirming, settled, or unknown (do not retry; read the conversation).

card_last4string nullable

The saved card that paid, for naming it to the holder.

error_codestring nullable

On conflict: cart_changed, turn_in_progress, delivery_address_changed, or delivery_address_bound_after_cart.

errorstring

Present when state is failed.

notestring

The next step.

Changes

No recorded changes to this operation across all 3 revisions of this API.