Skip to content

Tarinoi Public API

Version 0.0.2 — 2026-06-09

Tarinoi exposes a REST API for reading and writing project documents from outside the application. It is intended for pipeline integrations, custom plugin development, and any other use case where you need programmatic access to project content without going through the Tarinoi UI.


Intended uses

Pipeline integration — import documents into Tarinoi from an external pipeline, or export them to a downstream system. For example, a screenplay import tool might push a set of card documents into a board collection, or a reporting tool might pull the full project state periodically.

Custom plugin integration — build tools that extend Tarinoi by reading and writing documents directly. Because the API operates on raw document structures, a plugin has full visibility into the project and can create, update, or remove any document it has access to.

Other programmatic access — anything that benefits from scripted read access (backups, auditing, search indexing) or write access (bulk operations, migrations, automation).


Caveats

The write API applies minimal integrity checks. It does not enforce relational constraints between documents, validate payload schemas beyond what the database requires, or prevent writes that would leave the project in an inconsistent state. You can write documents with malformed payloads, orphaned references, or conflicting IDs.

If you use the write API incorrectly you can seriously corrupt your project data, and there is no automatic recovery. Before writing at scale, test against a non-production project. Keep backups. If you are unsure whether a write is safe, use the read API to examine the current state first. Inspect your results in Tarinoi before committing, but note that reverting a collection will revert user-originated changes along with API-originated ones. Be careful not to inconvenience your users.


Features

Read access

The read endpoint returns a stream of all documents matching your query, in newline-delimited JSON (NDJSON) format. You can fetch:

  • The full project — all documents across all layers and collections.
  • A single layer — all documents in a specific layer (the main project layer is tarinoi:main-project-layer).
  • A single collection — all documents in a specific collection within a layer.

Additional filters allow narrowing by origin_tag or excluding a specific document_type.

Pagination is cursor-based — the response includes a cursor value you pass to the next request to continue from where you left off.

Write access

The write endpoint accepts a batch of documents as NDJSON and ingests them idempotently into the buffer layer (tarinoi:main-project-layer.buffer). All written documents are tagged with the __api__ origin tag, regardless of what the caller supplies. Existing documents with the same collection_id and document_id in the buffer layer are overwritten. The maximum request body size is 10 MB.

After ingestion, the server emits real-time update signals to all connected Tarinoi clients for the affected project. Clients that have the project open will sync automatically — no manual refresh required.

Writing to the buffer layer means API-originated changes are isolated from committed project content and can be reverted independently from within Tarinoi if something goes wrong.


Authorisation

All API requests are authenticated with an opaque API access token passed as a Bearer token in the Authorization header:

Authorization: Bearer <token>

Tokens are scoped to an organisation (not to individual projects). A token with read permission may call the read endpoint for any project in that organisation. A token with write permission may also call the write endpoint.

Tokens have a configurable expiry of 1 to 365 days. They cannot be renewed — generate a new token before the old one expires. A token that has been revoked or has passed its expiry date is rejected with 401 Unauthorized.

Generating tokens

Tokens are managed in the Tarinoi application under the organisation's API access settings. When generating a token you choose:

  • Label — a human-readable name for the token (for your own reference).
  • Permissionread (read-only) or write (read and write).
  • Validity — number of days until the token expires (maximum 365).

The raw token value is shown exactly once at generation time. Copy it immediately — it cannot be retrieved again. The application only stores a hash of the token for verification.

Active tokens can be revoked at any time. Revoked tokens remain visible in the token list until you delete them.


API reference

Base URL

https://<your-tarinoi-host>/k/api/v1

Read documents

GET /k/api/v1/:groupId/:projectId/documents

Query parameters

ParameterRequiredDescription
layer_idRequired when collection_id is setLayer to read from. Use tarinoi:main-project-layer for the main layer.
collection_idOptionalRestrict to a single collection. Requires layer_id.
origin_tagOptionalExclude documents with a specific origin tag.
document_type_notOptionalExclude documents of a specific type.
cursorOptionalResume a paginated response from a previous request.

