HGV Traders Docs

Stock API

Create, update, and manage vehicle listings via the bearer-authenticated stock API.

Overview

Dealer integrations can manage stock programmatically:

MethodPathPurpose
GET/api/v1/stockList org stock (all statuses)
GET/api/v1/stock/{id}Get a single listing
POST/api/v1/stockCreate a draft listing
PATCH/api/v1/stock/{id}Update a listing
POST/api/v1/stock/{id}/publishPublish (subject to plan slot limits)
POST/api/v1/stock/{id}/unpublishRevert to draft
POST/api/v1/stock/{id}/soldMark 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)

FieldCreateUpdateNotes
organisationIdOptional*Optional**Required when user has multiple org memberships
assetClassRequiredOptionalTRUCK, TRAILER, PLANT, VAN
titleRequiredOptional3–200 characters
descriptionOptionalOptionalMax 50,000 characters
conditionOptionalOptionalNEW, USED, REFURBISHED (default USED)
registrationOptionalOptionalMax 20 characters
registrationDateOptionalOptionalISO date
vinOptionalOptionalMax 30 characters
yearOptionalOptional1900 – current year + 1
make, modelOptionalOptionalMax 100 characters each
priceTypeOptionalOptionalFIXED, POA, AUCTION (default FIXED)
pricePenceOptionalOptionalInteger pence (e.g. £45,000 = 4500000)
vatIncludedOptionalOptionalBoolean (default false)
locationCity, locationPostcodeOptionalOptional
imageKeysOptionalOptionalMax 50 image keys — see Image uploads
specsOptionalOptionalKey/value map for structured fields
gvwKgOptionalOptionalGross vehicle weight in kg
featuresOptionalOptionalMax 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" } }
RouteFrom statusTo status
POST …/publishDRAFTPUBLISHED
POST …/unpublishPUBLISHEDDRAFT
POST …/soldPUBLISHEDSOLD

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

  1. Upload photosPOST /api/v1/uploads for each image (Image uploads)
  2. Create draftPOST /api/v1/stock with imageKeys
  3. PublishPOST /api/v1/stock/{id}/publish
  4. Sync changesPATCH for price/details; upload additional photos with optional stockId
  5. Mark soldPOST /api/v1/stock/{id}/sold when the vehicle sells

Webhooks

Publishing, unpublishing, and marking sold trigger outbound webhooks (STOCK_PUBLISHED, etc.). See Webhooks.

Errors

StatusTypical cause
400Invalid body, validation failure, or missing organisationId for multi-org users
401Invalid or missing bearer token
403Publish blocked by slot limit
404Stock not found or wrong organisation
429Write rate limit exceeded

See Errors for the response envelope.