{"title":"The rules","lede":"KeyMart is a marketplace for model API keys. Sellers set their own prices; the platform never sets one, never takes a spread, and makes no routing choice of its own. This page is the whole rulebook — what happens to your call, what it costs, why it can be refused, and what the market keeps sealed.","footer":"These rules are the platform's behaviour, not a summary of it: the page is generated from the constants the code runs on, and the test suite goes red if the two ever differ. Questions about a specific call: every response carries an x-km-request-id, and your own Logs show the row it wrote.","commission_pct":"2.9%","constants":{"commission_pct":"2.9%","served_idle_drop_days":30,"default_max_r":1.0,"platform_max_r":999.0,"max_models":40,"max_providers":20,"balance_floor_usd":"$0.01","default_max_output_tokens":16384,"min_output_tokens":128,"hold_timeout_s":900,"min_topup_usd":"$5","max_topup_usd":"$1000","withdrawal_min_usd":"$20","refund_window_h":72,"refund_max_per_window":2,"refund_count_window_d":30,"rpm_floor":30,"cooldown_fails":3,"cooldown_window_s":60,"cooldown_statuses":[500,502,503,504],"stick_idle_ttl_h":24,"stick_wait_ms":1000,"contract_window_days_min":1,"contract_window_days_max":90,"contract_deposit_pct_min":"25%","contract_deposit_pct_max":"100%","contract_deposit_pct_default":"100%","ledger_grain_usd":"$0.00000001"},"sections":[{"id":"order","title":"How a call is given to a seller","lede":"KeyMart makes no routing decision of its own. Every request walks the buyer's own consent set, cheapest first, and the first seller with capacity takes it.","rules":[["The sort key is the price you pay","Candidates are ordered by unit price — (input price + output price) × the seller's rate, in US dollars per token. The wall at /market publishes that same number, so the price you see is the price you are sorted by."],["Equal prices are split by how much each key has actually served","When the cheapest listings tie, the tied group is reshuffled at random, weighted by each KEY's settled sales — every sale that key has ever made, not a recent window. A key that goes 30 days with no sale at all has that history dropped and starts level again. The weight is a straight pro-rata share of the tied group's history, so moving history between a seller's own keys changes nothing. Before any key in the tie has sold anything the group is split per SELLER first and then evenly among that seller's own listings, so a new seller cannot manufacture a share by listing one key many times. This is the only randomness in the walk."],["Everything dearer keeps strict price order","Candidates above the cheapest group are never reshuffled — they stay in price order and exist only as failover."],["A contract comes first","If you hold an in-window contract for the model, your own slices are the walk (cheapest locked rate first) and your standing terms are not consulted — the contract is the consent. KeyMart never serves a contract from another seller's key: if that key is down you get its error, not a substitute."],["Otherwise your standing terms decide who is eligible","A live listing is a candidate only if its provider is one you allow and its unit price is at or under your cap, expressed as a multiple of what the model's vendor charges directly (default 1× — the vendor's own price). At most 40 models and 20 providers per model; the cap saturates at 999×."],["There is no private supply on the live market","Every active listing on the wall is reachable by every buyer whose terms allow it. There are no invitations, no allow-lists and no per-buyer prices."]]},{"id":"capacity","title":"Capacity and when a seller is skipped","lede":"A seller declares what their key can do, and KeyMart admits against that declaration and against what the seller has already sold out of it — never against a number of KeyMart's own.","rules":[["The seller declares the limit","A listing carries one declared number: requests per minute, at least 30. KeyMart derives a concurrency limit from it and lowers that limit when the upstream itself answers 429. There is no platform ceiling on tokens per minute — how large your prompt is has no effect on whether you can be routed, and when an upstream is out of capacity it says so itself."],["Rate sold into a contract leaves the spot room","A contract can reserve part of a listing's declared rate for the buyer who paid for it. Those requests per minute come off the top: the spot room is offered the declared rpm minus everything live contracts have reserved on that listing, and the reserved traffic draws on a rate allowance of its own that spot cannot spend. Contracts first, spot sells the remainder — a listing whose whole declared rate is reserved serves no spot request at all and answers the same capacity refusal a busy key gives. A contract that reserved nothing shares the listing's one allowance with spot, first come first served."],["A failing key is taken out of the walk","3 upstream 5xx failures (500, 502, 503, 504), each within 60 seconds of the one before it, put that listing on ice for 60 seconds. A success in between does not clear the streak — only 60 quiet seconds do."],["A rejected key is stopped on the first strike","An upstream 401 or 402 stops the whole credential; a 403 stops the one listing. KeyMart does not probe keys and does not re-check them: the seller resumes the key, or replaces it."],["A warm prompt cache keeps you on the same seller","If a response shows the upstream read your prompt cache, the next call for that model goes to the same key first — a cache read costs a fraction of a fresh prompt. The binding is dropped as soon as a call reads no cache, and expires after 24h idle. A stuck key at its limit gets 1000ms of grace, then the call goes to the cheapest seller as usual. It changes the order only — never the price, and never a gate."]]},{"id":"money","title":"What a call costs you","lede":"The seller sets the price. KeyMart never sets one, never takes a spread, and never charges for a call that failed.","rules":[["Commission is paid by the seller","2.9% of what you are charged is KeyMart's commission, taken out of the seller's revenue — the same rate for every seller on every call. It is already inside the price you are quoted; nothing is added on top."],["vs direct (buyer's multiple)","The price you pay divided by the vendor's direct price for the same model — the alternative you actually have, which is why it is the one your standing terms cap."],["ask × upstream (seller's multiple)","A seller's ask is a multiple of the list price of the upstream they serve from, and the row names that upstream. Two sellers on two upstreams can quote the same multiple and cost you different money, which is why the market wall publishes both the list price and what you pay."],["A failed call is free","Any failure — upstream error, rate limit, a key that died mid-flight, KeyMart's own — costs $0 and the pre-authorisation is released."],["Money is kept in ledger units, and rounded down","Every charge is booked in ledger units of $0.00000001, rounded down to that grain — never up. The wallet shows cents; anything under a cent is shown at full precision."],["If you hang up, you pay for what was generated","KeyMart keeps reading the upstream to the end so the usage is real, and bills you for the tokens the model actually produced. Hanging up is not counted against the seller."],["The pre-authorisation is the worst case, not the bill","Before the call a hold is placed for the most it could cost: your input tokens plus your output cap (or 16384 when you set none), at the seller's rate. It is voided and replaced by the real charge within seconds of the answer, and expires by itself after 900s. If your balance cannot cover the worst case, KeyMart lowers your output cap to what you can afford and tells you so in the x-km-output-cap header; below 128 tokens the call is refused instead of being silently truncated."],["A balance is required before you are routed","Balances at or under $0.01, and any unsettled debt from a previous call, stop a live request before any seller is touched. A contract call is exempt: it places no pre-authorisation and debits no balance, so a contract you hold is served whatever your balance says. What the balance is still for is the end of that contract — where its deposit was under 100%, whatever you drew above the deposit is collected from your balance in one move when the contract closes, so keep it funded."],["Top-ups, refunds and payouts","Top-ups run $5–$1000 through Stripe; the card fee is shown separately and is never refunded. An unused top-up can be refunded within 72h of payment, at most 2 times per 30 days. Balance never expires. Sellers withdraw from $20 in USDT (TRC20), or move earnings into their own buying balance."]]},{"id":"contracts","title":"Contracts","lede":"The other door: buy a seller's capacity at a rate locked for a window, instead of paying spot.","rules":[["Either side can post the order","A seller offers capacity on one listing; a buyer posts an order for what they want to buy. Either is filled whole or in part — several buyers can split one offer, several sellers can fill one demand order — and every fill is its own contract, with what is left still on the book. An order is public on the contract shelf, or private: a private order is on no shelf, in no market feed, and is reached only through the invite link its author hands out. None of this exists on the live market, which stays anonymous spot."],["You prepay a deposit into escrow","The author of the order sets how much of a slice is prepaid — between 25% and 100% of it, and 100% unless they say otherwise. That share goes into KeyMart's escrow account when the slice is bought, and the window (1–90 days) starts then. Every call draws against the slice at the locked rate — including when spot is cheaper that minute. A deposit under 100% is the seller lending the difference: they carry it until the contract closes."],["The seller is paid at the end, not per call","Escrow is released once, when the slice is used up or the window closes. The deposit is the seller's either way — bought is bought, and an unused deposit is not refunded at expiry. Above the deposit you pay for what you actually drew and never for the rest of the slice: that balance is collected from your account in the same single move, capped by the slice — and where the deposit was the default 100%, there is nothing left to collect."],["Either side can ask for a human","Buyer or seller can request an admin review on any contract, running or finished, with a reason. An upheld breach refunds the entire remaining escrow to the buyer — KeyMart takes nothing from it. A breach is never decided by machine from a bad hour upstream: the platform does not probe keys, does not pause the clock and does not judge a failure rate."],["Supply that is physically gone refunds itself","The one automatic verdict: if the listing or the key the contract is written on stops existing — deleted, disabled, or retired with the model — the whole remaining escrow goes back to the buyer without anyone filing anything. There is nothing to review when the goods are gone."]]},{"id":"codes","title":"Why a call was refused","lede":"Every refusal of a call to the API — the paths under /v1, and anything KeyMart's edge refuses before them — carries a machine-readable code in x-km-code and in the error body. These four tables are the whole closed set of those words, and KeyMart answers an API call with no word that is not in them. The console's own API under /auth (what this site's pages call, and what your code never does) is not one of these surfaces: it answers in its framework's own shape, with no x-km-code.","tables":[{"id":"pre_trade","caption":"Refused before any seller was contacted — $0, and a row in your Logs","columns":["HTTP","x-km-code","What it means"],"rows":[{"code":"budget_exhausted","http":402,"http_alt":null,"http_note":null,"retry_after":null,"says":"Your own spend cap for this model is used up on every eligible provider. Raise or reset the per-provider spend cap in the BUY panel, then retry."},{"code":"insufficient_balance","http":402,"http_alt":null,"http_note":null,"retry_after":null,"says":"Your KeyMart balance is too low to serve this request: it has to cover the whole worst case of the call, plus anything still owed from an earlier one. Top up in the console, then retry — an unpaid amount is settled from your balance automatically."},{"code":"no_reference_price","http":422,"http_alt":null,"http_note":null,"retry_after":null,"says":"There is no vendor list price on file for this model, so a \"% of direct price\" cap cannot be measured and no provider with live supply carries a $ cap. Set a $ cap per provider for it in the BUY panel, or buy a contract, then retry."},{"code":"no_supply_for_filter","http":422,"http_alt":null,"http_note":null,"retry_after":null,"says":"No live supply matched your provider / max-rate filter for this model. Widen the providers or raise the max rate in the BUY panel, then retry."},{"code":"not_configured","http":422,"http_alt":null,"http_note":null,"retry_after":null,"says":"Routing for this model is off on your key. Turn it on in the BUY panel (tick providers, set your cap), or buy a contract for it, then retry."},{"code":"capacity_exhausted","http":429,"http_alt":null,"http_note":null,"retry_after":"Retry-After is sent when every matching seller's rpm bucket is empty — the wait is computed from those sellers' own declared refill rate. When the supply is cooling down or off the wall instead, no header is sent.","says":"Every seller KeyMart could route this model to is at capacity or cooling down right now. Nothing about the request was refused — retry shortly."},{"code":"no_match","http":429,"http_alt":null,"http_note":null,"retry_after":"No Retry-After is sent: KeyMart has no measured wait to give.","says":"KeyMart could not match a seller for this model on this request. Check that your standing terms for it are on and that any contract for it is in window, then retry shortly."},{"code":"contract_unroutable","http":503,"http_alt":null,"http_note":null,"retry_after":null,"says":"The key your contract for this model is written on is not answering, and KeyMart never serves a contract from another seller's key, so nothing was routed. Retry once the seller's key is back; if it stays down, open the contract in the console and request an admin review."},{"code":"market_unavailable","http":503,"http_alt":null,"http_note":null,"retry_after":null,"says":"KeyMart cannot serve this model right now: the marketplace itself is temporarily unavailable, so no seller was contacted. Retry in a few seconds; if it keeps happening, contact support."}]},{"id":"relayed","caption":"Routed, and then the call failed — $0, and a row in your Logs","columns":["HTTP","x-km-code","What it means"],"rows":[{"code":"cancelled","http":null,"http_alt":null,"http_note":"No status is sent: by then your own connection is gone.","retry_after":null,"says":"The request was cancelled before it completed."},{"code":"request_error","http":400,"http_alt":422,"http_note":"422 when the upstream itself answered 422 — your body is relayed as it was judged.","retry_after":null,"says":"The request could not be called as sent: either a field the route requires is missing — KeyMart refuses that before any seller is contacted — or the provider judged the body invalid. The message says which."},{"code":"rate_limited","http":429,"http_alt":null,"http_note":null,"retry_after":"Retry-After is the edge's own window (60 s) when KeyMart throttled you at the door, and otherwise only the upstream's own, relayed unchanged when it sends one.","says":"Rate limited upstream. Please retry shortly."},{"code":"error","http":502,"http_alt":504,"http_note":"504 when the failure was an upstream timeout, so an SDK's retry policy sees a timeout.","retry_after":null,"says":"The request could not be completed. You were not charged; retry shortly."},{"code":"upstream_error","http":502,"http_alt":null,"http_note":null,"retry_after":null,"says":"The upstream model failed to serve this request. You were not charged; retry shortly."}]},{"id":"edge","caption":"Answered by KeyMart's gateway itself, with no verdict from the router","columns":["HTTP","x-km-code","What it means"],"rows":[{"code":"invalid_api_key","http":401,"http_alt":null,"http_note":null,"retry_after":null,"says":"Invalid KeyMart API key. Issue a key in the KeyMart console and send it as `Authorization: Bearer <key>` (or `x-api-key`)."},{"code":"account_suspended","http":403,"http_alt":null,"http_note":null,"retry_after":null,"says":"This KeyMart API key is suspended. Contact support@keymart.ai."},{"code":"model_not_found","http":404,"http_alt":null,"http_note":null,"retry_after":null,"says":"The model id you sent is not on the KeyMart wall. GET /v1/models, sent with your KeyMart key, lists every model that is."},{"code":"not_found","http":404,"http_alt":null,"http_note":null,"retry_after":null,"says":"This endpoint is not served by KeyMart."},{"code":"method_not_allowed","http":405,"http_alt":null,"http_note":null,"retry_after":null,"says":"This method is not accepted on this endpoint."},{"code":"timeout","http":408,"http_alt":504,"http_note":"504 when the timeout was the upstream's own.","retry_after":null,"says":"The upstream model did not answer in time. You were not charged; retry."},{"code":"request_too_large","http":413,"http_alt":null,"http_note":null,"retry_after":null,"says":"The request body is larger than KeyMart accepts."}]},{"id":"edge_server","caption":"Answered by the edge server before the request reached KeyMart's gateway — $0, nothing routed, no row in your Logs","columns":["HTTP","x-km-code","What it means"],"rows":[{"code":"request_error","http":400,"http_alt":null,"http_note":null,"retry_after":null,"says":"The request could not be read."},{"code":"not_found","http":404,"http_alt":null,"http_note":null,"retry_after":null,"says":"This endpoint is not served by KeyMart."},{"code":"method_not_allowed","http":405,"http_alt":null,"http_note":null,"retry_after":null,"says":"This method is not accepted on this endpoint."},{"code":"timeout","http":408,"http_alt":null,"http_note":null,"retry_after":null,"says":"The request body did not arrive in time."},{"code":"request_too_large","http":413,"http_alt":null,"http_note":null,"retry_after":null,"says":"The request body is larger than this endpoint accepts."},{"code":"request_error","http":414,"http_alt":null,"http_note":null,"retry_after":null,"says":"The request URI is too long."},{"code":"rate_limited","http":429,"http_alt":null,"http_note":null,"retry_after":"Retry-After is the edge's own window (60 s) when KeyMart throttled you at the door, and otherwise only the upstream's own, relayed unchanged when it sends one.","says":"Too many requests from your address. Wait a minute and retry."},{"code":"error","http":500,"http_alt":null,"http_note":null,"retry_after":null,"says":"KeyMart hit an internal error. Retry shortly."},{"code":"upstream_error","http":502,"http_alt":null,"http_note":null,"retry_after":null,"says":"KeyMart could not reach the service behind this endpoint. You were not charged; retry shortly."},{"code":"upstream_error","http":503,"http_alt":null,"http_note":null,"retry_after":null,"says":"KeyMart is temporarily unavailable. Retry shortly."},{"code":"timeout","http":504,"http_alt":null,"http_note":null,"retry_after":null,"says":"The service behind this endpoint did not answer in time. You were not charged; retry."}]}],"rules":[["What the code tells you to do","The x-km-code says what happened; the HTTP status only tells an SDK how to treat it, and on its own it is not a guide to what you should do — a 408 and a 429 are both 4xx and neither is anything about your request. Every code above is in exactly one of three groups. budget_exhausted, insufficient_balance, invalid_api_key, method_not_allowed, model_not_found, no_reference_price, no_supply_for_filter, not_configured, not_found, request_error, request_too_large name something you can change — your standing terms, your balance, your key, the body, the path, the method, its size — and the same call sent again unchanged is refused again. cancelled, capacity_exhausted, contract_unroutable, error, market_unavailable, no_match, rate_limited, timeout, upstream_error are not a judgement about your request at all: supply, an upstream, an answer that did not arrive, or KeyMart itself. The same call sent again unchanged can succeed. account_suspended is a key KeyMart has suspended, and nothing you send changes that until support lifts it. A Retry-After header is sent only where KeyMart can measure the wait: when every matching seller's rpm bucket is empty it is computed from those sellers' own declared refill rate; the edge sends the width of its own window when it throttled you before any of that; and an upstream's own Retry-After is relayed through unchanged. Any other 429 carries no header — the note on the row says so, and there is no hidden wait behind it."],["Nothing was charged, whichever table it came from","Every code in the first table is decided before a seller is contacted: no upstream call was made and nothing was billed. The remaining tables are failures, and a failed call is free — see \"A failed call is free\" above. request_error is the one code that can come from either side: a body missing a field the route requires is refused before any seller, the same way, and a request the edge server will not even read (a URI too long, a body it cannot parse) never gets that far."],["Where a code shows up in your Logs","A refusal in the first two tables happened to a request KeyMart had already recognised as yours, so the same code is on the row in your Logs and you can look it up later. The last two tables are answered without a verdict from the router — by the gateway (an unusable key, a path KeyMart does not serve, a model that is not on the wall, an answer that never came) or by the edge server before the gateway was reached at all. Where the router never saw the request there is no buyer and no model to write a row about, and nothing is logged. model_not_found is the exception: your key was accepted, so a row is written, and it is filed under request_error, which is the word your Logs will show for it."],["A status can depend on what the upstream said","Where a row shows a second status, that is the same code carrying the upstream's own answer through: a rejected body relayed as 422 rather than flattened to 400, and a timeout relayed as 504 so an SDK's retry policy sees a timeout. The code never changes with it."],["One word can be answered by more than one part of KeyMart","The same code appears in more than one table because more than one thing can refuse a call: the router, the gateway behind it, and the edge server in front of both. Each row is a different refusal wearing the same word, and the status and the sentence on the row say which one you got."]]},{"id":"sealed","title":"What KeyMart does not publish","lede":"The wall shows prices. It does not show anyone's book.","rules":[["Sellers are anonymous","Buyers see a per-seller code (s-xxxx), never an identity, and sellers see b-xxxx for buyers."],["Only the executing price is published","A seller's sealed floor — the lowest price their follow-the-market setting may reach — never leaves the platform. The wall publishes what the next call actually costs and nothing behind it."],["Volumes are not published","No per-seller volume, no per-buyer spend, no order book. You see your own calls and your own money; sellers see theirs. The settled volume that splits an equal-price tie is used inside the router and shown to nobody."],["Your prompts are yours","KeyMart bills from token counts, and no seller or buyer is ever shown another's request. The gateway keeps a structural record of request shapes it has not seen before and of calls that failed upstream, for diagnosis — every string in it is replaced by its length and a hash before it touches disk, so your text is not stored anywhere."]]}]}