Seller Endpoints
All seller endpoints require authentication via one of:
si_seller_API key:Authorization: Bearer si_seller_xxx(programmatic access)- Privy session cookie (web UI)
A si_seller_ key cannot access buyer endpoints, and vice versa. Session cookies work for both.
Everything you can do in the seller dashboard, you can do here over the API. The dashboard is a pure client of this API, so managing keys, offers, pricing, health, earnings, and payouts are all HTTP calls you can script with no browser. Seller keys support create, list, and revoke; offers have a full lifecycle (create, read, update, deactivate, bulk create, bulk cancel, reset health, rotate credential).
Authentication — SIWE (Sign-In With Ethereum)
Get a seller API key using wallet signature auth. No browser needed.
Get Challenge
Returns a SIWE message with nonce and 5-minute expiry. The message must be signed and returned within 5 minutes. The server validates domain, uri, chainId, issuedAt (must be within ±5min of server time), and expirationTime (max 10min from issuedAt).
Issue Key
Exchange the signed SIWE message for a seller API key. Save the returned key — it will not be shown again.
The secret is the key field, shown once. expires_at is present only if you set one on the request.
Manage Keys
Once you hold one seller key (or a web session), you can mint and manage more programmatically, no browser required. Seller keys support create, list, and revoke. (Rename and per-key routing preferences are buyer-only, since a seller key carries no routing config.)
Create another si_seller_… key (up to 25 active per wallet). Requires an Idempotency-Key header. The secret is in the key field of the response, shown once.
List keys, redacted (id, key_prefix, label, timestamps, revoked_at). An existing seller key or web session authorizes this.
Revoke a key. Irreversible; returns 204.
Offers
Create offer.
Update price/caps.
Deactivate / soft-delete (encrypted key is retained; revoke at provider for immediate key invalidation).
List my offers (filter with ?model=, ?status=active|paused|inactive; paginate with max_items / next_token).
Read one offer (status, health, price, caps).
To deactivate every active offer at once, use POST /v1/seller/offers/bulk-cancel (see Offer operations); otherwise remove them one at a time.
One offer per credential, base URL and model
The same API key can back as many different models as you like — that is the normal case and nothing about it changes. What is refused is a second active offer for the same model on the same key and base URL, whoever owns it: the rule is global across workspaces and organizations.
A conflict returns 409 duplicate_offer_for_credential. When the existing offer is your own, the response
carries its offer_id in error.detail so you can update or delete it instead of creating a duplicate; when it
belongs to someone else, no identifier is returned.
The same rule applies to anything that brings an offer back into the active set — reactivating a paused offer, or rotating a credential onto a key that already serves that model. Deleting or deactivating an offer frees its slot, so the key can be relisted for that model straight away; if a slot ever appears stuck, the next listing attempt reclaims it automatically.
When the conflicting offer is your own, its id is returned as error.detail.existing_offer_id.
In bulk creation, a conflicting row comes back as status: "error" with duplicate_offer_for_credential in the
message; retrying will not change the outcome.
Offers Surplus has delisted
Surplus deactivates an offer itself when its provider endpoint cannot serve the model it is listed for — for example a video model listed against a host that exposes no video API at all. Such an offer can never complete a job: every request routed to it fails after the buyer has been quoted.
A delisted offer stays visible and editable, but setting status: "active" on it returns
400 offer_delisted_by_operator and it is not restored by rotating its credential. It is not a pause you can
undo. List the model against a provider that serves it, or contact support if you believe the endpoint does work.
Bulk Create
Create multiple offers from discovery results.
Up to 200 offers per request. Bulk-created offers support the same cap_daily_usd field as single-offer creation.
Offer operations
Deactivate ALL of your active offers in one call. Fire-and-forget: returns 202 with an operation_id; poll it for progress.
Clear an offer's failure backoff and return it to rotation immediately.
Swap an offer's upstream provider key in place, without recreating it.
Poll an async operation (such as a bulk cancel) for status, processed, total, and failed_count.
Model Discovery
Auto-detect models + pricing from a provider. Requires seller auth; streams NDJSON, one line per model.
Parses Venice, OpenRouter, Bankr, and generic pricing formats automatically.
Test Connection
Verify endpoint is reachable and returns valid responses.
Earnings
Precomputed earnings for a range: total_earned_usdc, pending_usdc, in_flight_usdc, paid_usdc (integer micro-USD strings), plus daily, by_model, share, a recent_sales teaser (up to 20), and any payout_hold.
Query param: range = 7d (default), 30d, 90d, or lifetime. Team orgs can add ?workspace_id=.
Earnings History
Cursor-paginated sale history, deeper than the 20-row earnings teaser. Params: limit (default 25), cursor, workspace_id. Returns recent_sales[] + next_token.
Usage Export
Your full sales record as CSV. Redirects (302) to a short-lived presigned download. Params: from, to, limit, format=csv, workspace_id.
Health Log
Returns recent health events for your offers (failures, backoffs, recoveries).
Query params: offer_id (filter to one offer), since / until (ms epoch), max_items, next_token, sort_order (ASC | DESC).
Payouts
Your payout position: available_usdc, in_flight_usdc, paid_usdc, the threshold_usdc, per-recipient groups, and executed-payout history with Base transaction hashes.
Request a withdrawal of your available balance. In batched mode the scheduled drain settles the pending balance (status: scheduled); self_submit: true instead requests a signed EIP-3009 authorization for you to broadcast yourself (paying your own gas). A withheld balance returns status: held with a reason.
Report the on-chain tx_hash for a payout you broadcast yourself.
Saved Provider Configs
Reusable saved provider-key cards (base URL + key fingerprint + hint; the key itself is never returned). Cards are created as a side effect of creating an offer, so there is no create endpoint here: management is list + delete. List them, or DELETE /v1/seller/configs/{id} to remove one. Bulk offer creation, discovery, and health probes can reuse a saved key via reuse_key_fingerprint instead of re-sending api_key.
Rate Limits
All seller endpoints are rate-limited per API key and per wallet:
429 responses include Retry-After (seconds) and X-RateLimit-Reset (Unix timestamp) headers.
These route limits are API-abuse controls. They are not a marketplace-side spend ceiling for provider usage. For provider-quota protection, use cap_daily_usd and provider-side API-key limits where available. There is no per-week or per-month USD cap on marketplace seller offers today.
Key Storage and Deletion
Seller provider API keys are encrypted at rest with AES-256-GCM under AWS KMS envelope encryption: a per-secret data key is requested from KMS, used to encrypt the plaintext, and the ciphertext plus the KMS-encrypted data key are stored in a private S3 bucket. The server decrypts keys only when it needs to call the seller's provider endpoint or run seller-owned management actions such as discovery/test-connection/health reset.
Deleting an offer is currently a soft delete: active = false on the offer record, removed from routing, encrypted API key retained in storage. There is no self-serve hard-delete endpoint yet. Sellers should revoke deleted offer keys at their upstream provider if immediate invalidation is required.
See Security & Privacy for the full current trust model.
Error Responses
All errors follow the format: