Skip to main content
API referenceProvider key endpoints

Provider key endpoints

The key marketplace's surface: the buyer proxy that calls a provider on someone else's key, the public discovery reads, and the seller endpoints that list a key.

Base URL https://api.surplusintelligence.ai. Guides: your first call, listing your key.

The buyer proxy

POST/v1/resources/{resource}/{path...}

Calls {resource} on a seller's key. GET, POST and PUT are all accepted — the method and the path are the provider's own, and what is reachable is decided per provider.

{resource} is fal, wavespeed or elevenlabs.

The path shape differs by provider. Path-style providers (Wavespeed, ElevenLabs) take the provider's path directly. Fal is header-style: the path must be empty and the target rides in x-fal-target-url. A path on Fal is refused unexpected_path.

Authenticate with your Surplus API key. The market is prepaid credit only and never falls through to the on-chain rail.

Request headers

  • Authorizationstringrequired

    Bearer <your Surplus API key>.

  • x-fal-target-urlstring

    Fal only, and required there. The absolute https target on fal.run or queue.fal.run.

  • X-SI-Requirestring

    Comma-separated traits the serving account must claim, e.g. data.zdr,residency.eu. No offer claims all of them ⇒ trait_unavailable.

  • Idempotency-Keystring

    Accepted, but a relay is not replay-safe: a repeat is a second real generation and is billed as one.

Response headers

  • x-si-buyer-cost-microinteger

    What you were charged, in microdollars.

  • x-si-list-cost-microinteger

    What the provider would have billed direct. The difference is your saving.

Both are CORS-exposed. A failed call is charged zero, and a successful one is charged the provider's reported usage or the quote, whichever is lower.

Three providers, one key
curl -X POST $SURPLUS_BASE_URL/resources/elevenlabs/v1/sound-generation \
  -H "Authorization: Bearer $SURPLUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"a short soft chime","duration_seconds":1}' \
  --output chime.mp3

The minimum-discount mirror

POST/min{N}/v1/resources/{resource}/{path...}

Identical, except only offers at least N% off are considered. Nothing that cheap ⇒ no_resource_offer rather than a worse price. See minimum-discount routing.

The x402 rail

POST/x402/resources/{resource}/{path...}

The same proxy, paid per call with an x402 payment proof instead of prepaid credit — no Surplus key needed. Fal's queue is not available on this rail: a model that must be queued answers job_route_required telling you to use an API key. GET /.well-known/x402 advertises the rail.

Errors

Every refusal names one cause, so you can tell whose problem it is.

unexpected_pathStatus · 400Meaning · A header-style provider was given a path.
provider_unpriceableStatus · 400Meaning · Cannot be priced, so it is refused rather than guessed.
job_route_requiredStatus · 400Meaning · This model can run for minutes — submit it to the provider's queue.
insufficient_creditStatus · 402Meaning · Add prepaid credit. Nothing was reserved.
platform_route_refusedStatus · 403Meaning · The platform fence. Never reachable, for any seller.
policy_refusedStatus · 403Meaning · Offers exist; no seller's rules allow this call.
no_resource_offerStatus · 404Meaning · Nobody lists this provider, or none meets your min{N}.
job_not_foundStatus · 404Meaning · Not your job, or its 27-hour binding expired.
trait_unavailableStatus · 404Meaning · Nobody advertises what you required.
seller_cap_reachedStatus · 429Meaning · Every capable offer spent its cap. Resets 00:00 UTC.
offers_unhealthyStatus · 503Meaning · Every capable offer is backed off.

Discovery

No authentication — these are the public book.

  • GET /v1/resource/marketspublic

    Every live provider with its unit, live-offer count, and best and median discount.

  • GET /v1/resource/capabilitiespublic

    The capability catalogue a seller scopes a listing with. Cached 5 minutes.

  • GET /v1/resource/traitspublic

    What a buyer may require with X-SI-Require, and each trait's provenance. Cached 5 minutes.

  • GET /v1/resource/book/{provider}public

    One provider's book: the live offers, their discounts and whether they can serve you.

  • GET /v1/resource/market/analyticspublic

    Market-wide volume and savings.

GET /v1/resource/markets
curl $SURPLUS_BASE_URL/resource/markets

Buyer reads

  • GET /v1/resource/access

    Whether your account may buy on the key market right now, and why not if it may not.

  • GET /v1/resource/buyer/analytics

    Your spend and savings on provider keys.

Seller endpoints

All under /v1/resource/seller, all requiring a seller-authenticated key.

  • POST /v1/resource/seller/keys/probefree

    Validate a provider key before listing it. Body { resource_id, api_key }. The key is used once and never stored. A bad key answers 200 with ok: false.

  • POST /v1/resource/seller/offers

    List a key. resource_type and api_key are required, discount_percent is a whole number 5–80, and both ack_persists_state and ack_provider_terms must be true.

  • GET /v1/resource/seller/offers

    Your listings. Never includes the key or any fragment of it.

  • PATCH /v1/resource/seller/offers/{id}

    Reprice, re-cap, re-scope or pause.

  • DELETE /v1/resource/seller/offers/{id}

    Delist, releasing the uniqueness claim.

  • POST /v1/resource/seller/offers/{id}/purge

    Delist and destroy the stored credential.

  • DELETE /v1/resource/seller/offers

    Delist everything.

  • GET /v1/resource/seller/analytics

    Earnings, and the demand your own rules refused.

A credential may back one active offer per model, per base URL, across every workspace and organization. A second is refused 409 duplicate_offer_for_credential.

Key listings take api_key only (api_secret ⇒ api_secret_unsupported) and are priced by discount_percent only (pricing_multiplier ⇒ pricing_multiplier_unsupported).

Probe, then list
curl -X POST $SURPLUS_BASE_URL/resource/seller/keys/probe \
  -H "Authorization: Bearer $SURPLUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"resource_id":"elevenlabs","api_key":"<provider key>"}'