API overview
Base paths, credentials, request and response shapes, pagination and error codes across every CID222 API surface.
- Version: 0.4
- Role: admin_user, normal_user, viewer
- Type: reference
Every CID222 API surface, the base path it answers on, the credential it accepts and the shape it returns.
Base URL
There is no global route prefix. Each controller declares its own base path, and the paths are not
uniform — detection is the only surface under /api/v1.
The gateway listens on TCP 3000, bound to 0.0.0.0, and an appliance publishes it on 443 behind
its own TLS front. Use https://<appliance-fqdn> in production and http://localhost:3000 only
when you are calling the container directly.
| Surface | Base path |
|---|---|
| Chat | /chat |
| Detection | /api/v1/guardrails |
| Sessions | /sessions |
| Models | /models |
| Authentication | /auth |
| Image analysis | /image-analysis |
| Document analysis | /document-analysis |
| Administration | /admin/… |
Authentication
Every authenticated request carries a bearer token. CID222 distinguishes the two credential types
by the cid_key_ prefix.
Warning
A gateway API key reaches /chat/…, /models and POST /api/v1/guardrails/detect. It does not
reach /sessions, /image-analysis, /document-analysis or /admin/…, which validate a JWT
and nothing else. See Authentication.
Chat endpoints
| Method | Path | Credential | Description |
|---|---|---|---|
| POST | /chat/completions | API key or JWT | Filtered completion, returned as Server-Sent Events (SSE) |
| POST | /chat/harden-prompt | API key or JWT | Rewrite a prompt for safety and clarity; returns JSON |
| GET | /chat/providers | API key or JWT | Providers registered in the catalogue and whether each is supported |
| GET | /models | API key or JWT | Models your tenant holds an active credential for |
Detection and file endpoints
| Method | Path | Credential | Description |
|---|---|---|---|
| POST | /api/v1/guardrails/detect | API key or JWT | Scan text for PII, secrets, toxicity and jailbreak. Returns 200 |
| POST | /image-analysis/analyze | JWT | Image PII by optical character recognition (OCR), with optional redaction |
| GET | /image-analysis/ocr-engines | JWT | OCR engines available |
| POST | /image-analysis/compare-ocr | JWT | Run one image through several OCR engines |
| POST | /document-analysis/analyze | JWT | Document PII from base64 JSON |
| POST | /document-analysis/analyze-file | JWT | Document PII from a multipart upload |
| POST | /document-analysis/redact-jobs | JWT | Start an asynchronous redaction job |
| GET | /document-analysis/redact-jobs/:jobId | JWT | Poll a redaction job |
| GET | /document-analysis/supported-types | JWT | Accepted document types |
| GET | /document-analysis/:id/download | JWT | Download a redacted document |
Session endpoints
| Method | Path | Credential | Description |
|---|---|---|---|
| POST | /sessions | JWT | Create an empty conversation session |
| GET | /sessions | JWT | List the tenant's chat sessions, most recently used first |
| GET | /sessions/:id | JWT | One session, including its full message history |
| PATCH | /sessions/:id | JWT | Rename a session |
| POST | /sessions/:id/messages | JWT | Send a message in a session; returns SSE |
| DELETE | /sessions/:id | JWT | Delete a session and its detections |
Authentication endpoints
| Method | Path | Credential | Description |
|---|---|---|---|
| POST | /auth/login | None | Exchange username and password for a JWT. Returns 200 |
| POST | /auth/forgot-password | None | Request a password-reset link |
| POST | /auth/reset-password | None | Complete a password reset |
| POST | /auth/change-password | JWT | Change the signed-in user's password |
Request format
Requests are JSON with Content-Type: application/json. Two behaviours are worth knowing before
you debug a request that "does nothing":
- Unknown fields are stripped, not rejected. Validation runs with whitelisting, so a body field the endpoint does not declare is silently removed and the request proceeds. A misspelled parameter produces a successful call with default behaviour.
- The body limit is 50 MB for JSON and URL-encoded bodies. Image analysis caps the decoded image at 10 MB and document analysis caps the upload at 20 MB, independently of that limit.
Response format
| Surface | Content type |
|---|---|
POST /chat/completions | text/event-stream |
POST /sessions/:id/messages | text/event-stream |
| Everything else | application/json |
The two streaming endpoints also send Cache-Control: no-cache, Connection: keep-alive and
X-Accel-Buffering: no.
An SSE response is a sequence of data: lines, each carrying one JSON object, terminated by
data: [DONE]:
Warning
There is no non-streaming chat mode. POST /chat/completions returns text/event-stream
whatever you set stream to, and the model's reply arrives in a single event rather than as
per-token deltas. Chat API documents the full event list.
Rate limits
Rate limiting exists only on the unauthenticated sign-in surfaces, keyed by client IP address.
| Endpoint | Limit |
|---|---|
POST /auth/login | 10 requests per minute |
POST /auth/forgot-password | 5 requests per minute |
POST /auth/reset-password | 5 requests per minute |
Every other endpoint, POST /chat/completions and POST /api/v1/guardrails/detect included, is
unlimited. CID222 sends no X-RateLimit-Limit, X-RateLimit-Remaining or X-RateLimit-Reset
header on any response, and there is no per-tier request or token quota. Budget provider spend
with Token Cost & Savings, not with a gateway quota.
Pagination
Pagination applies to admin list endpoints only — GET /admin/api-keys, GET /admin/models and
their siblings. GET /sessions and the chat surface return complete results.
Query parameters are page (default 1) and limit (default 10):
Errors
The error body is not uniform. A CID222 policy rejection carries a machine-readable code; a
framework-level rejection does not. Match on the HTTP status first.
| Code | Status | Meaning |
|---|---|---|
SETUP_REQUIRED | 423 | First-boot setup is unfinished; everything outside a small allowlist is locked |
LICENSE_EXPIRED | 402 | The licence is invalid or expired. Blocks chat, detection, inspection, image and document analysis |
FEATURE_NOT_LICENSED | 403 | The route is gated by a licence feature the installed tier lacks |
ROLE_NOT_FOR_CHAT | 403 | The auditor role called a chat or session-write endpoint |
READ_ONLY_ROLE | 403 | The viewer role attempted a mutating request |
Content blocks are not HTTP errors. On /chat/completions a blocked prompt or a blocked reply
arrives as an SSE event on a 200 response, so a client that inspects only the status code sees
success. Read the stream.
Notes
- Only detection is under
/api/v1. The prefix is hardcoded on that one controller. Treating it as a global version prefix produces 404s everywhere else. POST /api/v1/guardrails/detectreturns 200, not 201, despite being a POST.- Detection never returns raw PII.
detectedEntities[].valueis a placeholder or[REDACTED], andnormalization.originalTextis deliberately blank. - An unauthenticated detection call from a loopback or private address is admitted with no tenant context. This exists for the in-cluster red-team service. Every other caller needs a credential.
Related
- Chat API — the request body and the complete SSE event contract.
- Sessions API — server-side conversation state, JWT only.
- Authentication — issuing keys and obtaining tokens.
Last updated on