Sales order attachments — External V1 API
The External V1 API exposes four endpoints for managing files attached to a sales order. These follow the same snake_case conventions as the rest of the External V1 surface and use the same RBAC permissions as the in-app Attachments tab.
Feature flag: All four endpoints return
404while the sales order attachments feature is not yet enabled for your tenant. Contact your Luminous account team to enable it.
Authentication and permissions
All requests must use a valid External API bearer token. The token's associated user must hold:
salesOrders.read— to list or download attachments.salesOrders.update— to upload or delete attachments.
Endpoints
List attachments
GET /external/api/v1/sales-orders/{salesOrderId}/attachments
Returns an array of attachment objects for the order, newest first.
Response body (array of objects):
[
{
"id": 42,
"original_filename": "customer-po.pdf",
"mime_type": "application/pdf",
"size_bytes": 204800,
"uploaded_by": {
"id": 7,
"name": "Jane Smith"
},
"created_at": "2026-08-15T09:30:00+00:00"
}
]
No download URL is included in the list response. Fetch the file bytes through the
/downloadendpoint below — it streams over the authenticated connection and never expires.
Upload an attachment
POST /external/api/v1/sales-orders/{salesOrderId}/attachments
Content-Type: multipart/form-data
| Field | Type | Required | Notes |
|---|---|---|---|
file | Binary file | Yes | Must be an allowed type; maximum 20 MB |
Allowed types: PDF, PNG, JPG/JPEG, GIF, WEBP, DOC, DOCX, XLS, XLSX, CSV, TXT.
Success response (201): The newly created attachment object (same shape as the list item above).
Error responses:
400— file missing, invalid, over the 20 MB limit, or unsupported type. Theerrorfield describes the reason.404— sales order not found, or the feature is not enabled.403— insufficient permissions.
Upload actions are recorded on the order's activity log.
Download a file
GET /external/api/v1/sales-orders/{salesOrderId}/attachments/{attachmentId}/download
Streams the raw file bytes directly over the authenticated connection. The Content-Type header reflects the stored MIME type; the Content-Disposition header carries the original filename.
Because this is a streamed response (not a redirect to a pre-signed URL), the link never expires and works reliably in automation.
Delete an attachment
DELETE /external/api/v1/sales-orders/{salesOrderId}/attachments/{attachmentId}
Success response (200):
{ "message": "Attachment deleted." }
Deletion removes the stored file permanently and is recorded on the order's activity log.
Error envelope
All error responses follow the standard External V1 shape:
{ "error": "<human-readable message>" }
Typical integration workflow
- Read —
GET .../attachmentsafter creating or updating a sales order to discover any documents already attached. - Write —
POST .../attachments(multipart) to attach a generated PDF (e.g. a confirmation or packing note from your upstream system). - Sync —
GET .../attachments/{id}/downloadto pull a copy into your ERP or document store. - Clean up —
DELETE .../attachments/{id}to remove superseded versions before re-uploading.