Skip to main content
MarketplaceProvider Keys — Wavespeed

Provider Keys — Wavespeed

Wavespeed is a path-style provider, and almost everything on it is a job: you submit a task, you get an id, and you collect the result separately.

Billing unit: per image. Wavespeed keeps no record of a call against the seller's account.

What is reachable

Two rules, and together they are the whole surface:

POST /api/v3/{publisher}/+Covers · Submit a task to one of 44 allowed publishers' models.
GET /api/v3/predictions/*/resultCovers · Read one task's result.

Generation only. No price lookups, model lists, uploads, balance, billing or prediction history — and POST /api/v3/predictions, the generic submit, is refused precisely because it would sidestep the per-publisher allowlist.

The 44 publishers are the model owners Wavespeed hosts:

alibaba  black-forest-labs  bria  bytedance  character-ai  chatterbox
clarity-ai  decart  elevenlabs  google  heygen  hitem3d
hyper3d  ideogram-ai  inworld  kwaivgi  leonardoai  lightricks
luma  meshy  meta  microsoft  midjourney  minimax
mirelo-ai  mureka-ai  nvidia  openai  pika  pixverse
pruna-ai  recraft-ai  runwayml  skywork-ai  sonilo  sourceful
sync  topaz  tripo3d  veed  vidu  wavespeed-ai
x-ai  z-ai

A model under any other owner is refused policy_refused — the publisher is part of the rule, not a hint.

A listed publisher does not mean every model under it is priced. black-forest-labs/flux-schnell reads like the obvious first call and is a 404 at Wavespeed's own price endpoint, so it is refused provider_unpriceable rather than charged at a guess. wavespeed-ai/flux-schnell is the priced equivalent. If a model refuses this way, try the wavespeed-ai mirror of it.

Submit, then collect

A Wavespeed task, end to end
  1. POST the modelAnswers { data: { id, urls } }
  2. Bound to that offer27 h, your account only
  3. GET the status URLFree. created → processing → completed
  4. GET …/resultThe image, and the charge settles
The submit answers at once — the id is not the image. The charge is owed at the quote from the submit and settles at the actual figure when you read the result, so a task you never collect is never charged at an actual.
A full task
curl -X POST $SURPLUS_BASE_URL/resources/wavespeed/api/v3/wavespeed-ai/flux-schnell \
  -H "Authorization: Bearer $SURPLUS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"prompt":"a tiny blue paper boat on a white table","size":"1024*1024"}'

Look closely at urls.get in that response. Wavespeed returned its own api.wavespeed.ai URL; we rewrote it to point back at our route before handing it to you. Follow it as given and your poll stays on your own Surplus key and on the same seller's offer. Call Wavespeed's URL directly and you have no credential.

That rewriting is why path-style providers need no special handling from you, and it is covered in full under jobs and settlement.

Streaming is refused

Wavespeed publishes streaming variants at /api/v3/{publisher}/{model}/stream, and they are denied provider-wide rather than left to each seller.

A streamed response has to be metered from the stream, which this rail does not do — it would be billed at the submit's estimate and settle wrong. That makes it a platform capability gap, not a seller's choice. Both the /stream and /stream/* forms are denied, because a variant may nest.

Two layers here as well

Everything Wavespeed publishes
Named on the denylistbalance, billing, user, webhook secret, media uploads, prediction history, streams
Refused by absenceanything under an unlisted publisher
Open44 publishers’ models, and one result read
The allowlist admits 44 publishers and one result read. The denylist underneath names the account routes, so widening the allowlist to pick up a new publisher cannot accidentally open them.

/api/v3/webhook* is named deliberately: it holds the account's webhook signing secret. It was already refused by being off the allowlist, but a fence that only works while the allowlist stays narrow is not a fence.