Skip to main content
The SOLO Network API uses standard HTTP status codes and returns structured JSON error bodies. This page documents the exact response shapes, real examples of each status, and what your integration should do in response.

The error envelope

Application errors — anything the API’s domain logic rejects — return a consistent envelope:
Two kinds of responses use a shorter shape — just {"detail": "..."} with no error_code:
  • 422 request-shape validation, where FastAPI rejects the request before it reaches domain logic.
  • Authentication-layer 401/403, raised while verifying the bearer token (see Authentication).

Error codes

HTTP status codes

A 204 is not an error. It means the query ran — and is accounted for — but the network could not assemble a result that meets the policy’s requirements for this entity. Capture the X-Ref-Id header before treating the response as “no data”: it’s the reference for that specific query if you need to follow up.

Examples by status

Each example below is a real response produced by the API’s handlers.
Creating a consumer consent without affirming consent was gathered:
Updating a consent record with an empty change set:
Querying a product without identifying the subject:
Authentication-layer rejections use the short shape:
A valid token whose user has no account on the network yet:
A token lacking a required permission (short shape, from the auth layer):
A domain-level authorization failure (full envelope):
Reading a consent that doesn’t exist in the given network scope:
Configuring a furnishing policy by an unknown ID:
404 also covers resources that exist but are outside your network scope — the API does not distinguish “doesn’t exist” from “not visible to you”.
Creating something that already exists, or modifying state that has moved underneath you:
Re-read the current state before deciding whether to retry — a 409 on a create often means the resource is already there and your work is done.
The detail is a single string in the form <field path>: <message>, where the path walks from the request part (body, query, path) down to the offending field. Only the first validation error is reported.
Fix the named field and resend. The API Reference documents the expected type and format of every field.
Unexpected failures never leak internals:
Known-but-failed internal operations return OPERATION_FAILED instead. Both are logged and monitored on SOLO’s side; include the request_id when reporting one.

Validation errors vs domain errors

The API draws a sharp line between two kinds of “bad request”, and the status code tells you which side you’re on:
  • 422 — the request itself is malformed. A required field is missing, a date doesn’t parse, a UUID is garbled. The request never reached business logic. This is a bug in the calling code: fix the payload. The body is the short shape with a field path: message detail.
  • 400 — the request is well-formed but the operation is invalid. Every field parsed, but a business rule said no: consent wasn’t gathered, an update contained nothing updatable, a required identifier was absent given the combination of inputs. The body is the full envelope with "error_code": "VALIDATION_ERROR". Fixing this usually means changing what you’re asking for, not how you’re serializing it.
Treat 422 as a build-time problem (your integration is constructing requests wrong) and 400 as a run-time problem (this particular operation isn’t allowed right now, or needs different inputs).

Request IDs

Every request is assigned a request_id as it enters the API, and error envelopes include it whenever it’s available. The same ID is attached to SOLO’s internal logs and traces for that request. When contacting support about a failed call, always include:
  1. The request_id from the error body (or the X-Ref-Id header for 204 product-query responses).
  2. The full response body and status code.
  3. The endpoint, method, and approximate timestamp (with timezone).
With a request_id, support can jump directly to the exact request; without one, they’re searching by time window.

Retry guidance

Product query endpoints are billable. Build retry logic carefully so a transient failure doesn’t turn into a loop of repeated billable queries — cap attempts, and use the non-billable POST /v1/products/check coverage check when you only need to know whether data exists.