Response

200 OK with Content-Type: application/x-ndjson. Each line is a JSON object representing one document. If the result is paginated, the final line contains a cursor object:

json
{"cursor": 1234567}

Pass this value as the cursor query parameter in the next request to fetch the next page. When no cursor object appears, you have received the full result.

Example — fetch all documents in a collection

bash
curl -H "Authorization: Bearer <token>" \
  "https://your-tarinoi-host/k/api/v1/<groupId>/<projectId>/documents\
?layer_id=tarinoi:main-project-layer&collection_id=<collectionId>"

Example — count documents

bash
curl -s -H "Authorization: Bearer <token>" \
  "https://your-tarinoi-host/k/api/v1/<groupId>/<projectId>/documents\
?layer_id=tarinoi:main-project-layer" | wc -l

Write documents

POST /k/api/v1/:groupId/:projectId/documents
Content-Type: application/x-ndjson

Request body

Newline-delimited JSON. Each line must be a complete document object. The server always overwrites tenant_id, group_id, project_id, layer_id, and origin_tag — any values you supply for these fields are ignored.

Maximum body size: 10 MB.

Response

200 OK with a JSON summary:

json
{"count": 3, "errors": []}

count is the number of documents successfully ingested. errors is a list of per-document errors (empty on a clean write).

Example — write a single card document

bash
curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/x-ndjson" \
  --data '{"document_id":"<id>","collection_id":"<collectionId>","document_type":"card",...}' \
  "https://your-tarinoi-host/k/api/v1/<groupId>/<projectId>/documents"

Example — write a file of documents

bash
curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @documents.ndjson \
  "https://your-tarinoi-host/k/api/v1/<groupId>/<projectId>/documents"

Document data format versioning

Every Tarinoi document carries a data_version: a semantic version of the document format (not of the document's contents, and not of this API, which is versioned by URL path).

json
{"document_id": "...", "data_version": "1.0.0", "payload": { }}

What the version numbers mean

BumpMeaningWhat it means for you
Major (1.x.x2.0.0)Breaking change to the document format.A consumer written against the old major can no longer correctly read the data. You must update.
Minor (1.0.x1.1.0)Additive, backward-compatible: new optional fields or payload keys.Your existing consumer keeps working. It will see fields it doesn't recognise, and should ignore them.
Patch (1.0.01.0.1)Cosmetic; no shape change.Nothing.

The compatibility rule: a consumer built for format X.Y.Z can safely read any document whose data_version has the same major and a minor no higher than Y.

Consumers should therefore:

  • Check the major. If a document's major exceeds the one you were built for, don't guess — fail loudly and prompt for an update. The format changed in a way you cannot correctly interpret.
  • Tolerate unknown fields. A minor bump adds things. Ignore what you don't recognise rather than rejecting the document, or a routine additive release will break you.

Reading

Documents returned by the read endpoint carry their data_version as a top-level field. Documents in a project's Git repository carry it too, so a consumer reading the repo directly sees the same version the API reports.

Writing

You do not have to supply data_version when writing. Documents arriving without one, or with an older one, are automatically upgraded to the current format on ingestion, and their digest is recomputed. You will get the upgraded document back on the next read.

A document whose data_version the server does not recognise — one from a newer Tarinoi than the server you are writing to, or from a format whose support has been dropped — is rejected, and appears in the errors array of the write response rather than being silently misinterpreted.


Error responses

StatusBodyMeaning
400 Bad Request{"error":"INVALID_QUERY","message":"..."}Missing or invalid query parameters.
400 Bad Request{"error":"EMPTY_BODY"}Write request sent with no body.
401 UnauthorizedToken is missing, expired, or revoked.
403 ForbiddenToken does not have the required permission, or does not belong to the requested organisation.
500 Internal Server ErrorUnexpected server error.