Attachments
Attach files to any of 6 parent resources: workorders, invoices, quotes, contacts, deals and maintenance contracts. Uploads use a 2-step presigned S3 PUT flow — your bytes go directly from client to S3, Staffify only sees the metadata. Max 25 MB per file.
Endpoints
| Path | Scope |
|---|---|
| POST /attachments | files.write |
| POST /attachments/:id/complete | files.write |
| GET /attachments | files.read |
| GET /attachments/:id | files.read |
| DELETE /attachments/:id | files.write |
Upload flow
# 1. Request a presigned upload URL
curl -X POST https://app.staffifyai.com/api/workspace/v1/attachments \
-H "Authorization: Bearer $STAFFIFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"parent_type": "workorder",
"parent_id": 42,
"file_name": "boiler-before.jpg",
"mime_type": "image/jpeg",
"size_bytes": 348172
}'
# → 201 { id: 123, upload_url: "https://s3...", upload_url_expires_at: "...", status: "pending", ... }
# 2. PUT the file directly to S3 (within 10 minutes)
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/jpeg" \
--data-binary @boiler-before.jpg
# 3. Mark the attachment as uploaded
curl -X POST https://app.staffifyai.com/api/workspace/v1/attachments/123/complete \
-H "Authorization: Bearer $STAFFIFY_API_KEY"
# → 200 { status: "ready", completed_at: "...", ... } + webhook attachment.uploadedSupported parents
| parent_type | Description |
|---|---|
| workorder | Field service work orders (vakman module). |
| invoice | Sales invoices. |
| quote | Sales quotes. |
| contact | CRM contact person. |
| deal | CRM deal. |
| maintenance_contract | Service maintenance contract. |
File limits
- Max file size: 25 MB per attachment.
- Presigned PUT URL is valid for 10 minutes after creation.
- Presigned GET URL (download) is valid for 1 hour.
- Allowed mime_type values:
- image/jpeg · image/png · image/webp · image/heic · image/heif
- application/pdf
- text/plain · text/csv
- xlsx (openxmlformats spreadsheetml) · xls (ms-excel)
- docx (openxmlformats wordprocessingml) · doc (msword)
Lifecycle & status
pending— row created, PUT upload not confirmed yet. No download_url yet.ready—/completesucceeded. download_url is a 1-hour presigned GET. Webhookattachment.uploadedfires.deleted_at— soft-deleted. S3 object stays until GDPR cron removal. Webhookattachment.deletedfires.
Errors
422 INVALID_MIME— mime_type not in the allowed set.422 INVALID_SIZE— size_bytes zero or > 25 MB.404 PARENT_NOT_FOUND— parent_id doesn't exist in this tenant for the given parent_type.409 NOT_UPLOADED—/completecalled but S3 does not have the object yet. Retry after PUT succeeds.503 S3_UNCONFIGURED— the Staffify instance does not have S3 credentials configured. Contact support.