API conventions
Stable rules for integrating with the Unveilr Admin API (/v1/*). Follow these
so CI, scripts, and agent runtimes behave the same across tenants.
Versioning
| Surface | Meaning |
|---|---|
/v1/... | Current public Admin API |
OpenAPI info.version | Spec revision (today 0.1.0 — pre-GA) |
/internal/* | Not public — do not call |
Breaking changes before GA may ship with release notes. After GA, removals get a deprecation window. Prefer additive fields; treat unknown JSON fields as forward-compatible (ignore).
JSON shape
- Bodies use camelCase in JSON (
repoId,nextCursor,allowedTools). - Timestamps are ISO-8601 UTC.
- Resource ids are opaque strings.
Example list page (findings):
{
"items": [{ "id": "finding_…", "severity": "high", "status": "open" }],
"nextCursor": "eyJ…",
"total": 128
}
Pagination
Canonical pattern — GET /v1/findings:
| Query | Default | Notes |
|---|---|---|
limit | 50 | Max 200 |
cursor | — | Opaque; pass nextCursor from the previous page |
| Filters | — | repoId, severity, status, category, … |
curl -fsS "$UNVEILR_API/v1/findings?limit=50&status=open" \
-H "Authorization: Bearer $TOKEN"
# next page
curl -fsS "$UNVEILR_API/v1/findings?limit=50&status=open&cursor=$NEXT" \
-H "Authorization: Bearer $TOKEN"
Stop when nextCursor is null. Other list endpoints may still return a full
array — prefer findings-style pagination as those APIs adopt it.
HTTP status codes
| Status | Meaning | Client action |
|---|---|---|
| 200 / 201 / 204 | Success | Continue |
| 400 | Bad input (e.g. invalid cursor) | Fix request |
| 401 | Missing / invalid / revoked / expired credential | Refresh or remint token |
| 403 | Authenticated but not allowed (role, SoD, unapproved agent) | Stop / escalate |
| 404 | Unknown id (or not visible in this tenant) | Do not retry blindly |
| 409 | Conflict | Resolve state |
| 422 | Validation error | Fix body/schema |
| 429 | Rate limited (Gateway or edge WAF) | Back off; honor Retry-After if present |
| 5xx | Server / dependency | Retry with jitter |
Error bodies today use FastAPI detail (string or validation object). A stable
error.code + requestId envelope is on the GA roadmap — design clients to
read HTTP status first.
Rate limits
| Layer | Behavior |
|---|---|
| Edge (WAF) | Per-IP request budget (~2000 / window on AWS reference) |
| MCP Gateway | Per-instance sliding window; 429 when exceeded |
| Admin API | Edge-protected; per-token app quotas planned for GA |
For automation: exponential backoff on 429/503; keep CI concurrency modest.
Auth reminders
- Always
Authorization: Bearer … - Tenant is derived from the credential — never send tenant ids as a trust boundary.
- Agent calls fail closed when the identity is unknown, revoked, expired, or not approved.
Details: Authentication.
Public vs internal
| Call | OK for customers? |
|---|---|
/v1/*, /healthz, /readyz | Yes |
/mcp/* | Yes (agents) |
Console /* | Yes (humans) |
/internal/* | No |
X-Unveilr-* headers | No (automated tests only) |
SDKs
Thin clients for runtime governance:
| Language | Package path | Use |
|---|---|---|
| Python | sdk/python | @govern / framework adapters |
| JS/TS | sdk/js | requireAllow → /v1/govern/check |
Full Admin API SDKs (repos/findings/policies) are planned from OpenAPI. Until
then, use curl or generate a client from your operator’s OpenAPI export.