Skip to content

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.

All are mounted on a layer of the FeatureServer:

GET|POST …/FeatureServer/{layer}/{oid}/attachments → attachmentInfos
GET …/FeatureServer/{layer}/{oid}/attachments/{attachmentId} → the file bytes
GET|POST …/FeatureServer/{layer}/queryAttachments → attachmentGroups
POST …/FeatureServer/{layer}/{oid}/addAttachment → multipart upload
POST …/FeatureServer/{layer}/{oid}/deleteAttachments → remove by id

queryAttachments 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}

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.

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 original

The nearest available rendition is served; the original is the fallback.

Terminal window
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.
Terminal window
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 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.