Call the engine over HTTP
datanotes serve starts the engine’s HTTP server on http://127.0.0.1:27150. Every operation of the engine is a route, so any language that sends HTTP requests can read and write your notes. This page covers tokens, the routes, the engine’s health report and errors; the HTTP API reference documents each route.
Authenticate your requests
Section titled “Authenticate your requests”Every request needs an Authorization: Bearer your_token header, with one of two tokens:
- Owner token:
httpServerTokenin the settings file, which the engine generates when it first starts; it can do everything - Named token: the engine creates it when you create a token for a program or an agent, with only the permissions you give it
Three routes answer without a token: GET /, GET /datanotes/openapi.json and the /datanotes/docs console. They hold no data from your notes.
To use another port, set httpServerPort in the settings, or start the engine with --port. To listen on another address, start the engine with --host. Choose the port explains both.
Call the engine’s routes
Section titled “Call the engine’s routes”The engine serves its operations and a description of itself:
POST /datanotes/operations/<operation>/: one route per operation, with the operation’s arguments as the JSON body, for examplePOST /datanotes/operations/insert_row/with{"table": "film", "values": {…}}GET /: whether the engine runs, and its versionGET /datanotes/openapi.json: the OpenAPI 3.1 description of every route, generated from the catalog of operations, to generate clients in any languageGET /datanotes/docs: the same description in an interactive console
The console is Swagger UI, which the engine serves itself, with nothing from other hosts. Click Authorize, paste the owner token or a named token, then click Execute on any route to call this engine. The browser keeps the token in its local storage until you log out in the Authorize dialog.
An operation’s body takes the same arguments as the agent’s tool of the same name. You read notes, rows or not, with three operations:
read_note: one note, by itspathlist_folder: the notes and folders in afoldersearch_notes: the notes that contain aquery
Routes and fields follow semantic versioning: see Compatibility.
Record who makes each write
Section titled “Record who makes each write”The X-Datanotes-Actor header tells the engine on whose behalf you write. Its value is JSON, with any of session, harness, model and tool:
curl -X POST http://127.0.0.1:27150/datanotes/operations/insert_row/ \ -H "Authorization: Bearer your_owner_token" \ -H "Content-Type: application/json" \ -H 'X-Datanotes-Actor: {"harness": "my-script"}' \ -d '{"table": "film", "values": {"title": "His Girl Friday", "year": 1940}}'The engine stores the actor with the write in the journal, and in the table’s history when the table keeps one. It adds the credential as auth: owner, or the named token’s name, which the header can’t claim.
Check the engine’s health
Section titled “Check the engine’s health”POST /datanotes/status/ reports the engine’s health, and datanotes status prints the same report from a shell. Check the engine’s status shows both.
Read errors
Section titled “Read errors”Errors come back as JSON {"error": "…", "hint": "…", "docs": "…"}: what is wrong, how to fix it, and the page of this site, in Markdown, that shows the fix (read the engine’s errors). The status is one of these:
- 400: bad input
- 401: missing or wrong token
- 403: a named token beyond its permissions
- 404: unknown table, view, migration or note
- 409: ambiguous table name
- 500: an unexpected error, or a write that failed partway and couldn’t be rolled back
- 503: a write that failed partway, which the engine rolled back, so nothing changed: send it again later
The engine answers a refused write, from validation or a conflict, with 422 (409 for an undo). The body is the operation’s result, with ok: false, the reasons, hint and docs, and the engine writes nothing. An unexpected error (500) has no hint: it isn’t a mistake in the request.
Several clients can write at the same time. Concurrent writes explains what the engine does then, and when to retry a refused write.
Keep the engine local
Section titled “Keep the engine local”The engine binds to 127.0.0.1 unless you start it with --host. It answers no Cross-Origin Resource Sharing (CORS) preflight, so web pages can’t call it. To reach it from another device, follow the security model.
Generate a client or explore the routes
Section titled “Generate a client or explore the routes”The HTTP API reference documents every route, generated from the same OpenAPI description, openapi.json. From JavaScript, use the JavaScript client. Agents use the Model Context Protocol (MCP) server.
To see the routes at work in one program, follow Build an app on Datanotes.