Upload a file to a MEDIA Custom Field
This guide shows how to upload a file to a Custom Field of type MEDIA on any DJUST entity (for example: Commercial Order, Logistic Order, Operation, Quote, Product) using a presigned URL flow.
At a glance
- Authenticate
- Read the entity to find the MEDIA CF id
- Request a presigned URL
- PUT the file to that URL
- PATCH the entity with the file URL as the custom field value.
🔑 Prerequisites
- Headers: use the correct surface headers for your endpoint (for admin,
dj-client=OPERATORplusdj-api-key; for shop surfaces,dj-client=ACCOUNTwhere applicable). - Permissions: you must be allowed to read and patch the target entity.
- A MEDIA CF exists on the entity (type
MEDIA, with properties like mediaType, maxSize). - File size and type are within limits (see the Custom Field’s property
maxSize; set a correct Content-Type on upload).
This flow updates a value for an existing custom field. It does not create CF definitions.
🗺️ End-to-end flow
flowchart LR A[🔐 Authenticate]:::node --> B[📦 Read entity<br/>find MEDIA CF id]:::node B --> C[🔗 Request presigned URL<br/>by MEDIA CF id]:::node C --> D[⬆️ PUT file to presigned URL<br/><i>no auth header</i>]:::success D --> E[🧩 PATCH entity<br/>customFieldValues with file URL]:::success %% Styles classDef node fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef success fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; style A rx:8,ry:8 style B rx:8,ry:8 style C rx:8,ry:8 style D rx:8,ry:8 style E rx:8,ry:8
🔐 Authenticate
curl -X POST "$BASE_URL/auth/token" \
-H "Content-Type: application/json" \
-H "dj-api-key: $DJ_API_KEY" \
-H "dj-client: OPERATOR" \
-d '{
"username": "your_username",
"password": "your_password"
}'Response (excerpt)
{ "token": { "accessToken": "eyJhbGciOi..." } }📦 Read the entity and find the MEDIA CF id
curl -X GET "$BASE_URL/v1/{entityPath}/{entityId}" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "dj-client: OPERATOR" \
-H "dj-api-key: $DJ_API_KEY" \
-H "Accept: application/json"Look for a Custom Field with "type": "MEDIA":
{
"customFieldValues": [
{
"customField": {
"id": "0000065247",
"name": { "EN": "CF MEDIA DOC" },
"type": "MEDIA",
"properties": { "mediaType": "DOCUMENT", "maxSize": 11 }
},
"value": null
}
]
}Keep the
customField.id(for example0000065247) - you will need it to request the presigned URL. Also keep the entire original customFieldValues array; you will send all values back on the PATCH.
🔗 Request a presigned upload URL
# fileName is the target name, fileSize in bytes
curl -X POST "$BASE_URL/v1/custom-fields/{mediaCustomFieldId}/media?fileName=document.txt&fileSize=1000" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "dj-client: OPERATOR" \
-H "dj-api-key: $DJ_API_KEY" \
-H "Accept: application/json"Response: a plain URL (Amazon S3 presigned URL), for example
https://document.example.com/fileUpload-1764933402860.txt?Expires=...&Signature=...Presigned URLs expire (typ. 24–48h). Request and upload within that window.
⬆️ Upload the file to the presigned URL
curl -X PUT "$PRESIGNED_URL" \
-H "Content-Type: text/plain" \
--data-binary @"$FILE_PATH"• Do not send auth headers on the presigned URL. • Set the correct
Content-Type(application/pdf,image/png, etc.). • Use--data-binaryfor binary files.
🧩 PATCH the entity with the file URL
Send all custom field values back, replacing only the MEDIA one with the uploaded file URL.
curl -X PATCH "$BASE_URL/v1/{entityPath}/{entityId}" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "dj-client: OPERATOR" \
-H "dj-api-key: $DJ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customFieldValues": [
{ "customFieldId": "AAAAAA1111", "customFieldValue": "foo" },
{ "customFieldId": "0000065247", "customFieldValue": "https://document.example.com/fileUpload-1764933402860.txt?..." },
{ "customFieldId": "BBBBBB2222", "customFieldValue": "bar" }
]
}'Body format rules • Array of
{ customFieldId, customFieldValue }. • Do not include nestedcustomFieldobjects. • For MEDIA,customFieldValueis the full URL you just uploaded to.
✅ Verify
curl -X GET "$BASE_URL/v1/{entityPath}/{entityId}" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "dj-client: OPERATOR" \
-H "dj-api-key: $DJ_API_KEY" \
-H "Accept: application/json"You should now see the MEDIA CF populated with the uploaded URL.
🧯 Troubleshooting
| Symptom or message | Likely cause | Fix |
|---|---|---|
mediaCustomFieldId not found | No MEDIA CF on this entity | Ensure the CF exists and is enabled for the target entity |
| Presigned URL expired | Upload performed too late | Request a new presigned URL and re-upload |
| PATCH fails (invalid parameter) | Wrong body shape (nested customField included) | Send only { customFieldId, customFieldValue } pairs |
| File too large | Exceeds properties.maxSize | Check CF properties and compress or choose a smaller file |
| Upload 403 or signature error | Altered URL or wrong Content-Type | Re-request URL, do not alter query string, set correct content type |
| Upload 4xx when auth header present | Authorization header sent to storage | Remove auth headers on the presigned PUT |
📋 Summary of calls
| Step | Method | Endpoint | Notes |
|---|---|---|---|
| 1 | POST | /auth/token | Get accessToken |
| 2 | GET | /v1/{entityPath}/{entityId} | Find the MEDIA CF id |
| 3 | POST | /v1/custom-fields/{mediaCustomFieldId}/media | Query params: fileName, fileSize |
| 4 | PUT | {presignedUploadUrl} | Upload the file (no auth headers) |
| 5 | PATCH | /v1/{entityPath}/{entityId} | Send all customFieldValues back |
🧠 Implementation tips
- Cache CF metadata client side if you use it often.
- Validate
fileSizebefore requesting the presigned URL. - Timeouts: increase for big files (for example
curl --max-time 300). - Retries: add basic retries on transient network errors.
- Security: handle presigned URLs as temporary secrets and avoid verbose logging.
🔗 API quicklinks
- Read entity -
GET /v1/{entityPath}/{entityId}(Pick the right path for your entity, for example logistic-orders, commercial-orders, operations, quotes, products.) - Get presigned URL for a MEDIA CF -
POST /v1/custom-fields/{mediaCustomFieldId}/media?fileName=...&fileSize=... - Upload to storage -
PUT {presignedUploadUrl}(no auth header) - Patch entity CF values -
PATCH /v1/{entityPath}/{entityId}
Updated 5 days ago
