REST API
Updated 31 July 2026 · 9 min read
On this page
The API exposes your sheets for reading and writing. Payloads follow the shape of the Airtable API: an integration written for Airtable transposes without relearning anything.
Base URL: https://rowbase.co/api/v1
Authenticate
Create a token from API tokens, in the sidebar. Administrators only. You tick the tables it can reach; it sees nothing else. The secret is shown once.
Authorization: Bearer rowb_…
With no header, the response is 401 AUTHENTICATION_REQUIRED. With a revoked or unknown token, 401 INVALID_API_KEY. With a table outside the token's scope, 403 NOT_AUTHORIZED.
Throughput is capped at thirty calls per second per token. Past that, the response is 429 RATE_LIMIT_REACHED; its Retry-After header says how long to wait, and the message repeats it.
List the tables
GET /api/v1/tables
Returns the token's tables, their sheets, and each sheet's columns. This is where you read the identifiers used by the other calls.
{
"tables": [
{
"id": "table_k2m9x4qp7v1c",
"slug": "lar",
"name": "LAR",
"sheets": [
{
"id": "sheet_b8n3r6wz5t2j",
"slug": "sheet-1",
"name": "Sheet 1",
"fields": [
{ "id": "fld20", "name": "ID", "type": "text" },
{ "id": "fld23", "name": "Email", "type": "email" }
]
}
]
}
]
}
A table and a sheet each carry a fixed identifier, table_… and sheet_…. Drawn at random on creation, it never changes. Prefer it in a script you intend to keep: a slug follows the name it comes from, so renaming a table changes its slug.
Both are shown in the grid, under Use this sheet from the API.
Addressing by slug or by numeric identifier still works, and will keep working. An integration written before these identifiers existed has nothing to change.
List records
GET /api/v1/tables/{table}/{sheet}/records
{
"records": [
{
"id": "0c8f2b16-1f3e-4a91-9a0c-2b7d0f5c8ab1",
"createdTime": "2026-07-27T00:06:46.000Z",
"fields": { "ID": "…", "Website": "lettre-ar.com" }
}
],
"offset": "100"
}
A record's identifier is a UUID, unrelated to its position or to the internal key. Cells are keyed by column name; an empty cell is absent from the payload.
| Parameter | Effect |
|---|---|
pageSize |
Records per page, 100 at most and by default |
offset |
Resumes at the next page, returned while more remain |
maxRecords |
Caps the total returned |
fields[] |
Returns only these columns, by name or by fld… |
sort[0][field], sort[0][direction] |
Sorts on a column, asc or desc |
returnFieldsByFieldId |
Keys cells by fld… rather than by name |
filterByFormula and view do not exist: Rowbase has neither formulas nor views.
Read one record
GET /api/v1/tables/{table}/{sheet}/records/{recordId}
Create records
POST /api/v1/tables/{table}/{sheet}/records
A single row:
{ "fields": { "ID": "abc", "Website": "lettre-ar.com" } }
Or up to ten at once:
{ "records": [ { "fields": { "ID": "abc" } }, { "fields": { "ID": "def" } } ] }
The response mirrors the request: an object for the single form, a records array for the batch form.
Values are converted according to the column's type, just like typing in the grid. An unknown column name returns 422 UNKNOWN_FIELD_NAME, and nothing is written.
A row created through the API triggers the sheet's Google Sheets syncs, exactly like data entered by hand.
Update records
PATCH /api/v1/tables/{table}/{sheet}/records
{ "records": [ { "id": "0c8f2b16-…", "fields": { "Website": "example.com" } } ] }
PATCH only touches the cells you send. PUT replaces the row: cells you leave out are cleared.
An update through the API rewrites the row in Google Sheets, just like an edit made in the grid.
Delete records
DELETE /api/v1/tables/{table}/{sheet}/records?records[]=0c8f2b16-…
{ "records": [ { "id": "0c8f2b16-…", "deleted": true } ] }
Ten records at most per call.
Errors
Every error has the same shape:
{ "error": { "type": "UNKNOWN_FIELD_NAME", "message": "Unknown field “Nope”." } }
| Type | Code | When |
|---|---|---|
AUTHENTICATION_REQUIRED |
401 | No Authorization header |
INVALID_API_KEY |
401 | Unknown or revoked token |
NOT_AUTHORIZED |
403 | Table outside the token's scope |
TABLE_NOT_FOUND, SHEET_NOT_FOUND, ROW_NOT_FOUND |
404 | Unknown identifier |
UNKNOWN_FIELD_NAME |
422 | Column name not on the sheet |
TOO_MANY_RECORDS |
422 | More than ten records in one call |
INVALID_REQUEST_BODY |
422 | Malformed body |
RATE_LIMIT_REACHED |
429 | More than thirty calls per second |
Full example
curl -X POST https://rowbase.co/api/v1/tables/table_k2m9x4qp7v1c/sheet_b8n3r6wz5t2j/records \
-H "Authorization: Bearer rowb_…" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"ID": "Cj0KCQjw4a3OBhCHARIsAChaq",
"Date": "2026-04-01 02:35:53",
"Website": "lettre-ar.com",
"Email": "[email protected]"
}
}'