Skip to content
SBDocs

Providers · Reference

Probe results and errors

What a probe sends, each outcome and what it means, and every problem a declaration can be refused for.

A probe is one real request to your endpoint, built and read exactly the way a customer's run is. Checking a declaration's shape catches typos; only a probe catches a declaration that is well formed and wrong — a path that answers 404, a header your API does not read, a result path your answer does not have. Nothing goes live without a passing probe.

What the probe sends#

  • The model: one model your provider serves that has a descriptor. An openai-compatible provider with none uses the first model its GET {baseUrl}/models lists.
  • Your key: the one you declared, sent the way your auth says.
  • Settings: stand-in values, of which the model's descriptor keeps only what it declares:
Stand-in settings a probe uses
SettingDescription
prompt"a probe image, one small grey cube on white"
systemPrompt"You are a probe."
negativePrompt"text, watermark"
seed1
variations1
steps4
guidance3
strength0.5
aspectRatio"1:1"
width512
height512
scale2
conditionScale0.5
temperature0.5
maxTokens16
duration8
  • Input files: a public sample image and 3D model that your API can download. There is no fetchable sample audio yet, so a model that needs an audio input cannot pass a probe.

Note: a probe is a real call

Your API does the work, and may bill your own account for it. A submit-and-poll probe starts a real task.

Outcomes#

Probe outcomes
OutcomeDescription
passThe request was accepted and the result was where your declaration says. ok is true. The only outcome that lets a declaration go live.
failSomething did not work; error says what. For a claim, the declaration cannot be handed over until a later probe passes. For a live provider in its trial period, a failed probe run by Sushibelt hands the provider back; one you ran yourself does not.
inconclusiveSubmit-and-poll only: the task started and your API answered, but it had not finished at the first poll, so the result path was not checked yet. pendingTaskId is the task. Probe again: for up to 24 hours, and while the transport and model are unchanged, the next probe checks that same task instead of starting a new one. Neither a pass nor a failure.
Probe answer fields
FieldDescription
okbooleantrue only for pass.
outcomestringpass, fail or inconclusive.
errorstringWhy, for fail and inconclusive. Your key is replaced with [redacted] wherever it appears.
probedUrlstringThe URL the probe sent its request to — the submit URL for submit-and-poll.
pendingTaskIdstringFor inconclusive: the task the next probe will check.
resumedbooleanThis probe checked a task an earlier probe started.
A passJSON
{
  "ok": true,
  "outcome": "pass",
  "probedUrl": "https://api.example.com/v2/task"
}
A failureJSON
{
  "ok": false,
  "outcome": "fail",
  "error": "YOUR_PROVIDER_KEY: no value at declared output path \"data.output.model\" — the declared path is wrong, or the provider changed its response shape",
  "probedUrl": "https://api.example.com/v2/task"
}
Not finished yetJSON
{
  "ok": false,
  "outcome": "inconclusive",
  "error": "YOUR_PROVIDER_KEY: task \"abc123\" had not reached a terminal state yet — …",
  "probedUrl": "https://api.example.com/v2/task",
  "pendingTaskId": "abc123"
}

Answers from before the request is sent#

  • { "ok": false, "stage": "validate", "problems": [...] } — the stored declaration does not pass its checks. Declare it again.
  • { "ok": false, "stage": "credential", "error": "… no credential configured to probe with …" } — declare your key first. The claim records it as a failed probe.
  • 503 with stage credential or resolve-descriptor — Sushibelt could not read your key or the descriptors. Nothing is recorded; try again.
  • 400 Declare a transport before probing.
  • 404 No claim in verifying for this provider. — the claim is not approved, or has moved on.

Why a probe fails#

The error starts with your provider key. The common reasons, by where they happen:

Building the request#

  • No descriptor names a model for your provider, so a sync-rest or submit-poll run has no request to send. A descriptor has to exist first.
  • dispatch cannot build its request — … followed by the reason: the transport declares GET (declare POST), or the descriptor's endpoint is on another host than your baseUrl.
  • no model to probe with — GET …/models answered HTTP … or … listed none — openai-compatible only.

Your answer to the request#

  • rejected the request (HTTP …): … — your API answered with an error status; your message follows.
  • response had no "choices" array — not an OpenAI-compatible shape
  • submit response was not valid JSON
  • could not find a task id in the submit response (tried …) — set taskIdPath, or return the id at one of id, task_id, data.id, data.task_id, result.id, result.task_id.
  • A sync-rest answer with no file where result.path points, such as response had no base64 payload at ….

The poll#

  • poll rejected (HTTP …): … — the poll URL (baseUrl + pollPath + "/" + taskId) answered with an error.
  • poll response was not valid JSON
  • task reported failure (status "…"): … — the status was in poll.failure; the message at errorPath follows.
  • no value at declared output path … — the declared path is wrong, or the provider changed its response shape

The network#

  • probe threw — … — the request did not complete: DNS, TLS, a refused connection or similar.

Declaration problems#

A declaration that breaks a rule is refused with 400 Invalid transport declaration and a problems list. Each line names the field. The lines:

Transport problems
FieldDescription
baseUrlrequired, must be a non-empty string · must not end with a trailing slash · must be an absolute http(s) URL · for a claim, must be on … or one of its subdomains.
pollPathrequired, must be a non-empty string · must start with "/".
methodmust be one of GET | POST.
authmust be an object · auth.scheme: must be one of bearer | header · auth.header: required for scheme "header" · auth.header: meaningless for scheme "bearer" · unknown field.
taskIdPathmust be a dotted path such as "data.task_id".
unknown fieldA field the family does not carry; the line lists the fields it does.
familyA family tag that differs from the provider's own family.
transportmust be an object.
Delivery problems
FieldDescription
delivery.transportmust be one of sync | poll | webhook · must be "sync" (sync-rest) or must be "poll" (submit-poll) for this family.
delivery.producesmust be one of … · is not a stored artefact (for text).
delivery.result.kindmust be one of url | base64 | bytes · is unknown.
delivery.result.pathis required for kind "url" (or "base64") · is meaningless for kind "bytes".
delivery.result.mimeis required for kind "base64" (or "bytes"), e.g. image/png.
delivery.pollis required when transport is "poll" · is only meaningful when transport is "poll" · a polled result cannot be "bytes".
delivery.poll fieldsstatusPath must be a string · success must list at least one terminal success state · failure must list at least one terminal failure state · states cannot mean both success and failure.

A claim declaration can also be refused for its price or key:

  • credits_per_unit must be a number greater than 0 · credits_per_unit must have at most 6 decimal places
  • pricing_unit must be one of: run, token, character, second, megapixel, step, usd_micro
  • credential must be an object holding the key this provider will be called with

Replacing a key#

Replacing the key of a provider you operate runs a probe with the new key first. The key is saved only on a pass. Otherwise the answer is 422 — The new key did not work, so the old key is still in use: …, or The provider did not finish the test call in time. The old key is still in use — try again. — and nothing changes. See keep your key current.

Next steps