Image uploads
Upload stock photos and attach image keys to listings.
Overview
Most integrations upload photos in one step, then attach the returned image key to a stock listing.
| Step | Action | Auth |
|---|---|---|
| 1 | POST /api/v1/uploads with the image file | Bearer token |
| 2 | Include the returned key in imageKeys on POST or PATCH /api/v1/stock | Bearer token |
See Stock API for create, update, and publish routes.
Allowed formats
| Type | Typical extension |
|---|---|
image/jpeg | .jpg, .jpeg |
image/png | .png |
image/webp | .webp |
image/heic | .heic |
Up to 50 image keys per listing. Direct upload accepts files up to 4MB. Larger files use the presigned upload flow below.
Upload an image
curl -X POST "https://hgvtraders.com/api/v1/uploads" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@front-three-quarter.jpg" \
-F "organisationId=clorg123abc"When adding photos to an existing draft, include stockId:
curl -X POST "https://hgvtraders.com/api/v1/uploads" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@side-view.webp" \
-F "organisationId=clorg123abc" \
-F "stockId=clstk456def"Form fields
| Field | Required | Description |
|---|---|---|
file | Yes | Image binary |
organisationId | When multi-org | Required when the user belongs to more than one organisation — see Accounts |
stockId | No | Omit for new listings; set when uploading to an existing draft |
Response (201 Created)
{
"data": {
"key": "orgs/clorg123abc/temp/1717243200123-a1b2c3d4.jpg"
}
}Store the key — not a public URL. HGV Traders serves images from these keys on the website.
Image key patterns:
- New listing (no
stockId):orgs/{organisationId}/temp/{timestamp}-{uuid}.{ext} - Existing draft (
stockIdset):stock-images/{stockId}/{timestamp}-{uuid}.{ext}
If stockId does not belong to your organisation, the API returns 404.
Attach keys to stock
Pass an ordered array of keys when creating or updating a listing:
{
"title": "2020 DAF XF 530",
"imageKeys": [
"orgs/clorg123abc/temp/1717243200123-a1b2c3d4.jpg",
"orgs/clorg123abc/temp/1717243200999-e5f6g7h8.jpg"
]
}On PATCH, send the complete gallery you want — the array replaces the previous one.
End-to-end example
TOKEN="your_bearer_token"
ORG="clorg123abc"
# 1. Upload photo A
KEY_A=$(curl -s -X POST "https://hgvtraders.com/api/v1/uploads" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@front.jpg" \
-F "organisationId=$ORG" | jq -r '.data.key')
# 2. Upload photo B
KEY_B=$(curl -s -X POST "https://hgvtraders.com/api/v1/uploads" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@rear.jpg" \
-F "organisationId=$ORG" | jq -r '.data.key')
# 3. Create draft listing
curl -X POST "https://hgvtraders.com/api/v1/stock" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"organisationId\": \"$ORG\",
\"assetClass\": \"TRUCK\",
\"title\": \"2020 DAF XF 530\",
\"priceType\": \"FIXED\",
\"pricePence\": 4500000,
\"locationPostcode\": \"M1 1AA\",
\"imageKeys\": [\"$KEY_A\", \"$KEY_B\"]
}"Then publish with POST /api/v1/stock/{id}/publish — see Stock API.
Large files (advanced)
Phone originals and uncompressed HEIC files often exceed the 4MB direct upload limit. When POST /api/v1/uploads returns 413, use the presigned flow:
POST /api/v1/uploads/presignwithfilenameandcontentType(optionalstockId)PUTthe file bytes to the returnedurl— no bearer token on this request; use the sameContent-Typeas presign- Include the returned
keyinimageKeys
# Presign
curl -X POST "https://hgvtraders.com/api/v1/uploads/presign" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"organisationId": "clorg123abc",
"filename": "large-photo.heic",
"contentType": "image/heic"
}'{
"data": {
"url": "https://…upload?signature=…",
"key": "orgs/clorg123abc/temp/1717243200123-a1b2c3d4.heic"
}
}# Upload to presigned URL
curl -X PUT "$PRESIGNED_URL" \
-H "Content-Type: image/heic" \
--data-binary @large-photo.heicThe presigned url expires after 5 minutes. Request a fresh one if the upload fails or times out.
Errors
| Status | Cause |
|---|---|
| 400 | Invalid body, unsupported file type, or missing organisationId for multi-org users |
| 401 | Missing or invalid bearer token |
| 404 | stockId not found or not owned by your organisation |
| 413 | File over 4MB on direct upload — use presign |
| 429 | Write rate limit exceeded — see Rate limits |