Skip to main content
Use Ragic through Corsair: one client, typed API calls. Generate an API key in Ragic under Personal Settings. It goes in Authorization: Basic <key> — the key is the Basic username and the password is empty, and the value is not base64-encoded, because Ragic reads it directly. Four things trip up almost every integration:
  • Every call needs the sheet’s coordinates. A Ragic URL is https://{server}/{account}{path}/{sheetIndex}, so each operation takes account, path and sheetIndex, read straight off the URL you see in the browser. There is no way to address a sheet without them.
  • The server is per account. www.ragic.com is the default; an account on another shard uses na3, ap5, eu2 and so on, and a key only works on its own server. Pass server: 'eu2.ragic.com' when that is where your account lives.
  • A failure arrives as HTTP 200. Ragic reports nearly every error inside the response body — {"status":"ERROR","code":106,"msg":"…"} — including an unrecognised key, a bad sheet index and a server fault. The plugin checks for that envelope and throws, so a refusal can never be mistaken for a record. Note that 106 covers both a missing key and a genuine permission gap: both fall back to the guest account, and the message names which.
  • Records are keyed by row id, not returned as an array. A list answers {"12345": {…}, "12346": {…}}, and each row repeats its id in _ragicId. Field keys are field names by default; pass naming: 'EID' for field IDs.
Writing, in practice:
  • Use schema.get first. A write needs field IDs, and a form’s fields differ per account. schema.get returns them with their types and, for a select field, up to 50 options — but it needs an account manager’s API key, so a non-admin key gets 403 no right.
  • Subtable rows are grouped by row id. On create, give every field of one row the same negative id under _subtable_<id> so Ragic can tell which values belong together. On update, use the positive row id you read from the record. To delete a row, send _DELSUB_<subtableId> with an array of row ids.
  • Dates are yyyy/MM/dd or yyyy/MM/dd HH:mm:ss, in filters and in field values, never ISO 8601.
  • where is a three-part filter. { fieldId, op, value } becomes fieldId,op,value, and several conditions are sent as a repeated where parameter. A comma or % in the value is encoded the way Ragic expects, so pass the value as plain text. Repeated eq/regex/like on one field is an OR; a gte with an lte on one field is a range (AND). Leave value out to match an empty field.
  • A listing returns 1,000 records by default. Set limit explicitly for more, and subtables: false when you do not need them, which makes the response far smaller.
  • Writes run more than the save. Workflows, AI Agents and notifications run by default; doWorkflow: false, doAIAgent: false and notification: false turn them off, and doValidation: true refuses a save that breaks the sheet’s validation rules. checkLock: true refuses to edit a locked record.
  • records.lock / records.unlock map to Ragic’s bare lock / unlock query flag on a POST to the record, and need the same permission as locking in the form. An update with checkLock: true on a locked record fails with code 402; without it Ragic saves the update anyway, so a lock only guards updates that ask for the check.
  • records.delete moves the record to the sheet’s recycle bin, where it can be restored from the Ragic UI. Reading a deleted or unknown id answers an empty object rather than an error.
  • A write answers { status, msg, ragicId, data }: ragicId is the record id and data is the saved record keyed by field ID. A save that breaks a field rule (a required field left empty, a duplicate key) comes back as status: "INVALID" with code 202, and the plugin throws it.
  • records.comment is sent as multipart form data with Ragic’s comment flag, which is the only form the comment route accepts, and answers the new comment keyed by its row id.
  • No rate limit, but a queue. Ragic documents no numeric limit, only a per-account queue of 50 that stops accepting GET requests when full, and a manual review above 5 requests a second. A 429 or body code 204 (“Request Frequency Too High”) is retried up to three times, and a 5xx twice, for reads, lock and unlock only; a create, update, comment or delete is never sent twice, since a 5xx can follow a save that already ran its workflows.
What you get:
  • 9 typed API operations

Setup

1

Install

2

Add the plugin

corsair.ts
With multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.
3

Choose authentication

4

Connect a tenant

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.

Example API calls

List records from a sheet
Create a record
See the full list on the API page.

What’s next

API reference

Every ragic.api.* operation with input and output types.

Connect / OAuth

createLink, Hub delivery, and tenant connect flows.

Use with agents

Expose this plugin’s operations as MCP tools.