Sell API and MCP
Everything Sell does in the console, from code or an agent: /api/v1/sell on the Management API, and the same operations as MCP tools.
Who calls it
The base is https://app.opencheap.si/api/v1, with an agent key (kl_rs_…) or a wallet session (kla_…), as for the rest of the Management API. The account's owner accepts the selling terms once: in the console with the first key, or with become_seller from the owner's own wallet. Until then every sell call answers 403 not_seller.
A key is never echoed back: answers carry its prefix and last four. Nothing names a buyer, another seller, or a request id. The full contract is the Sell tag of /api/v1/openapi.json.
List an offer
Save the server (or key), discover its models, draft offers, test them, then publish with the statement. The statement is your user's to accept: show it to them first. Today it is version own-server-v2 for your own server and vendor-key-v2 for a provider key; GET /sell/presets always has the current text and version.
export OPENCHEAP=https://app.opencheap.si/api/v1
export AUTH="Authorization: Bearer kl_rs_…"
export JSON="Content-Type: application/json"
# 1. save your server: its base URL and key, sealed at once (the answer has its id and hint only)
curl -s $OPENCHEAP/sell/credentials -H "$AUTH" -H "$JSON" -H "Idempotency-Key: own-1" \
-d '{ "preset": "custom", "baseUrl": "https://llm.example.com/v1", "key": "…" }'
# 2. discover its models: poll the job until done
curl -s -X POST $OPENCHEAP/sell/credentials/CRED_ID/discover -H "$AUTH" -H "$JSON" -d '{}'
curl -s $OPENCHEAP/sell/jobs/JOB_ID -H "$AUTH"
# 3. draft offers, priced to match the market with a floor of 60 %
curl -s $OPENCHEAP/sell/offers -H "$AUTH" -H "$JSON" \
-d '{ "credentialId": "CRED_ID", "models": ["Qwen/Qwen3-32B"], "pricingMode": "match", "maxDiscountPct": 60 }'
# 4. the health test and identity checks, then read the status (ready or failed)
curl -s -X POST $OPENCHEAP/sell/offers/OFFER_ID/test -H "$AUTH" -H "$JSON" -d '{}'
curl -s $OPENCHEAP/sell/offers/OFFER_ID -H "$AUTH"
# 5. go live with the statement your user accepted
curl -s $OPENCHEAP/sell/offers/OFFER_ID/publish -H "$AUTH" -H "$JSON" -d '{ "statement": "own-server-v2" }'The key is optional for your own server; Sell from your own server has what it must answer. A Z.ai GLM Coding Plan key is { "preset": "zai", "key": "…" }: a free-tier or unfunded key fails discover with the reason, and nothing is drafted on it. A preset marked comingSoon (OpenAI, Google AI Studio, DeepSeek, Moonshot) is refused with 422 preset_coming_soon, and so is a Z.ai open-platform key when you draft its models.
Operations and tools
- GET /sell/presetslist_supply_presetsWhat can be listed: your own server and Z.ai GLM Coding Plan keys now, the rest marked comingSoon; each provider's terms page and the statement with its version
- POST /sell/sellerbecome_sellerAccept the selling terms (owner only)
- GET · PATCH /sell/sellerget_seller · update_sellerSeller status, your daily cap and concurrency
- GET · POST /sell/credentialslist_supply_credentials · create_supply_credentialSaved keys (hint only) · save a key or your own server
- POST /sell/credentials/{id}/rotaterotate_supply_credentialA new key for the same listing
- DELETE /sell/credentials/{id}revoke_supply_credentialRemove a key: its offers are cancelled
- POST /sell/credentials/{id}/discoverdiscover_modelsRead the key's models and check it is funded (a job)
- GET /sell/jobs/{id}get_supply_jobA discovery, test or check, and its result
- GET · POST /sell/offerslist_offers · create_offersOffers with status, checks and market · draft offers from discovered models
- GET · PATCH · DELETE /sell/offers/{id}get_offer · set_offer_pricing · discard_offerOne offer · its price · discard a draft
- GET /sell/book/{model}get_order_bookThe model's order book: price levels, what buyers pay and you earn, asks, yours flagged
- POST /sell/offers/{id}/testtest_offerHealth test and identity checks
- POST /sell/offers/{id}/publishpublish_offerGo live, with the statement's version
- POST /sell/offers/{id}/pause · resume · cancel · reset-healthpause_offer · resume_offer · cancel_offer · reset_offer_healthRun a live offer
- POST /sell/offers/bulkbulk_offer_actionThe same action on up to 100 offers
- GET /sell/offers/{id}/healthget_offer_healthThe offer's health log
- GET /sell/earnings · /sell/earnings/requestsget_supply_earnings · list_supply_earningsEarnings by range and offer · served requests, an hour late
- GET · POST /sell/payoutsget_supply_payouts · request_payoutOwed, available, history · ask for a payout now from $5 (owner only); every balance from $5 is also paid in the next batch
- GET · PUT · DELETE /sell/payout-addressget_payout_address · set_payout_address · remove_payout_addressAny address for USDC on Base, no signature (owner only to change)
Over MCP
The tools above are the Sell group of the MCP server. Ask in your own words. Reads can run without asking; a change that overwrites or deletes asks first.
- “List my vLLM server at https://llm.example.com/v1 on OpenCheap and match the market, with a floor of 60 %.”
- “Which of my offers are paused or unhealthy, and why?”
- “What did my offers earn this week, per model?”
- “Pause my offer on kimi-k3.”