Send data via the API
Create an API token
Section titled “Create an API token”- Open API Tokens in the admin sidebar (under People & Access).
- Click Create New. In the Create token modal, name the token (e.g.
CI pipeline) and pick a Role — the role bounds everything the token can do. - Keep the access setting on Limited to scopes (the default) and grant only what your integration needs: each scope (Data, Structure, Analytics, Automation, Agents, Secrets, Admin) can be None, Read, or Write. Full access skips scope limits entirely and shows a red warning — prefer Limited.
- Click Create token and copy the secret from the Token created modal.
“Copy this token now — you won’t be able to see it again.”
Send the token on every request in the Authorization header. The interactive API reference lives in the app under Documentation (/admin/docs/api); a summary is in the API reference.
Push data files
Section titled “Push data files”The file push API feeds a manual-integration table — a table whose data you push from your own systems instead of syncing through a connection. It accepts Parquet files only, sent as a raw request body (never multipart), up to 1 GiB per file. Convert CSV first, for example:
python -c "import pandas as pd; pd.read_csv('sales.csv').to_parquet('sales.parquet')"-
Create the table once —
featureID, the feature that will own the table, is a required body field alongsidename. The response contains the table ID,table_…, which also appears in the table’s URL in the app:Terminal window curl -X POST "$RONJA_BASE_URL/api/v2/feature/model" \-H "Authorization: $RONJA_API_TOKEN" \-d '{"name":"sales_pushes","kind":"manual_integration","featureID":"<your feature ID>"}' -
Upload a file:
Terminal window curl -X PUT \"$RONJA_BASE_URL/api/v2/feature/model/table_a1b2c3d4e5/file/sales_2026.parquet" \-H "Authorization: $RONJA_API_TOKEN" \--data-binary @./sales_2026.parquet# -> 200 {"filename":"sales_2026.parquet","size":48230}Re-uploading the same filename replaces the previous file; different filenames accumulate and are built together.
-
List or delete files as needed:
Terminal window curl "$RONJA_BASE_URL/api/v2/feature/model/table_a1b2c3d4e5/files" \-H "Authorization: $RONJA_API_TOKEN"curl -X DELETE \"$RONJA_BASE_URL/api/v2/feature/model/table_a1b2c3d4e5/file/old.parquet" \-H "Authorization: $RONJA_API_TOKEN" -
Build to make the data queryable — uploading alone is not enough:
Terminal window curl -X POST "$RONJA_BASE_URL/api/v2/feature/model/table_a1b2c3d4e5/build" \-H "Authorization: $RONJA_API_TOKEN"The build runs asynchronously; poll
GET /api/v2/feature/model/table_a1b2c3d4e5untilstatusis"ready". The schema is detected automatically from the Parquet files.
$RONJA_BASE_URL is your organization’s Ronja URL. Tokens are bound to your organization — a token from one organization can never read or write another’s tables.
Let Ronja call your API
Section titled “Let Ronja call your API”A Ronja API credential lets Ronja’s own agents and workflows call your Ronja API directly, for operations the built-in tools don’t already cover (general resource reads and writes, and so on). It is a scoped API token sealed inside a secret — the same kind of stored credential you’d use for any external service, but pointed back at your own Ronja organization.
The easiest way is to ask Ronja in a chat: as an Admin, tell Ronja to “create a Ronja API credential” and it mints one for you, pausing for your approval before it lands. The credential defaults to a safe read-oriented scope and to your working feature, and the token is sealed in the secret — never shown. If you are not an Admin, ask an Admin to create it (they can do it right in a chat).
You can also create one directly through the API. featureID is required — the credential lives in a feature, and putting it in your private feature keeps it personal to you (a shared feature would let that feature’s members use it too):
curl -X POST "$RONJA_BASE_URL/api/v2/secret/ronja-api" \ -H "Authorization: $RONJA_API_TOKEN" \ -d '{ "name": "Ronja self-call", "featureID": "<your private feature ID>", "scopeGrants": {"data": "read", "structure": "read"} }'scopeGrantsis optional. Omit it and the credential defaults to a read-oriented grant (Data, Structure, and Analytics at Read), which deliberately excludes the Agents and Automation scopes so a defaulted credential can’t start agent sessions or fire automations. Grant only what the work needs — the same scopes as any API token, each at Read or Write.roleis optional and defaults to Admin, so the credential can reach role-gated read endpoints — such as listing every table in the organization — that a User-role token would be denied. Role and scope are independent, so the read-onlyscopeGrantsdefault above still bounds what it can write. Pass User for a narrower credential; the role is capped to your own.expiresInDaysis optional. Omit it and the credential expires 90 days after it is created; pass a larger number for a longer-lived credential (for example, one a recurring automation depends on). Once it expires it stops authenticating and must be re-created — so if a scheduled workflow relies on it, set a lifetime that outlasts the schedule.- The response is the created secret’s metadata. The token itself is never returned — it is sealed in the secret and cannot be read back by anyone, including you. If you need a different scope or role, create a new credential.
A Ronja API credential can’t be used to create another Ronja API credential, and each organization can hold a limited number of them at once — delete an unused credential (delete its secret) before creating a new one if you hit the limit.
The credential’s underlying token appears in your API Tokens list marked Managed by secret, with a link back to the secret. You can’t delete it from there — deleting the secret revokes the token. On the secret’s own page a Ronja API token badge marks it as a self-call credential, and Admins get a View token link to its token.
Once the credential exists, an agent or workflow simply references the secret; Ronja injects the Authorization header automatically, so the token never appears in a prompt or a workflow’s code. Because the credential is scoped, it can only reach the routes those scopes allow — see API reference for the reachability caveat.