Skip to main content
Version: 2026-08-25 (archived)

Errors

All Voshi API errors share one JSON envelope:

{
"id": "Ie4rR0r1d",
"api": "api",
"time": "2026-07-27T18:10:00+00:00",
"error": "ValidationError",
"message": "score must be between 0 and 1",
"details": {}
}
idstring

A unique ID for this error occurrence. Include it when contacting support — it lets the Voshi team find the corresponding server-side report.

errorstring

The error class, matching the status code below.

messagestring

A human-readable description of what went wrong.

detailsobject

Structured extras, when the error has them.

note

The response format is content-negotiated on the Accept header: API clients sending Accept: application/json (or no preference) get the JSON envelope; a browser gets an HTML error page carrying the same report ID.

Status codes​

StatusErrorWhen
401AuthenticationErrorMissing, malformed, invalid, or expired credentials — a bad API key, a suspended app, or a stale api.token.
403NotAuthorizedAuthenticated, but not allowed — e.g. an app data token used on another user's row.
404Http404The resource doesn't exist — or belongs to another app. Voshi deliberately doesn't distinguish these, so other apps' launches and grades can't be probed.
422ValidationErrorThe request was understood but a value is invalid. The message says which — see the per-endpoint error tables. Also how an unprovisioned course or location row answers.
500ApiExceptionSomething failed on Voshi's side. Retry, and report the error id if it persists.
warning

Validation failures return 422, not 400. If your HTTP client only treats 400 as a validation error, widen the check.

Provisioning errors​

Two 422s come from the provisioning flow:

MessageCause
App … has not been provisioned for Context …A GET/PUT/PATCH on a context or location storage row whose level isn't provisioned yet.
App … must be provisioned before its locations are provisionedA PUT to a provision.location URL while that course's provision.context is still unfinished. Call the course URL first.

Errors that don't reach your code​

Launch-time failures (draft app, broken callback URL, a course that isn't provisioned yet) happen before your endpoint is called: the user sees a Voshi page with a report ID, and your app never hears about the launch. See errors on Voshi's side.

Deep-link failures work the same way, in the other direction: if your locations endpoint times out, refuses the request, or returns something Voshi can't read, the instructor sees the error and your app is told nothing.

Grade sync failures are not HTTP errors​

A grade submission whose LMS sync fails still returns 200 — the failure is reported in-band via sync_status: "failed" and sync_error, so you can retry by re-POSTing. See sync status and retries.