Skip to content

Native HTTP API

The native HTTP API is the direct, language-neutral surface of a Nimbus server. All endpoints accept and return JSON (Content-Type: application/json) unless noted. For a guided walkthrough, see Use the native HTTP and WebSocket API.

  • Base URL — the server’s listen address, for example http://localhost:8080.
  • Tenancy — data routes are scoped by path: /api/tenants/{tenant_id}/.... A tenant must exist before its data routes work; unknown tenants return 404 with code session.tenant_not_found.
  • Authentication — when the server runs with local security (the default for nimbus start), tenant, document, query, schema, scheduling, and WebSocket routes require a local admin credential: either Authorization: Bearer <token> or X-Nimbus-Admin-Token: <token>. Missing or invalid credentials return 401 with code auth.unauthorized.
  • Browser origins — requests that carry an Origin header are only accepted from loopback HTTP origins (localhost, 127.0.0.1, [::1]) on the server’s port. Non-browser clients that send no Origin header are not subject to this check. Disallowed origins return 403.
  • Errors — every error response uses the structured envelope described in the error reference.
MethodPathSuccessResponse body
GET/health200{"ok": true}

The health route requires no credential.

MethodPathSuccessResponse body
POST/api/tenants201{"id": "<tenant_id>"}
GET/api/tenants200{"tenants": ["<tenant_id>", ...]}
DELETE/api/tenants/{tenant_id}204

POST /api/tenants body: {"id": "<tenant_id>"}.

MethodPathSuccessResponse body
POST/api/tenants/{tenant_id}/documents201{"id": "<document_id>"}
GET/api/tenants/{tenant_id}/documents/{table}200{"data": [<document>, ...]}
GET/api/tenants/{tenant_id}/documents/{table}/{document_id}200{"document": <document>}
PATCH/api/tenants/{tenant_id}/documents/{table}/{document_id}200{"id": "<document_id>"}
DELETE/api/tenants/{tenant_id}/documents/{table}/{document_id}204

Request bodies:

  • Insert{"table": "<table>", "fields": {...}}. The table is created implicitly on first write.
  • Update{"patch": {...}}. The patch is a partial field map merged into the existing document.

Document objects in responses carry three system fields alongside the user-defined fields:

FieldTypeMeaning
_idstringDocument id
_creationTimenumberCreation time, epoch milliseconds
_updateTimenumberLast update time, epoch milliseconds
MethodPathSuccessResponse body
POST/api/tenants/{tenant_id}/query200{"data": [<document>, ...]}
POST/api/tenants/{tenant_id}/query/paginated200{"data": [...], "next_cursor": "<cursor>" | null, "has_more": bool}

Query object (the body of /query, and the query field of /query/paginated):

FieldTypeRequiredMeaning
tablestringyesTable to query
filtersarrayyesFilter clauses; [] matches all documents
orderobjectno{"field": "<field>", "direction": "asc" | "desc"}
limitnumbernoMaximum number of results

Filter clause: {"field": "<field>", "op": "<op>", "value": <json>} with operators eq, neq, gt, gte, lt, lte.

Paginated query body:

FieldTypeRequiredMeaning
queryobjectyesQuery object as above
page_sizenumberyesDocuments per page
afterstringnoCursor from a previous page’s next_cursor

Schemas are optional: a table without a schema accepts any document. Setting a schema adds validation constraints.

MethodPathSuccessResponse body
GET/api/tenants/{tenant_id}/schema200{"tables": {"<table>": <table schema>, ...}}
GET/api/tenants/{tenant_id}/schema/{table}200<table schema>
PUT/api/tenants/{tenant_id}/schema/{table}204
DELETE/api/tenants/{tenant_id}/schema/{table}204

Table schema shape (also the PUT request body; its table field must match the path table or the request fails with 400):

{
"table": "messages",
"fields": [
{ "name": "text", "field_type": "string", "required": true },
{ "name": "votes", "field_type": "number", "required": false }
],
"indexes": [
{ "name": "by_author", "fields": ["author"] }
]
}

Field types: string, number, boolean, array, object, any. Index entries may also carry server-managed id and state fields (state defaults to enabled); omit them when writing.

MethodPathSuccessResponse body
POST/api/tenants/{tenant_id}/schedule201{"job_id": "<job_id>"}
GET/api/tenants/{tenant_id}/schedule200{"jobs": [<job>, ...]}
DELETE/api/tenants/{tenant_id}/schedule/{job_id}204
GET/api/tenants/{tenant_id}/schedule/history/{job_id}200{"result": <job result>}

Schedule request body: {"run_after_ms": <ms>, "mutation": <mutation>}.

Mutation objects are tagged by type:

{ "type": "insert", "table": "messages", "fields": { "text": "hi" } }
{ "type": "update", "table": "messages", "id": "<document_id>", "patch": { "text": "edited" } }
{ "type": "delete", "table": "messages", "id": "<document_id>" }

insert also accepts an optional id. A pending job has id, run_at (epoch milliseconds), mutation, and created_at. A job result has id, run_at, finished_at, mutation, outcome (completed or failed), and error (string or null).

MethodPathSuccessResponse body
POST/api/tenants/{tenant_id}/crons201
GET/api/tenants/{tenant_id}/crons200{"crons": [<cron>, ...]}
DELETE/api/tenants/{tenant_id}/crons/{name}204

Create request body:

{
"name": "cleanup",
"schedule": { "type": "interval", "seconds": 3600 },
"mutation": { "type": "delete", "table": "temp", "id": "<document_id>" }
}

Interval schedules are the supported schedule type. A cron object in list responses has name, schedule, mutation, enabled, last_run (epoch milliseconds or null), next_run, and created_at.

These routes manage services, sandboxes, and sessions. The JavaScript SDK guide covers their request and response shapes through a typed client.

MethodPathPurpose
GET, POST/api/tenants/{tenant_id}/servicesList or create service definitions
GET, PUT, DELETE/api/tenants/{tenant_id}/services/{service_name}Read, update, or delete a service
POST/api/tenants/{tenant_id}/services/{service_name}/startStart a service
POST/api/tenants/{tenant_id}/services/{service_name}/stopStop a service
POST/api/tenants/{tenant_id}/services/{service_name}/restartRestart a service
GET, POST/api/tenants/{tenant_id}/sandboxesList or create sandboxes
GET/api/tenants/{tenant_id}/sandboxes/{sandbox_id}Read a sandbox
POST/api/tenants/{tenant_id}/sandboxes/{sandbox_id}/stopStop a sandbox
GET, POST/api/sessionsList or open sessions (tenant passed in query/body)
GET/api/sessions/{session_id}Read a session
POST/api/sessions/{session_id}/closeClose a session
MethodPathPurpose
GET/wsUpgrade to the nimbus.v2 subscription protocol

The tenant is identified by an X-Tenant-Id header or a tenant_id query parameter. See the WebSocket protocol reference.