API Contract
The cPod backend exposes a REST API documented as an OpenAPI 3.1 specification. The spec is the authoritative source of truth for every endpoint, request/response shape, and error code in the platform.
SDK vs direct API. Use the typed SDKs (@cpod/sdk, cpod-sdk, etc.) rather than
calling the REST API directly. The spec exists to define the contract between SDK and
backend — not as a primary integration point for application developers.
Specification file
The spec lives at docs/api-contract/openapi.yaml
in the repository. It follows OpenAPI 3.1 and uses JSON Schema Draft 2020-12 for all
schema definitions.
View interactively
npx @redocly/cli preview-docs docs/api-contract/openapi.yaml
# Opens http://localhost:8080Endpoint groups
| Group | Base path | Description |
|---|---|---|
| Authentication | /v1/oauth/* | Token issuance, introspection, app registration |
| People | /v1/people | Person CRUD |
| Groups | /v1/groups | Group CRUD + membership |
| Technology | /v1/technology | Assets + entitlements |
| Licenses | /v1/licenses | Licenses + assignments |
| Assets | /v1/assets | Physical + cloud resources |
| Risk | /v1/risk | Vulnerabilities, controls, risk items |
| Relationships | /v1/relationships | Entity graph edges |
| Data Sources | /v1/data-sources | Connector CRUD + sync |
| Storage: Files | /v1/storage/files/* | Blob upload/download |
| Storage: DB | /v1/storage/db/* | Document store |
| Storage: KV | /v1/storage/kv/* | Key-value store |
| Skills | /v1/skills | List + run |
| Workflows | /v1/workflows | CRUD + trigger |
| Jobs | /v1/jobs | Submit + track |
| Masking | /v1/masking/* | PII masking |
| Telemetry | /v1/telemetry/* | Audit, traces, events |
| Feature Flags | /v1/flags/* | Flag evaluation |
| Secrets | /v1/secrets/* | Secret resolution |
| Management | /v1/organizations, /v1/users, /v1/credentials, /v1/pods | Admin ops |
Contract validation (CI)
Every PR that touches docs/api-contract/, emulator/src/routes/, or sdks/ triggers the
API Contract Validation workflow (.github/workflows/api-contract.yml), which runs three jobs:
1. Spectral lint
Stoplight Spectral lints the spec against the
ruleset in .spectral.yaml. The ruleset extends spectral:oas and adds cPod-specific rules:
| Rule | Severity | Description |
|---|---|---|
operation-operationId | error | Every operation must have a unique operationId |
operation-description | warn | Every operation should include a description |
operation-tags | warn | Every operation should belong to a tag |
operation-success-response | error | Every operation must define at least one 2xx response |
oas3-schema | error | Schema objects must be valid OAS 3.1 |
cpod-id-pattern | warn | Entity id properties must declare a regex pattern |
cpod-no-inline-schemas | warn | Inline schemas with >3 properties should be extracted to components/schemas |
cpod-pagination-shape | warn | List-endpoint responses should include items and total |
2. Path completeness check
scripts/check-api-contract.mjs reads the spec and asserts:
- At least 40 paths are defined (warns if the spec looks truncated)
- At least 10 component schemas are defined
- OpenAPI version is
3.1.x info.contactis present- Every path starts with
/v1/
3. SDK alignment check
scripts/validate-api-contract.ts compares the set of SDK service names
(people, groups, technology, licenses, assets, risk, relationships, dataSources)
against the tags declared in the spec. The build fails if any SDK service has no
corresponding tag in the OpenAPI document (or vice-versa, with a warning).
Keeping the contract in sync
When you add a new endpoint, follow this order:
- Emulator route — add the handler in
emulator/src/routes/ - OpenAPI spec — add the path + schema to
docs/api-contract/openapi.yaml - SDK methods — implement the client method in all four SDKs
- Tests — add at minimum a smoke test per SDK
- Docs — update the relevant domain page under
docs/pages/docs/domains/
CI will catch any step you miss that touches the spec.
Never hand-edit the spec for an endpoint that does not yet exist in the emulator. The spec and the emulator must stay in lock-step — they are tested together in CI.
Entity ID prefixes
All cPod entity IDs use a three-letter kebab prefix so they are self-describing in logs:
| Entity | Prefix | Example |
|---|---|---|
| Person | per- | per-01J... |
| Group | grp- | grp-01J... |
| TechnologyAsset | tast- | tast-01J... |
| AccessEntitlement | ent- | ent-01J... |
| SoftwareLicense | lic- | lic-01J... |
| LicenseAssignment | lasgn- | lasgn-01J... |
| PhysicalAsset | past- | past-01J... |
| CloudResource | cres- | cres-01J... |
| Vulnerability | vuln- | vuln-01J... |
| ComplianceControl | ctrl- | ctrl-01J... |
| RiskItem | risk- | risk-01J... |
| Relationship | rel- | rel-01J... |
| DataSource | ds- | ds-01J... |
The cpod-id-pattern Spectral rule warns when an id property is missing a pattern
constraint — this keeps the spec honest about ID shapes.