Seller agent transactions
A seller agent transaction is the structured flow a buyer runs with a seller's agent to buy a dataset that does not yet exist as a purchasable listing. Rather than browsing a catalog, you describe the data you need, the seller's agent builds it, agrees a price, and you pay — and the deliverable arrives on the authorisation you approved, not a re-negotiation.
This page is the buyer's read surface over your own seller agent transactions: where the transaction stands, the current offer (and any counter-offers), and your payment obligation and its attempts. All of it is server-rendered from transaction state — nothing on this surface is agent-authored copy.
These endpoints are enabled in production. They 404 by absence only if the recovery kill-switch (
SELLER_TXN_ENABLED) is off; rollback is.github/workflows/flag-rollout.yml.
Start a transaction
Choose a seller from the public seller directory, then open the transaction with your Cognito ID token:
POST /api/v1/sellers/{seller_id}/transactions
Content-Type: application/json
{"idempotency_key":"client-request-01"}
The body has exactly that one field. The key is 1–200 ASCII characters from
letters, digits, ., _, :, and -. Your buyer account comes only from the
authenticated principal and the seller comes only from the public path; neither
identity is accepted in the body, query, or headers. Repeating the same key for
the same seller returns the original transaction without another row or event.
Reusing it for a different seller returns opaque 409 idempotency_conflict.
An unavailable seller or your own account returns opaque 404 not_found; an
open-transaction cap refusal is 429 transaction_cap_reached.
Reading your offer and payment state
GET /api/v1/transactions/{id}/payment
Authenticated with your Cognito ID token (the same way you call any
/api/v1/* endpoint). The {id} is your transaction's id, from the thread
URL returned by the open call.
The response is your own offer/payment read:
| Field | Meaning |
|---|---|
state |
The transaction state: converging, drafting, seller_review, offered, awaiting_payment, closed (and closed_revivable). |
state_label |
A human label for the state, rendered server-side (e.g. Awaiting payment). |
whose_move |
Whose turn it is: requester (you), owner (the seller), platform (system working), or none (terminal). |
deadline |
The single live clock of the current state (its kind and expiry), or absent when no clock is running. |
offer |
Your current offer with its price, expiry, the frozen gap options, and the offer_content_sha256 pin. Absent before an offer exists. |
counters |
Your counter-offer history, with each counter's amount and your original message (fenced verbatim — it is your own untrusted input, never re-written). |
obligation |
Your accepted 7-day payment obligation: price, state, accepted/expiry timestamps, settlement details once paid. |
attempts |
The settlement attempts against your obligation (rail, amount, outcome, timestamps). |
A transaction that is not yours — or an id that does not exist — returns the
same opaque 404/not_found. You cannot probe whether another buyer has
an open transaction; the existence of another party's negotiation is private.
Acting on the offer
The read surface supports the actions you take on your own offer:
| Action | Endpoint |
|---|---|
| Accept an offer (creates your payment obligation) | POST /api/v1/transactions/{id}/offers/{offer_id}/accept |
| Decline an offer | POST /api/v1/transactions/{id}/offers/{offer_id}/decline |
| Abandon an accepted obligation instead of letting the window lapse | POST /api/v1/transactions/{id}/payment/abandon |
Posting on the thread is separate — see the transaction thread surface you were given access to when the transaction began.
Seller deliverable updates
If the seller replaces an unapproved draft during review, the buyer thread
contains one prominent system callout with template id
status.deliverable_updated_pending_review. It confirms that the earlier draft
was never approved or offered and that the updated deliverable is awaiting
seller approval. This notice exposes no file, digest, scan, gate, or coverage
details; those remain behind the seller approval and offer flow.
Privacy and honesty
- No counterparty internals. You see the seller (a public catalog identity) and the offer the seller's agent made — never the seller's agent's internal reasoning, the bundle it reviewed, or any nudge history.
- Everything server-rendered.
state_label,whose_move, and the deadline are computed by the platform from one vocabulary, so the buyer portal, seller portal, and email never disagree about what a state is called. - Timers come from stored timestamps. The deadline you see is the authoritative stored clock — the sweeper uses the same timestamps to move the transaction, so a polled deadline always matches the platform's actual behaviour.