Form with file
Create a form with file fields and upload/download attachments without exposing storage paths. This page continues from Forms — same Field Snapshot template field UUID for the site-photo file field.
- Ensure a form configuration defines file fields (including
maxFileswhenmultipleis true) — see Form configuration POST /v0/formswith those fields as[]— captureformId— see Forms example create payload (e4f5a6b7-c8d9-4e12-a345-67890abcdef0:[])POST /v0/media/forms/{formId}/attachments— multipart upload (example below)
EnforcesmaxFilesandforms.attachments.uploadPerDayGET /v0/forms/{formId}— file fields become descriptors (fieldId,partKey,contentType,bytes,filename)GET /v0/media/forms/{formId}/attachments/{partKey}— raw bytes- Optional:
DELETE .../attachments/{partKey}?fieldId=...
Optional workflow query params on Media routes: pass workflowConfigurationId and workflowViewId together when required by your process.
Example attachment upload
Section titled “Example attachment upload”After create, upload binaries with multipart/form-data. Parts are paired by position: each fieldIds entry matches the files part at the same index (same length, same order).
For the Field Snapshot template, the file field id is e4f5a6b7-c8d9-4e12-a345-67890abcdef0 (config allows up to maxFiles: 3).
One file
curl -X POST "https://<api-gateway-server-url>/v0/media/forms/<formId>/attachments" \ -H "Authorization: Bearer <session-token>" \ -H "<license-key-header>: <license-key>" \ -F "fieldIds=e4f5a6b7-c8d9-4e12-a345-67890abcdef0" \ -F "files=@./site-photo-1.jpg;type=image/jpeg"Two files on the same field (repeat both part names; order must align)
curl -X POST "https://<api-gateway-server-url>/v0/media/forms/<formId>/attachments" \ -H "Authorization: Bearer <session-token>" \ -H "<license-key-header>: <license-key>" \ -F "fieldIds=e4f5a6b7-c8d9-4e12-a345-67890abcdef0" \ -F "files=@./site-photo-1.jpg;type=image/jpeg" \ -F "fieldIds=e4f5a6b7-c8d9-4e12-a345-67890abcdef0" \ -F "files=@./site-photo-2.jpg;type=image/jpeg"Files across multiple file fields (same request; each pair targets a different field UUID)
When the configuration has more than one type: "file" field, include every attachment in one multipart call by pairing each file with its own fieldIds value. Below, the first two parts attach to the site-photo field; the third attaches to a second file field (replace <second-file-field-id> with that field’s UUID from your configuration — and ensure create/update set both file fields to []).
curl -X POST "https://<api-gateway-server-url>/v0/media/forms/<formId>/attachments" \ -H "Authorization: Bearer <session-token>" \ -H "<license-key-header>: <license-key>" \ -F "fieldIds=e4f5a6b7-c8d9-4e12-a345-67890abcdef0" \ -F "files=@./site-photo-1.jpg;type=image/jpeg" \ -F "fieldIds=e4f5a6b7-c8d9-4e12-a345-67890abcdef0" \ -F "files=@./site-photo-2.jpg;type=image/jpeg" \ -F "fieldIds=<second-file-field-id>" \ -F "files=@./site-sketch.pdf;type=application/pdf"Index pairing for that call:
| Index | fieldIds |
files |
|---|---|---|
| 0 | site-photo field UUID | site-photo-1.jpg |
| 1 | site-photo field UUID | site-photo-2.jpg |
| 2 | second file field UUID | site-sketch.pdf |
Each field still respects its own file.accept, maxBytes, and maxFiles.
| Multipart part | Type | Purpose |
|---|---|---|
fieldIds |
text (repeatable) | Form field UUID for the paired file |
files |
file (repeatable) | Binary bytes; non-empty; MIME should match the field’s file.accept |
Do not put file bytes in POST / PATCH /v0/forms. JSON keeps file fields as []; Media owns the binaries.
After a successful upload, GET /v0/forms/{formId} returns descriptors on that field (including opaque partKeys). Use those for download/delete — never storage paths.
Full media model: Media uploads. Next in the series for review processes: Workflow configuration.