Requests and responses

Send named API actions, read their results and handle errors.

View Markdown
On this page

Cabane's HTTP API is served from https://app.cabane.ai. Workspace requests select an operation: a named API action such as files.read.

For example, send this JSON to POST /api/workspaces/{workspaceId}/ops/query:

json
{
  "op": "files.read",
  "args": {
    "path": "/api-example/hello.md"
  }
}

Replace {workspaceId} with the workspace's UUID. Send Authorization: Bearer TOKEN and Content-Type: application/json. All arguments go in one flat args object; the operation declaration tells you their names.

Endpoints

EndpointPurposeBody
POST /api/workspaces/{workspaceId}/ops/queryRead contentOne {op, args} or a batch of reads
POST /api/workspaces/{workspaceId}/ops/mutateChange contentOne {op, args}
POST /api/workspaces/{workspaceId}/ops/describeDiscover operations and arguments{} or {"op":"files.read"}

First API request shows complete curl requests, including how to obtain the workspace ID and token.

Success and failure

A successful operation returns HTTP 200 with ok: true and its answer in result. For the file written in the first-request walkthrough:

json
{
  "ok": true,
  "result": {
    "path": "/api-example/hello.md",
    "mime": "text/markdown",
    "size": 38,
    "sha256": "edb3a4c9af5d8b0e6e755719bae5ffeee15c6aaca2bb994ec08f678dc116f52e",
    "created": true
  }
}

An operation failure also returns HTTP 200, with ok: false. Writing to that existing path without overwrite returns:

json
{
  "ok": false,
  "error": {
    "kind": "conflict",
    "code": "name_conflict",
    "message": "name_conflict: a file already exists at \"/api-example/hello.md\". Pass { overwrite: true } to replace its contents."
  }
}

Branch on error.kind for the recovery strategy and error.code for the particular cause. Use message to explain the failure. Errors may also include declaration to correct a call or current with the current hash or version. A current hash is a reason to reread the file before replacing it.

Errors that prevent a request from reaching an operation use an HTTP error status and a different body:

http
HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error":"invalid_json"}

Common HTTP errors are 400 invalid_json for malformed JSON, 400 invalid_id for an invalid ID, 401 unauthenticated for an unusable credential, and 404 not_found for a route the credential cannot access. A batch sent to mutate returns 400 batch_not_supported_for_writes. These responses have no ok field.

Check the HTTP status first, then ok. A client that checks only HTTP 200 will miss operation failures.

Operation error kinds

kindWhat to do
bad_callCorrect the named arguments using the returned declaration or describe.
unknown_opCheck the operation name; use describe to find the intended action.
wrong_kindSend reads to query and writes to mutate.
not_foundCheck the identifier and the credential's access. A hidden object also appears missing.
ambiguousReplace a name or text match with an exact identifier.
conflictReread the object and reconcile the name, content or version conflict.
forbiddenUse an identity with the required permission, or have the appropriate person perform the action.
too_largeReduce the input size or item count named in the error.
refusedInspect code and message for a state or policy requirement, such as an archived target.
output_too_largeNarrow the read or split the batch. See Pagination and batching.
timeoutNarrow an expensive read. For a write, establish what happened before retrying.
transientRetry the same call; this kind explicitly permits that recovery.
internal_errorPreserve the error for investigation. Check the resulting state before replaying a write.

There is no general guarantee that replaying a failed or disconnected write is safe. Safe writes and retries explains which operations provide that guarantee.

Discover an operation

Send {} to describe for the operation index. To inspect one operation, send:

json
{
  "op": "files.read"
}

The response provides its call declaration and supporting types. You can also use a search phrase, such as {"op":"read a file"}, to find relevant operations. The Operation reference publishes these declarations together.

The call-line notation is a compact description of JSON arguments:

NotationMeaning
path:stringA required string argument named path
maxBytes?:numberAn optional number argument
overwrite?:boolean=falseOptional; defaults to false
id|reference:stringSupply one of those named arguments
→ FileReadThe result has the declared FileRead shape

The call line is documentation; the request still uses {"op":"…","args":{…}}.

Identifiers and file content

Use UUIDs in id and names ending in Id. Use the named alternative when you have a different identifier: slug or roomSlug for a room slug, reference or taskReference for a task reference, and boardPrefix for a board's reference prefix. Do not put a slug in an id field.

files.read returns text in content. For binary files, it returns content: null with MIME type, size, hash and an explanatory note. files.write accepts text, and files.import can fetch a public HTTPS source.