Skip to main content

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

SurfaceMeaning
/v1/...Current public Admin API
OpenAPI info.versionSpec 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 patternGET /v1/findings:

QueryDefaultNotes
limit50Max 200
cursorOpaque; pass nextCursor from the previous page
FiltersrepoId, 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

StatusMeaningClient action
200 / 201 / 204SuccessContinue
400Bad input (e.g. invalid cursor)Fix request
401Missing / invalid / revoked / expired credentialRefresh or remint token
403Authenticated but not allowed (role, SoD, unapproved agent)Stop / escalate
404Unknown id (or not visible in this tenant)Do not retry blindly
409ConflictResolve state
422Validation errorFix body/schema
429Rate limited (Gateway or edge WAF)Back off; honor Retry-After if present
5xxServer / dependencyRetry 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

LayerBehavior
Edge (WAF)Per-IP request budget (~2000 / window on AWS reference)
MCP GatewayPer-instance sliding window; 429 when exceeded
Admin APIEdge-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

CallOK for customers?
/v1/*, /healthz, /readyzYes
/mcp/*Yes (agents)
Console /*Yes (humans)
/internal/*No
X-Unveilr-* headersNo (automated tests only)

SDKs

Thin clients for runtime governance:

LanguagePackage pathUse
Pythonsdk/python@govern / framework adapters
JS/TSsdk/jsrequireAllow/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.