CircaOS API

Version 0.1.0 · raw openapi.json · /help · /cookbook

Schema-locked, tier-routed inference substrate with cryptographic response signing. The `/v1/chat/completions` request and response shape is API-compatible with the widely-adopted format so existing client SDKs work without modification. Byte-identical outputs at temperature 0. Hash-chained per-(tenant, app) audit. Substrate-resolved inference — no third-party hosted LLM is in the prod request path.

/v1

POST /v1/chat/completions

Create a chat completion (schema-locked, signed response)

Request/response shape is the widely-adopted `/v1/chat/completions` format, so existing client SDKs work unmodified. Every response is HMAC-signed; verify the `X-Cogos-Signature` header against your HMAC secret. At `temperature: 0` with `response_format.strict: true`, outputs are byte-identical across N identical-input calls.

Request body

{
  "application/json": {
    "schema": {
      "$ref": "#/components/schemas/ChatCompletionRequest"
    }
  }
}

Responses

  • 200 · Completion returned. Verify `X-Cogos-Signature` before trusting `choices[].message.content`.
  • 401 · Missing or invalid API key
  • 429 · Daily cap exceeded (free tier: 100 req/day)
GET /v1/models

List available models

Responses

  • 200 · Models list
  • 401 · Missing or invalid API key
GET /v1/me

Identity probe — caller's tenant, key, package, quota

Returns the requesting key's identity + the resolved package's monthly_request_quota, allowed_model_tiers, and current billing-cycle start. Used by CLI / SDK quota commands to render usage-vs-cap without a second call.

Responses

  • 200 · Identity payload
  • 401 · Missing or invalid API key
GET /v1/audit

Query the hash-chained audit log slice for this tenant

Returns the requesting tenant's chained usage rows since a unix-ms timestamp. Strictly tenant-scoped — customer A can never see customer B's rows. chain_ok reflects server-side verifyChain() on the returned slice; customers re-run verification locally for independent assurance.

nameinrequiredtypedescription
sincequerynointegerUnix-ms; rows with ts >= since are returned.
limitquerynointeger
app_idquerynostringOptional — scope the slice to a single app's chain.

Responses

  • 200 · Audit slice + chain integrity flag
  • 400 · Invalid `since` or `limit`
  • 401 · Missing or invalid API key
POST /v1/chat-grounded

Search-augmented chat — answer + citations bound by one receipt

Composes /v1/search + sovereign LLM on the server side so the customer makes ONE call and the output_hash binds answer + citations together as one indivisible artifact. Search trigger is heuristic in mode='auto' (keywords: today, current, latest, news, price of, who won, etc.); override with mode='always-search' or 'never-search'. ONE billable usage row per call regardless of internal sub-operations.

Request body

{
  "application/json": {
    "schema": {
      "type": "object",
      "required": [
        "query"
      ],
      "properties": {
        "query": {
          "type": "string"
        },
        "mode": {
          "type": "string",
          "enum": [
            "auto",
            "always-search",
            "never-search"
          ],
          "default": "auto"
        },
        "model": {
          "type": "string",
          "default": "cogos-tier-b"
        },
        "temperature": {
          "type": "number",
          "default": 0
        },
        "max_tokens": {
          "type": "integer",
          "default": 500
        },
        "max_results": {
          "type": "integer",
          "default": 5,
          "maximum": 10
        }
      }
    }
  }
}

Responses

  • 200 · Answer + citations + receipt with evidence_chain
  • 400 · Missing or invalid query
  • 401 · Missing or invalid API key
  • 429 · Daily cap or monthly quota exceeded
  • 502 · Upstream LLM call failed
GET /v1/process

List available deterministic processes

Catalog endpoint — machine-readable list of processes this gateway exposes. No auth required for discovery; invocations are auth-gated.

Responses

  • 200 · Process catalog
POST /v1/process/{slug}

Invoke a deterministic process — same input → same bytes out

Each process is a pure function over its input; output_hash in the receipt proves bit-stable output for this (input, engine_version). v0.1 ships iolta-reconcile and 5law-conflict-check.

nameinrequiredtypedescription
slugpathyesstringProcess id from /v1/process catalog (e.g. `iolta-reconcile`)

Request body

{
  "application/json": {
    "schema": {
      "type": "object",
      "description": "Process-specific input shape — see catalog for each process's schema."
    }
  }
}

Responses

  • 200 · Process output + receipt
  • 400 · Invalid input shape
  • 401 · Missing or invalid API key
  • 429 · Daily cap or monthly quota exceeded
  • 500 · Engine failure
POST /v1/search

Receipt-bearing live-web search

Live web search via Brave (or provider:'none' when BRAVE_SEARCH_API_KEY is unset — receipt still emitted). Same receipt-chain semantics as /v1/process; the output_hash proves what was returned at this moment (not determinism — search is non-deterministic by nature).

Request body

{
  "application/json": {
    "schema": {
      "type": "object",
      "required": [
        "query"
      ],
      "properties": {
        "query": {
          "type": "string"
        },
        "max_results": {
          "type": "integer",
          "default": 5,
          "maximum": 10
        }
      }
    }
  }
}

Responses

  • 200 · Search results + receipt
  • 401 · Missing or invalid API key
  • 429 · Daily cap or monthly quota exceeded
POST /v1/compose

Multi-step deterministic workflow composition

Linear-sequence composition of registered processes with end-to-end chain hashing. One billable usage row per composition (not per step).

Request body

{
  "application/json": {
    "schema": {
      "type": "object",
      "properties": {
        "steps": {
          "type": "array",
          "items": {
            "type": "object"
          }
        }
      }
    }
  }
}

Responses

  • 200 · Composed output + receipt
  • 400 · Invalid step shape
  • 401 · Missing or invalid API key
  • 429 · Daily cap or monthly quota exceeded
POST /v1/state/matters

Upsert one or many matter records (per-key stateful substrate)

Writes one chain-row per call. Reads on /v1/state/* GET endpoints are free (not metered).

Request body

{
  "application/json": {
    "schema": {
      "type": "object"
    }
  }
}

Responses

  • 200 · Write succeeded + receipt
  • 401 · Missing or invalid API key
  • 429 · Daily cap or monthly quota exceeded

/signup

POST /signup/free

Issue a free-tier API key (no email required)

Returns an HTML page with the new `sk-cogos-...` key and the matching HMAC secret. The key is shown once. Idempotent on email: if the supplied email already has a key, no second key is minted.

Request body

{
  "application/x-www-form-urlencoded": {
    "schema": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "description": "Optional. Used for support contact and dedup."
        }
      }
    }
  }
}

Responses

  • 200 · Either the new-key page or an already-exists notice.
  • 429 · Per-IP signup rate limited

/health

GET /health

Liveness check

Responses

  • 200 · Service alive