Stock API
Create, update, and manage vehicle listings via the bearer-authenticated stock API.
Overview
Dealer integrations can manage stock programmatically:
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/stock | List org stock (all statuses) |
GET | /api/v1/stock/{id} | Get a single listing |
POST | /api/v1/stock | Create a draft listing |
PATCH | /api/v1/stock/{id} | Update a listing |
POST | /api/v1/stock/{id}/publish | Publish (subject to plan slot limits) |
POST | /api/v1/stock/{id}/unpublish | Revert to draft |
POST | /api/v1/stock/{id}/sold | Mark as sold |
All routes require bearer authentication. Pass organisationId when the user belongs to multiple organisations — see Accounts.
Write routes share a 120 requests/minute per-user limit — see Rate limits.
Image uploads
Photos use image keys in the imageKeys array — not public URLs. Upload with POST /api/v1/uploads, then attach keys on create/update.
See Image uploads for the upload request, key patterns, and the presigned fallback for files over 4MB.
Request fields (create / update)
| Field | Create | Update | Notes |
|---|---|---|---|
organisationId | Optional* | Optional* | *Required when user has multiple org memberships |
assetClass | Required | Optional | TRUCK, TRAILER, PLANT, VAN |
title | Required | Optional | 3–200 characters |
description | Optional | Optional | Max 50,000 characters |
condition | Optional | Optional | NEW, USED, REFURBISHED (default USED) |
registration | Optional | Optional | Max 20 characters |
registrationDate | Optional | Optional | ISO date |
vin | Optional | Optional | Max 30 characters |
year | Optional | Optional | 1900 – current year + 1 |
make, model | Optional | Optional | Max 100 characters each |
priceType | Optional | Optional | FIXED, POA, AUCTION (default FIXED) |
pricePence | Optional | Optional | Integer pence (e.g. £45,000 = 4500000) |
vatIncluded | Optional | Optional | Boolean (default false) |
locationCity, locationPostcode | Optional | Optional | |
imageKeys | Optional | Optional | Max 50 image keys — see Image uploads |
specs | Optional | Optional | Key/value map for structured fields |
gvwKg | Optional | Optional | Gross vehicle weight in kg |
features | Optional | Optional | Max 100 strings |
New listings are always created in DRAFT status.
List stock
curl "https://hgvtraders.com/api/v1/stock?status=PUBLISHED&page=1&limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"With multiple org memberships:
curl "https://hgvtraders.com/api/v1/stock?organisationId=clorg123abc&status=DRAFT" \
-H "Authorization: Bearer YOUR_TOKEN"{
"data": {
"stock": [
{
"id": "clstk456def",
"slug": "2020-daf-xf-530",
"organisationId": "clorg123abc",
"assetClass": "TRUCK",
"title": "2020 DAF XF 530",
"status": "PUBLISHED",
"priceType": "FIXED",
"pricePence": 4500000,
"locationPostcode": "M1 1AA",
"imageKeys": ["stock-images/clstk456def/1717243200123-a1b2c3.jpg"],
"publishedAt": "2024-06-01T10:00:00.000Z",
"createdAt": "2024-05-28T14:30:00.000Z",
"updatedAt": "2024-06-01T10:00:00.000Z"
}
],
"total": 42,
"page": 1,
"pages": 3
}
}Filter by status: DRAFT, PUBLISHED, or SOLD. Pagination matches Pagination (page, limit max 100).
Get a single listing
curl "https://hgvtraders.com/api/v1/stock/clstk456def?organisationId=clorg123abc" \
-H "Authorization: Bearer YOUR_TOKEN"{
"data": {
"id": "clstk456def",
"slug": "2020-daf-xf-530",
"title": "2020 DAF XF 530",
"status": "DRAFT",
"assetClass": "TRUCK",
"description": "One owner, full service history.",
"priceType": "FIXED",
"pricePence": 4500000,
"vatIncluded": false,
"imageKeys": ["orgs/clorg123abc/temp/1717243200123-a1b2c3.jpg"],
"specs": { "axleConfig": "6x2" },
"features": ["Air conditioning", "Lane assist"],
"createdAt": "2024-05-28T14:30:00.000Z",
"updatedAt": "2024-05-28T14:30:00.000Z"
}
}Returns 404 if the ID does not exist or belongs to another organisation.
Create a draft
curl -X POST "https://hgvtraders.com/api/v1/stock" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"organisationId": "clorg123abc",
"assetClass": "TRUCK",
"title": "2020 DAF XF 530",
"description": "One owner, full service history.",
"condition": "USED",
"registration": "AB12 CDE",
"year": 2020,
"make": "DAF",
"model": "XF 530",
"priceType": "FIXED",
"pricePence": 4500000,
"vatIncluded": false,
"locationCity": "Manchester",
"locationPostcode": "M1 1AA",
"imageKeys": [
"orgs/clorg123abc/temp/1717243200123-a1b2c3.jpg"
],
"features": ["Air conditioning"]
}'Response (201 Created):
{
"data": {
"id": "clstk456def",
"slug": "2020-daf-xf-530",
"status": "DRAFT",
"title": "2020 DAF XF 530",
"imageKeys": ["orgs/clorg123abc/temp/1717243200123-a1b2c3.jpg"]
}
}Save the returned id for publish and for presigning additional photos with stockId.
Update a listing
Send only fields you want to change. To reorder or replace photos, send the full imageKeys array:
curl -X PATCH "https://hgvtraders.com/api/v1/stock/clstk456def" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"organisationId": "clorg123abc",
"pricePence": 4350000,
"imageKeys": [
"stock-images/clstk456def/1717243200123-a1b2c3.jpg",
"stock-images/clstk456def/1717243200999-d4e5f6.jpg"
]
}'{
"data": {
"id": "clstk456def",
"status": "DRAFT",
"pricePence": 4350000,
"imageKeys": [
"stock-images/clstk456def/1717243200123-a1b2c3.jpg",
"stock-images/clstk456def/1717243200999-d4e5f6.jpg"
]
}
}Publish, unpublish, and sold
Status transitions use dedicated POST sub-routes. The body may include organisationId for multi-org users:
curl -X POST "https://hgvtraders.com/api/v1/stock/clstk456def/publish" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "organisationId": "clorg123abc" }'Success:
{ "data": { "id": "clstk456def" } }| Route | From status | To status |
|---|---|---|
POST …/publish | DRAFT | PUBLISHED |
POST …/unpublish | PUBLISHED | DRAFT |
POST …/sold | PUBLISHED | SOLD |
Publish slot limits: non-admin publishes are capped by your plan's stock slot limit (free tier: 3 published listings). When the limit is reached:
{ "error": "Slot limit reached" }HTTP status 403. Only DRAFT listings can be published:
{ "error": "Only draft listings can be published" }Typical integration flow
- Upload photos —
POST /api/v1/uploadsfor each image (Image uploads) - Create draft —
POST /api/v1/stockwithimageKeys - Publish —
POST /api/v1/stock/{id}/publish - Sync changes —
PATCHfor price/details; upload additional photos with optionalstockId - Mark sold —
POST /api/v1/stock/{id}/soldwhen the vehicle sells
Webhooks
Publishing, unpublishing, and marking sold trigger outbound webhooks (STOCK_PUBLISHED, etc.). See Webhooks.
Errors
| Status | Typical cause |
|---|---|
| 400 | Invalid body, validation failure, or missing organisationId for multi-org users |
| 401 | Invalid or missing bearer token |
| 403 | Publish blocked by slot limit |
| 404 | Stock not found or wrong organisation |
| 429 | Write rate limit exceeded |
See Errors for the response envelope.