gtable
gtable.appOpen the Studio
REST APIConventions

Conventions

The response envelope, how a record looks on the wire, cursor pagination, strict inputs, writes by field name, and replacing a whole document safely.

The envelope

Success and failure have one shape each, and a list is an object with an array in it:

JSON
{ "data": [], "meta": { "nextCursor": null, "hasMore": false } }
JSON
{ "error": { "code": "validation_failed", "message": "…", "details": {} } }

Switch on error.code, never on the message. See Errors.

Records on the wire

A record is keyed by field id, because an id survives a rename and a name does not. The id-to-name map travels with every list, in meta.fields: use it to show a name, never to key on one.

JSON
{
  "data": [{ "id": "rec_4nqw8e2hzk7s", "created_at": "2026-09-05T16:53:39.058Z", "fld_dd7kbtsjuhdc": "First record", "fld_jx99fwfvhv3x": 42 }],
  "meta": { "hasMore": false, "nextCursor": null, "fields": { "fld_dd7kbtsjuhdc": "Name", "fld_jx99fwfvhv3x": "Margin" } }
}

Anything that points at a record or a person reads back with both halves, so nobody needs a second request to show it:

Field typeReads back asWritten as
link[{ "id", "label" }], the label being the linked record’s primary fieldids, or the same objects
user, created by, modified by[{ "id", "label" }], the label being a name or an emailids
attachment[{ "id", "name", "size", "mime", "url", … }]the descriptor an upload returned

Two values catch people: a percent holds the fraction (0.15 is 15%), and a duration holds milliseconds (one hour is 3600000). A select holds an option id, which is what lets its label be renamed. Dates are ISO 8601 in UTC.

Writing by name

On records.create and records.update, a key may be a field’s id or its exact name, resolved before anything is stored. A key that is neither is refused with a 422 that names it, so a typo is loud rather than an empty row. id and created_at are ignored, so echoing a record back is safe.

Email, URL and phone fields keep the text you send. A suspect format is still saved, and the response lists it under warnings (code: "suspect_format"). A warning is a successful save: do not retry it.

Pagination

Opaque cursors, limit capped at 200, never offsets: an offset over a table people are writing to skips and repeats rows silently. Pass meta.nextCursor back as cursor until meta.hasMore is false. A cursor the list did not give out is a 422, not a silent restart.

HTTP
GET /v1/tables/tbl_8fj3kq2wmv5d/records?limit=100
GET /v1/tables/tbl_8fj3kq2wmv5d/records?limit=100&cursor=eyJ…

Lists that are short by nature (a record’s comments, a page’s versions, your views of a table) take a limit and have no cursor; the reference says which.

Inputs are strict

An unknown query parameter or body key is a 422 that names it, never silently ignored. A limit must be a whole number written in digits.

Replacing a whole document

A permission document, one group’s permissions and a page’s code are replaced whole. Reading one gives you its revision (or a page’s version); send it back as baseRevision (or baseVersion) and a save made after somebody else changed it is refused with 409 instead of erasing their change. Without it, the last write wins. records.update takes an optional baseVersion too: the changesetId of the last write you saw on that record.

Deleting

Deleting an organisation, a suite, an app, a table or a field takes its current name as ?confirm=, the same proof the Studio asks a person to type; closing an account takes its email address. A call without it is refused and deletes nothing.

HTTP
DELETE /v1/apps/{appId}/tables/{tableId}?confirm=Old%20deals

Deleting a table or a field is also refused, with the list of what reads it (rules, views, pages, other fields), until you send acknowledge=true.

Use these docs with your AI tools

An AI agent can read this documentation directly. You do not need an account or an API key. Everything here is public and read-only.

Query these docs via MCP

Recommended

Add this server to Claude, Claude Code, Cursor, Mistral, or any tool that supports MCP. Your agent can then search gtable documentation and read it in full, instead of answering from memory.

https://gtable.app/docs/mcp
  • searchFind the passages that answer a question.
  • fetchRead one page in full, as Markdown.
  • list_pagesSee every page in this documentation.

Query these docs over HTTP

The same tools also work as plain web requests. Use this for scripts, or for any tool that does not support MCP. There is one endpoint per tool. Arguments go in the query string, and the answer comes back as JSON.

https://gtable.app/docs/api/docs/search?query=custom+domain

Read the OpenAPI description. It is built from the same definitions as the tools, so it always matches what the endpoints do.

Read these docs as Markdown

Add .md to any page URL to get its Markdown source. You can also send the headerAccept: text/markdown to the page URL itself.

To read the whole documentation in one file, open llms-full.txt. For a short index of every page, open llms.txt.