Skip to content

API reference

This page is the lookup summary. For the end-to-end walkthrough with examples, see Send data via the API. The interactive endpoint-by-endpoint API reference is served at /docs/api on your Ronja domain. For AI agents, a compact machine-readable index of every endpoint (with the scope each needs) is served at /docs/api/llms.txt (also at /.well-known/llms.txt), alongside the full OpenAPI schema at /docs/api/openapi.json.

Tokens are created by an Admin on the API Tokens page (page title “Tokens”): click Create New.

Create field Details
Name A label, e.g. “CI pipeline”
Role Every token is bound to a role (default User); the role bounds everything the token can do. An admin cannot mint a token at or above their own role level
Access Limited to scopes (recommended default — grant at least one scope) or Full access (unrestricted within its role; a warning is shown)
  • The token secret is shown exactly once at creation (“Copy this token now — you won’t be able to see it again.”). It cannot be re-displayed — only revoked.
  • Send it as a bearer token: Authorization: Bearer <token> (the Bearer prefix is optional).
  • Tokens are bound to your organization and can be revoked at any time from the token list or detail page.

Scopes narrow a token within its role — they never widen it. Each scope is granted at None, Read, or Write. A scoped token is denied on anything outside its grants.

Scope Covers
Data Tables, files, tags, connectors & search
Structure Features & access groups
Analytics Data apps, notes & knowledge
Automation Workflows, schedules & scripts
Agents AI agents, chat & MCP
Secrets Secrets & OAuth connections
Admin Members, billing, governance & settings

A token can later be restricted to scopes, or widened back to full access (confirm-gated), from its detail page.

A Ronja API credential is a scoped API token sealed inside a secret, pointed back at your own Ronja organization, so Ronja’s own agents and workflows can call your Ronja API for operations the built-in tools don’t cover. An Admin can create one either with the endpoint below or simply by asking Ronja in a chat (“create a Ronja API credential”), which mints it after an approval step. See Let Ronja call your API for the walkthrough.

Field Details
Endpoint POST /api/v2/secret/ronja-apiAdmin only
name A label for the secret
featureID Required — the feature the credential lives in. A private feature keeps it personal; a shared feature exposes it to that feature’s members
scopeGrants Optional map of scope → read/write (same scopes as a token). Omitted → the read-oriented default (Data, Structure, Analytics at Read; Agents and Automation excluded)
role Optional — the minted token’s role (default Admin, so the credential can reach role-gated read endpoints such as listing every table in the organization; the read-only scope default still bounds writes). Pass User for a narrower credential. Capped to the caller’s own role
expiresInDays Optional — the credential’s lifetime. Omitted → 90 days; a larger number lives longer. After it expires the credential stops authenticating and must be re-created

The response is the created secret’s metadata. The token is never returned — it is sealed in the secret and can’t be read back. An agent or workflow references the secret and Ronja injects the Authorization header automatically.

A Ronja API credential can’t create another Ronja API credential, and each organization can hold only a limited number at once — delete an unused one before creating another if you reach the limit.

Reachability caveat. A scoped credential (like any scoped token) reaches only routes that carry a scope annotation; anything outside its grants is denied. The interactive reference at /docs/api lists the set of public endpoints, which is not identical to the scope-reachable set — some listed endpoints aren’t reachable by a scoped credential, and some reachable ones aren’t listed. Treat /docs/api as a guide, not a guarantee, and grant scopes to match the routes you actually call.

Push data files into a manual-integration tableIntegration tables fed by files instead of a connector. Requires a token whose role has Admin rights and (if scoped) Data: Write; listing files only needs read access.

Format: Parquet only. Filenames must match [a-zA-Z0-9._-]+.parquet; convert CSV to Parquet client-side first.

Step Endpoint Notes
1. Create the table (once) POST /api/v2/feature/model with {"name":"...","featureID":"...","kind":"manual_integration"} featureID goes in the body, not the path. Returns the table ID (table_…), also visible in the table’s URL
2. Upload a file PUT /api/v2/feature/model/{tableID}/file/{filename} Raw body (not multipart), max 1 GiB per file. Re-uploading the same filename replaces it; different filenames accumulate and build together
3. List files GET /api/v2/feature/model/{tableID}/files Paginated (200 per page, nextCursor)
4. Delete a file DELETE /api/v2/feature/model/{tableID}/file/{filename} 404 if the file doesn’t exist
5. Build POST /api/v2/feature/model/{tableID}/build Required — uploads alone are not queryable. Async: poll GET /api/v2/feature/model/{tableID} until status is ready

The table’s schema is auto-detected from the Parquet files.

Each upload is validated as a readable Parquet file before it is accepted: the footer must parse, there must be at least one column, and the data pages must decode. A file that fails any of these is rejected with a 400 and discarded, so a bad file can never be stored. An empty file (valid Parquet, zero rows) is accepted — it is treated as “no data this window” and skipped at build time, contributing nothing to the table.

Bodies are always {"error": "<message>"}.

Status Message Cause
401 Unauthorized Missing or invalid token
403 forbidden Role below Admin, or a scoped token without the Data: Write grant
400 invalid filename: must match [a-zA-Z0-9._-]+.parquet Bad filename
400 model is not a manual_integration table Wrong table kind
400 no rows: ... Nonexistent table ID (returned as 400, not 404)
400 uploaded file is not a valid parquet file (corrupt or missing footer): re-export the file and upload again Not a Parquet file, or a corrupt/truncated footer; the upload is discarded
400 uploaded parquet file has no columns The file declares an empty schema; the upload is discarded
400 uploaded parquet file is unreadable (…): re-export the file and upload again The footer parses but the data pages fail to decode; the upload is discarded
404 file not found DELETE on a missing file
413 file too large: max 1073741824 bytes Over 1 GiB — split the file client-side