Attachments
Attachment cells in Airtable and NocoDB are exposed through the standard Esri attachment endpoints, so any client that already supports attachments on a feature layer works unchanged. Each sync downloads every attachment (and its thumbnails) into the cache and rewrites the cell’s URLs to point at this server, so files stay available even when the upstream URL expires — Airtable’s do, after a few hours.
Endpoints
Section titled “Endpoints”All are mounted on a layer of the FeatureServer:
GET|POST …/FeatureServer/{layer}/{oid}/attachments → attachmentInfosGET …/FeatureServer/{layer}/{oid}/attachments/{attachmentId} → the file bytesGET|POST …/FeatureServer/{layer}/queryAttachments → attachmentGroupsPOST …/FeatureServer/{layer}/{oid}/addAttachment → multipart uploadPOST …/FeatureServer/{layer}/{oid}/deleteAttachments → remove by idqueryAttachments accepts objectIds, globalIds, attachmentTypes, returnUrl and size.
updateAttachment is deliberately not supported — replace by adding the new file and
deleting the old one, which is what the underlying providers actually do anyway.
There’s also a direct path to a cached file, which is what the rewritten cell URLs point at:
GET /api/v0/{baseId}/attachments/{filename}Attachment ids
Section titled “Attachment ids”Esri clients require integer attachment ids; providers use strings. The served id is the same 31-bit hash used for OBJECTIDs, applied to the provider’s attachment id, and is reversed by re-hashing the record’s current attachment array on each request — no extra state to keep in sync, but also no meaning outside the current contents of that record.
Thumbnails
Section titled “Thumbnails”Where the provider generated renditions, they’re cached too. Add w= to a file request to pick
one:
…/attachments/1024?w=128 → the small rendition…/attachments/1024?w=2000 → the full-size originalThe nearest available rendition is served; the original is the fallback.
Adding a file
Section titled “Adding a file”curl -X POST '…/FeatureServer/0/recAbC123/addAttachment' \ -H 'Authorization: Bearer ims_…' \ -F 'attachment=@site-photo.jpg'- Needs write access to the base.
- 5 MB per file. A larger upload gets a
413. - A table with several attachment fields writes to the first one unless you pass
fieldName. - The upload goes to the provider, the cache is updated, and the change is logged and broadcast like any other edit.
Deleting
Section titled “Deleting”curl -X POST '…/FeatureServer/0/recAbC123/deleteAttachments' \ -H 'Authorization: Bearer ims_…' \ -F 'attachmentIds=1024,1025'Deletes are applied by writing back the surviving ids, which is how the providers model it.
Provider support
Section titled “Provider support”| Provider | Read | Add / delete |
|---|---|---|
| Airtable | ✅ | ✅ |
| NocoDB | ✅ | ❌ (read-only adapter) |
| Everything else | — | — |
A base whose provider has no attachment adapter advertises hasAttachments: false and returns
Esri’s “not supported” error on an edit, rather than accepting a write that would go nowhere.