https://api.visiqlabs.com.
Validation errors
A request that fails schema validation returns400 Bad Request with a machine-readable body. The error field is always a short string; a details field carries the underlying diagnostics.
error string names what failed to parse:
The
details payload has one of three concrete shapes depending on the endpoint — all are derived from the same underlying validator, so all pinpoint the offending field(s):- Flattened (the unified
POST /evaluateand the/orchestrate/*endpoints):{ "formErrors": [...], "fieldErrors": { "field": ["message"] } }. - Raw issues (the unified
/rulesCRUD): an array of issue objects, each{ "code": "...", "path": ["field"], "message": "..." }. - Mapped (the
/record/*endpoints): an array of{ "field": "path.to.field", "message": "..." }.
Invalid rule ID, etc.) and Invalid JSON body carry no details.400 means nothing was persisted.
Versioned vs unversioned paths
Two path conventions coexist, and which one an endpoint uses is deliberate./v1/* — the versioned read API
Cross-cutting and query endpoints live under a
/v1 prefix: the decision audit-log reads (/v1/allow/audit-log, /v1/recall/audit-log, /v1/record/audit-log), the cognition reads (/v1/allow/cognition/sessions, /v1/allow/cognition/events), and decision polling (/v1/allow/decisions/:id). The prefix marks the stable, URL-versioned public surface. Other /v1 routes serve the dashboard or the partner program and are not part of the API-key surface.Unversioned — the governance planes
The governance surfaces are mounted at the root without a version segment:
/allow/*, /recall/*, /orchestrate/*, /rules/*, /evaluate, and /record/*. They are kept unversioned for product isolation, and their evolution is governed by the SDK wire contract below, not by a URL version./v1 path stable and adds fields additively; a governance-plane endpoint evolves under the bundle-dialect contract. The OEM Partner API is a third, separate surface with its own dated version header and a 12-month deprecation window — see Versioning & deprecation.
List pagination
List endpoints acceptpage (default 1) and limit query parameters and return a paginated envelope. The default and maximum limit, and the name of the page-size field in the response, vary by surface:
Both fields hold the same value — the effective page size — under a different key.
total is an accurate server-side count over the (vendor-scoped) query.
Error codes
Every JSON error response carries a stable, machine-readablecode next to the human-readable error string. Branch on code; show error to people. The field is additive, so existing clients that read only error are unaffected.
error is already a snake_case identifier (for example rate_limited or insufficient_scope), code repeats it. Otherwise code is the default for the HTTP status:
Any other status uses
error as its code. An endpoint that sets its own code keeps it.
Idempotent writes
The write endpoints below accept an optional idempotency key, so a client can retry a request after a timeout or a dropped connection without creating a second rule, agent or approval response. Send the key in theIdempotency-Key header (the legacy X-Idempotency-Key header is also read). A request without a key behaves exactly as it always has.
How a key behaves:
- Format. 1 to 256 characters: letters, digits,
-and_. A UUID v4 is a good choice. An invalid key returns400, and so does sending both headers with different values. - Scope. A key belongs to the credential that sent it (the API key, or the signed-in user) within your organization, and it lives for 24 hours. Another key never receives your stored response.
- Replay. Repeating a request with the same key, method, path, query string and body within 24 hours returns the stored status and body with the header
X-Idempotent-Replayed: true, and the operation does not run again. The replay also carries the originalLocation,Content-Location,ETag,Link,DeprecationandSunsetheaders; it never carries cookies. - Mismatch. Reusing a key with a different method, path, query string or body returns
422. - In flight. If the first request is still running, a repeat waits briefly and then returns
409. Retry after a short delay. A request that has held its key for more than 2 minutes without finishing is treated as abandoned, and the next request with that key runs instead. - Failures are not stored. A
5xxor429response releases the key, so a retry with the same key runs the request again. Other4xxresponses are stored and replayed. - Store outage. If the idempotency store is unavailable, a request that carries a key is refused with
503andRetry-After, rather than running without replay protection.
code:
The evaluation, rule-bundle and telemetry endpoints (
/evaluate, /allow/evaluate, /recall/evaluate, /rules/bundle and the SDK ingest routes) do not take part. Evaluation is already safe to repeat, and those paths must keep serving a running agent even when the idempotency store is down.Authentication & rate limits
All endpoints authenticate with a Bearer credential and are rate-limited per key (default 600 requests / 60 seconds). Credentials come in two audiences — operational harness keys confined to the SDK routes, and management keys governed by permission grants. The full model, error codes, and the permission ↔ endpoint matrix live in Managing API Keys.Stability policy
The platform is pre-1.0 — there is no frozen wire-compatibility guarantee yet, and the SDK surface may change across a minor release until v1.0 GA. Two properties hold regardless of version, because a governance product cannot be casual about them:1
Additive-only, readers ship first
The control plane never emits a bundle construct — a new outcome verb, field, or operation facet — that the reading SDK cannot already enforce. The SDK that understands a construct is published before the plane emits it. Write your clients as tolerant readers: ignore response fields you don’t recognize rather than failing on them.
2
Fail closed on the unrecognized
An SDK treats any construct it does not recognize as must-understand and resolves it to the fail-closed outcome for a confirmed-enforcing agent — never fail open. A version skew can degrade coverage but never safety.