sethucms
Build on it

API

One contract for every client. REST is the primary surface; GraphQL is generated from the same content model; OpenAPI is the source for SDK generation.

Resources

Drawing diagram…

REST endpoints (v1)

MethodPathPurpose
POST/v1/connectionsCreate a connection (validated, read-only by default)
GET/v1/connectionsList connections
GET/v1/connections/{id}Connection detail and health
PATCH/v1/connections/{id}Update config, mode, secret reference
DELETE/v1/connections/{id}Remove connection and stored secret
POST/v1/connections/{id}/introspectStart an introspection job
GET/v1/connections/{id}/collectionsList collections and fields
PATCH/v1/collections/{id}Edit display name, field UI hints, exposure
GET/v1/connections/{id}/collections/{name}/recordsList records (filter, sort, cursor)
GET/v1/connections/{id}/collections/{name}/records/{rid}Get one record
POST/v1/connections/{id}/collections/{name}/recordsCreate
PATCH/v1/connections/{id}/collections/{name}/records/{rid}Update
DELETE/v1/connections/{id}/collections/{name}/records/{rid}Delete
POST/v1/connections/{id}/batchBatch writes
GET/v1/auditQuery the audit log
POST/v1/workspaces/signinTrade a Firebase ID token for a session in the person's own workspace (doc 30)
GET/v1/schemaThe loaded schema file and where it differs from each connection; admin only (doc 29)
POST/v1/connections/{id}/filesUpload an image or PDF (doc 31)
GET, HEAD/v1/files/{id}/{fileId}Download a file; private files need a token
DELETE/v1/connections/{id}/files/{fileId}Remove a file; admin only

Workspace requests use the prefix /w/{workspaceId}, for example /w/{workspaceId}/v1/connections. | GET | /v1/health | Liveness and readiness |

Write endpoints return READ_ONLY on read-only connections.

Listing records

GET /v1/connections/c1/collections/orders/records
    ?filter={"and":[{"field":"status","op":"eq","value":"paid"}]}
    &sort=-created_at
    &fields=id,status,total
    &limit=50
    &cursor=eyJ...

Response:

{
  "data": [ { "id": "o_1", "status": "paid", "total": 120 } ],
  "page": { "nextCursor": "eyJ...", "limit": 50 },
  "meta": { "capabilityNotes": [] }
}

capabilityNotes lists emulated or degraded behaviour (for example "sort emulated at gateway").

Pagination

Cursor-only. Cursors are opaque, signed and bound to the query, so a client cannot alter the filter between pages. Offset pagination is offered only where the adapter's pagination.offset flag is true.

Errors

{
  "error": {
    "code": "CAPABILITY_UNSUPPORTED",
    "message": "Sorting by 'total' is not supported on this connection",
    "details": { "adapter": "dynamodb", "field": "total" },
    "requestId": "req_8f2a"
  }
}
CodeHTTP
VALIDATION_FAILED400
AUTH_FAILED401
FORBIDDEN403
NOT_FOUND404
CONFLICT409
CAPABILITY_UNSUPPORTED422
READ_ONLY403
RATE_LIMITED429
CONNECTION_FAILED502
TIMEOUT504
INTERNAL500

GraphQL

Generated per tenant from the content model: one type per collection, connections for paginated lists, and the same permission checks as REST. Cross-source relations resolve at the gateway with batching.

Authentication

Bearer token from the OIDC provider. Service tokens for server-to-server use are scoped to a tenant and a role, are rotatable, and are never accepted from browsers.

Rate limits and idempotency

  • Per-tenant and per-connection rate limits.
  • Writes accept an Idempotency-Key header.

Versioning

Path-versioned (/v1). Breaking changes ship as /v2; additive changes do not bump the version.