Skip to main content
CID222 Docs

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.

https://<appliance-fqdn>

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.

SurfaceBase 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.

# Gateway API key (server-to-server)
Authorization: Bearer cid_key_0123456789abcdef…

# User JWT (from POST /auth/login)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…

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

MethodPathCredentialDescription
POST/chat/completionsAPI key or JWTFiltered completion, returned as Server-Sent Events (SSE)
POST/chat/harden-promptAPI key or JWTRewrite a prompt for safety and clarity; returns JSON
GET/chat/providersAPI key or JWTProviders registered in the catalogue and whether each is supported
GET/modelsAPI key or JWTModels your tenant holds an active credential for

Detection and file endpoints

MethodPathCredentialDescription
POST/api/v1/guardrails/detectAPI key or JWTScan text for PII, secrets, toxicity and jailbreak. Returns 200
POST/image-analysis/analyzeJWTImage PII by optical character recognition (OCR), with optional redaction
GET/image-analysis/ocr-enginesJWTOCR engines available
POST/image-analysis/compare-ocrJWTRun one image through several OCR engines
POST/document-analysis/analyzeJWTDocument PII from base64 JSON
POST/document-analysis/analyze-fileJWTDocument PII from a multipart upload
POST/document-analysis/redact-jobsJWTStart an asynchronous redaction job
GET/document-analysis/redact-jobs/:jobIdJWTPoll a redaction job
GET/document-analysis/supported-typesJWTAccepted document types
GET/document-analysis/:id/downloadJWTDownload a redacted document

Session endpoints

MethodPathCredentialDescription
POST/sessionsJWTCreate an empty conversation session
GET/sessionsJWTList the tenant's chat sessions, most recently used first
GET/sessions/:idJWTOne session, including its full message history
PATCH/sessions/:idJWTRename a session
POST/sessions/:id/messagesJWTSend a message in a session; returns SSE
DELETE/sessions/:idJWTDelete a session and its detections

Authentication endpoints

MethodPathCredentialDescription
POST/auth/loginNoneExchange username and password for a JWT. Returns 200
POST/auth/forgot-passwordNoneRequest a password-reset link
POST/auth/reset-passwordNoneComplete a password reset
POST/auth/change-passwordJWTChange 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

SurfaceContent type
POST /chat/completionstext/event-stream
POST /sessions/:id/messagestext/event-stream
Everything elseapplication/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]:

data: {"type":"token_usage","usage":{"prompt_tokens":20,"completion_tokens":10,"total_tokens":30}}

data: {"id":"filtered-response","content":"Hello. How can I help?","finish_reason":"stop","filtered":false,"entities_masked":0}

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.

EndpointLimit
POST /auth/login10 requests per minute
POST /auth/forgot-password5 requests per minute
POST /auth/reset-password5 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):

{
  "data": [],
  "meta": { "total": 42, "page": 1, "limit": 10, "totalPages": 5 }
}

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.

{
  "statusCode": 400,
  "message": "Invalid request body",
  "error": "Bad Request"
}
{
  "statusCode": 403,
  "code": "FEATURE_NOT_LICENSED",
  "message": "This feature is not included in the installed license tier.",
  "feature": "documents",
  "tier": "starter"
}
CodeStatusMeaning
SETUP_REQUIRED423First-boot setup is unfinished; everything outside a small allowlist is locked
LICENSE_EXPIRED402The licence is invalid or expired. Blocks chat, detection, inspection, image and document analysis
FEATURE_NOT_LICENSED403The route is gated by a licence feature the installed tier lacks
ROLE_NOT_FOR_CHAT403The auditor role called a chat or session-write endpoint
READ_ONLY_ROLE403The 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/detect returns 200, not 201, despite being a POST.
  • Detection never returns raw PII. detectedEntities[].value is a placeholder or [REDACTED], and normalization.originalText is 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.
  • 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

On this page

Download PDF