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-compatibleprovider with none uses the first model itsGET {baseUrl}/modelslists. - Your key: the one you declared, sent the way your
authsays. - Settings: stand-in values, of which the model's descriptor keeps only what it declares:
| Setting | Description |
|---|---|
prompt | "a probe image, one small grey cube on white" |
systemPrompt | "You are a probe." |
negativePrompt | "text, watermark" |
seed | 1 |
variations | 1 |
steps | 4 |
guidance | 3 |
strength | 0.5 |
aspectRatio | "1:1" |
width | 512 |
height | 512 |
scale | 2 |
conditionScale | 0.5 |
temperature | 0.5 |
maxTokens | 16 |
duration | 8 |
- 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#
| Outcome | Description |
|---|---|
pass | The request was accepted and the result was where your declaration says. ok is true. The only outcome that lets a declaration go live. |
fail | Something 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. |
inconclusive | Submit-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. |
| Field | Description |
|---|---|
okboolean | true only for pass. |
outcomestring | pass, fail or inconclusive. |
errorstring | Why, for fail and inconclusive. Your key is replaced with [redacted] wherever it appears. |
probedUrlstring | The URL the probe sent its request to — the submit URL for submit-and-poll. |
pendingTaskIdstring | For inconclusive: the task the next probe will check. |
resumedboolean | This probe checked a task an earlier probe started. |
{
"ok": true,
"outcome": "pass",
"probedUrl": "https://api.example.com/v2/task"
}{
"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"
}{
"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.503withstagecredentialorresolve-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-restorsubmit-pollrun has no request to send. A descriptor has to exist first. dispatch cannot build its request — …followed by the reason: the transport declaresGET(declarePOST), or the descriptor's endpoint is on another host than yourbaseUrl.no model to probe with — GET …/models answered HTTP …or… listed none—openai-compatibleonly.
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 shapesubmit response was not valid JSONcould not find a task id in the submit response (tried …)— settaskIdPath, or return the id at one ofid,task_id,data.id,data.task_id,result.id,result.task_id.- A
sync-restanswer with no file whereresult.pathpoints, such asresponse 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 JSONtask reported failure (status "…"): …— the status was inpoll.failure; the message aterrorPathfollows.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:
| Field | Description |
|---|---|
baseUrl | required, 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. |
pollPath | required, must be a non-empty string · must start with "/". |
method | must be one of GET | POST. |
auth | must 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. |
taskIdPath | must be a dotted path such as "data.task_id". |
unknown field | A field the family does not carry; the line lists the fields it does. |
family | A family tag that differs from the provider's own family. |
transport | must be an object. |
| Field | Description |
|---|---|
delivery.transport | must be one of sync | poll | webhook · must be "sync" (sync-rest) or must be "poll" (submit-poll) for this family. |
delivery.produces | must be one of … · is not a stored artefact (for text). |
delivery.result.kind | must be one of url | base64 | bytes · is unknown. |
delivery.result.path | is required for kind "url" (or "base64") · is meaningless for kind "bytes". |
delivery.result.mime | is required for kind "base64" (or "bytes"), e.g. image/png. |
delivery.poll | is required when transport is "poll" · is only meaningful when transport is "poll" · a polled result cannot be "bytes". |
delivery.poll fields | statusPath 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 placespricing_unit must be one of: run, token, character, second, megapixel, step, usd_microcredential 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.