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 takesaccount,pathandsheetIndex, 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.comis the default; an account on another shard usesna3,ap5,eu2and so on, and a key only works on its own server. Passserver: '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 that106covers 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; passnaming: 'EID'for field IDs.
- Use
schema.getfirst. A write needs field IDs, and a form’s fields differ per account.schema.getreturns 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 gets403 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/ddoryyyy/MM/dd HH:mm:ss, in filters and in field values, never ISO 8601. whereis a three-part filter.{ fieldId, op, value }becomesfieldId,op,value, and several conditions are sent as a repeatedwhereparameter. A comma or%in the value is encoded the way Ragic expects, so pass the value as plain text. Repeatedeq/regex/likeon one field is an OR; agtewith anlteon one field is a range (AND). Leavevalueout to match an empty field.- A listing returns 1,000 records by default. Set
limitexplicitly for more, andsubtables: falsewhen 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: falseandnotification: falseturn them off, anddoValidation: truerefuses a save that breaks the sheet’s validation rules.checkLock: truerefuses to edit a locked record. records.lock/records.unlockmap to Ragic’s barelock/unlockquery flag on a POST to the record, and need the same permission as locking in the form. An update withcheckLock: trueon a locked record fails with code402; without it Ragic saves the update anyway, so a lock only guards updates that ask for the check.records.deletemoves 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 }:ragicIdis the record id anddatais the saved record keyed by field ID. A save that breaks a field rule (a required field left empty, a duplicate key) comes back asstatus: "INVALID"with code202, and the plugin throws it. records.commentis sent as multipart form data with Ragic’scommentflag, 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
429or body code204(“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.
- 9 typed API operations
Setup
1
Install
2
Add the plugin
corsair.ts
multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.3
Choose authentication
- API Key (Recommended)
No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.More: API Key
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 sheetWhat’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.