Skip to main content

Requests and responses

Every /v1 endpoint follows the same conventions, so once you have handled one resource you have handled them all.

Base URL​

https://api.vehiso.com/v1

All requests use HTTPS. Send JSON request bodies with Content-Type: application/json, except image uploads, which are multipart/form-data.

Response shape​

A single object is returned under data:

{
"data": {
"id": "5f0c6a8e-2d41-4f7b-9a53-1f0e8c2b7d19"
}
}

A list puts the items under data and the paging state under meta:

{
"data": [
{"id": "5f0c6a8e-2d41-4f7b-9a53-1f0e8c2b7d19"},
{"id": "b7e3a1c2-9f4d-4a6e-8c21-7d5b0e9f3a64"}
],
"meta": {
"next_cursor": "eyJpdiI6...",
"has_more": true
}
}

There is no further nesting: fields sit directly on each object. The examples on this page show only the fields relevant to the convention being described; the API reference lists every field.

Ids​

Every id is a UUID string, for example 5f0c6a8e-2d41-4f7b-9a53-1f0e8c2b7d19. Numeric ids never appear in the API. Event ids are prefixed: evt_ followed by a UUID.

Money​

Amounts are objects with an integer amount in minor units (pence for GBP) and an ISO 4217 currency code:

{"amount": 1499500, "currency": "GBP"}

That is £14,995.00. Never use floating point for money: divide by 100 only when displaying it.

In a request body, money is a plain integer in minor units of the dealer's currency. A vehicle's asking price of £14,995.00 is sent as "price": 1499500.

Times and dates​

  • Timestamps are ISO 8601 in UTC with a Z suffix: 2026-09-27T14:02:11Z.
  • Dates without a time are YYYY-MM-DD: 2026-09-27.

Convert to the dealer's local time (Europe/London for UK dealers) only for display.

Errors​

Errors use a consistent body and an appropriate HTTP status:

{
"success": false,
"message": "The request was not valid.",
"code": "validation_failed",
"request_id": "0b7c9d4e-6f1a-4c3b-8e2d-5a9f7b1c3e60",
"errors": {
"email": ["The email field must be a valid email address."]
}
}
FieldDescription
successAlways false on an error.
messageA human-readable explanation. Show it in logs; do not match on it, because the wording may change.
codeA stable, machine-readable string. Branch on this.
request_idThe id of this request. Quote it when you contact support.
errorsPresent on 422 only. Maps each invalid field to a list of messages.

A 404 for an id that does not exist looks like this:

{
"success": false,
"message": "No vehicle was found with that id.",
"code": "not_found",
"request_id": "0b7c9d4e-6f1a-4c3b-8e2d-5a9f7b1c3e60"
}

Status codes​

StatusWhenExample code
200, 201Success.
202Accepted for background processing, for example a batch upload.
204Success with no body.
401The key is missing, invalid, revoked or expired.invalid_api_key
403The key lacks a scope, the plan does not include the API, or an allowlist refused the request.insufficient_scope
404The resource does not exist, or the key cannot see it.not_found
405The method is not allowed on this path.method_not_allowed
409A conflict with the record's current state, or an idempotency key reused with a different body.idempotency_key_reused
413The request body is too large, for example too many image files at once.payload_too_large
422Validation failed. errors says which fields.validation_failed
429Rate limit exceeded. Wait for Retry-After seconds.rate_limited
5xxSomething went wrong on our side. Safe to retry with backoff; use an Idempotency-Key on POSTs.server_error

The authentication and permission codes are listed in Authentication and API keys.

The OAuth endpoints are the one exception to this format. They answer with the standard RFC 6749 body, {"error": "invalid_grant", "error_description": "..."}, because that is what OAuth client libraries expect.

Request ids​

Every response, successful or not, carries an X-Request-Id header. Error bodies repeat it as request_id. Log it alongside your own request logs: the dealer can find the same request in the DMS under Administration > Developers, and support can trace it from the id alone.

HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: 0b7c9d4e-6f1a-4c3b-8e2d-5a9f7b1c3e60
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118

Request bodies are never logged by Vehiso, only the method, path, status and timing.

Reference lists​

Status and type values (vehicle statuses, enquiry statuses, enquiry types, enquiry sources, appointment types and deal statuses) are available from GET /v1/reference/{list}, which works with any scope:

curl https://api.vehiso.com/v1/reference/vehicle-statuses \
-H "Authorization: Bearer $VEHISO_API_KEY"

The lists are vehicle-statuses, enquiry-statuses, enquiry-types, enquiry-sources, appointment-types and deal-statuses. Each code comes with the dealer's own name for it, so use the lists for labels as well. Read them rather than hard-coding values.