Datasets API
Read and write an agent's dataset rows from external code using scoped API keys and a PostgREST-style REST API.
New to the API? Read the API Overview first — it covers the base URL, authentication, scopes, the response envelope, error codes, and key management that apply to every endpoint below.
Overview
The Datasets API exposes your agent's datasets over a small, REST-standard HTTP interface. It uses the same scoped API keys and PostgREST-style query syntax described in the API Overview, and reuses the exact same permission checks, plan limits, and validation as the agent itself.
All paths are relative to the base URL https://communa.io/api/v1, and every request sends a Authorization: Bearer header. Remember to call the API from a server-side proxy — never directly from the browser (why).
API reference
| Method | Path | Scope | Description |
|---|---|---|---|
GET | /datasets | datasets:read | List datasets the key's agent owns |
GET | /datasets/{captureId}/rows | datasets:read | Query rows (filter, sort, paginate) |
POST | /datasets/{captureId}/rows | datasets:write | Insert one or more rows |
PATCH | /datasets/{captureId}/rows | datasets:write | Bulk-update rows matching a condition |
DELETE | /datasets/{captureId}/rows | datasets:write | Bulk-delete rows by ID |
GET | /datasets/{captureId}/rows/{rowId} | datasets:read | Fetch a single row |
PATCH | /datasets/{captureId}/rows/{rowId} | datasets:write | Update a single row |
DELETE | /datasets/{captureId}/rows/{rowId} | datasets:write | Delete a single row |
Endpoints
List datasets
GET /datasets
Returns the datasets the key's agent owns. Requires datasets:read.
curl https://communa.io/api/v1/datasets \ -H "Authorization: Bearer $COMMUNA_API_KEY"
Response
json{ "data": [ { "id": "abc123", "name": "Leads", "row_count": 42 } ] }
Query rows
GET /datasets/{captureId}/rows
Requires datasets:read. Supports a PostgREST-style query string:
| Param | Example | Meaning |
|---|---|---|
select | ?select=name,status | Return only these columns |
| filter | ?amount=gte.100&status=eq.active | {field}={op}.{value} |
search | ?search=acme | Free-text across all columns |
order | ?order=created_at.desc | Sort (field.asc / field.desc) |
limit / offset | ?limit=50&offset=100 | Pagination — limit 1–1000, offset ≥ 0 |
distinct | ?distinct=status | Distinct values + counts (filter dropdowns) |
Filter operators: eq, neq, gt, gte, lt, lte, contains, starts_with (like/ilike are accepted as aliases for contains).
Sorting is type-aware: ?order=amount.asc sorts numeric columns numerically (75, 150, 1200) and text columns alphabetically — you don't need a numeric filter present for numeric ordering. Sorting by created_at/updated_at/row_index uses the row's metadata.
Pagination is strict: a limit outside 1–1000, a negative offset, or a non-integer value returns 400 invalid_query rather than being silently clamped.
curl "https://communa.io/api/v1/datasets/abc123/rows?status=eq.active&amount=gte.100&select=name,amount&order=amount.desc&limit=20" \ -H "Authorization: Bearer $COMMUNA_API_KEY"
Response
json{ "data": { "rows": [ { "id": "r1", "name": "Acme", "amount": 1200 } ], "total": 1, "columns": ["name","amount"] } }
Insert rows
POST /datasets/{captureId}/rows
Requires datasets:write. Respects the agent's dataset row plan limit.
curl -X POST https://communa.io/api/v1/datasets/abc123/rows \ -H "Authorization: Bearer $COMMUNA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "rows": [ { "name": "Acme", "status": "active" } ] }'
Response
json{ "data": { "inserted": 1, "rows": [ { "id": "r9", "name": "Acme", "status": "active" } ] } }
Update rows (bulk)
PATCH /datasets/{captureId}/rows
Requires datasets:write. Updates all rows matching every where condition. Omit where to update all rows. The API builds and validates the SQL server-side — raw SQL is never accepted from the caller.
curl -X PATCH https://communa.io/api/v1/datasets/abc123/rows \ -H "Authorization: Bearer $COMMUNA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "where": { "status": "pending" }, "set": { "status": "active" } }'
Response
json{ "data": { "updated": 7 } }
Delete rows (bulk)
DELETE /datasets/{captureId}/rows
Requires datasets:write. Get row IDs from a GET query (each row includes its id).
curl -X DELETE https://communa.io/api/v1/datasets/abc123/rows \ -H "Authorization: Bearer $COMMUNA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "row_ids": ["r1", "r2"] }'
Response
json{ "data": { "deleted": 2 } }
Single row operations
Rows are a sub-resource of a dataset, so a single row has its own REST URL with both IDs — the dataset captureId (which scopes authorization) and the rowId (which identifies the row):
GET /datasets/{captureId}/rows/{rowId}
PATCH /datasets/{captureId}/rows/{rowId}
DELETE /datasets/{captureId}/rows/{rowId}
This is the right choice when your dashboard already knows the row's id (e.g. a user clicks Edit or Delete on one row). For changing many rows at once by a condition, use the bulk collection endpoints above.
Fetch one row
GET /datasets/{captureId}/rows/{rowId}
Requires datasets:read. Returns the single row { id, row_index, ...fields }, or 404 if it doesn't exist in this dataset.
curl https://communa.io/api/v1/datasets/abc123/rows/r1 \ -H "Authorization: Bearer $COMMUNA_API_KEY"
Response
json{ "data": { "id": "r1", "row_index": 0, "name": "Acme", "status": "active" } }
Update one row
PATCH /datasets/{captureId}/rows/{rowId}
Requires datasets:write. The rowId in the path is the scope — no where body. Returns 404 row_not_found if the row doesn't exist in this dataset.
curl -X PATCH https://communa.io/api/v1/datasets/abc123/rows/r1 \ -H "Authorization: Bearer $COMMUNA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "set": { "status": "active", "notes": "Reviewed" } }'
Response
json{ "data": { "id": "r1", "status": "active", "notes": "Reviewed" } }
Delete one row
DELETE /datasets/{captureId}/rows/{rowId}
Requires datasets:write. Returns { "data": { "deleted": true, "id": "<uuid>" } }, or 404 row_not_found if the row didn't exist.
curl -X DELETE https://communa.io/api/v1/datasets/abc123/rows/r1 \ -H "Authorization: Bearer $COMMUNA_API_KEY"
Response
json{ "data": { "deleted": true, "id": "r1" } }
An invalid (non-UUID) rowId returns 400 invalid_row_id.
Response shape
Row queries return a consistent { rows, total, columns } shape, where total is the number of rows matching your query (filter/search aware):
json{ "data": { "rows": [ ... ], "total": 42, "columns": ["name","status"] } }
A distinct query instead returns { values, total_unique, ... }. For the full success/error envelope and error codes, see the API Overview.
What's Next?
- API Overview — Auth, scopes, errors, and key management
- Datasets — How datasets are created and managed in the UI