Caravan Guide API Docs
Navigation - Endpoints

Endpoints

All endpoints are prefixed with https://caravanguide.co.uk/api/v1/. All responses are JSON. Pagination uses page and limit query parameters unless otherwise noted.

Health

No authentication required. Suitable for uptime monitors and load balancers.

GET /api/v1/health

Returns the current platform status with a database connectivity check. Returns HTTP 200 when healthy and 503 when degraded.

Response

{
  "status": "ok",
  "timestamp": "2026-04-13T12:00:00Z",
  "version": "v1",
  "checks": {
    "database": "ok",
    "platform": "operational"
  }
}
FieldValuesDescription
statusok | degradedOverall platform health
checks.databaseok | errorDatabase connectivity
checks.platformoperational | disabledAPI platform kill-switch state

A 503 response body uses the same shape as above with "status": "degraded". The HEAD method is also supported for lightweight polling.

Valuations

Requires scope: valuations:read

Partner catalogue workflow

Use these endpoints together to power partner search forms with cascading dropdowns, individual field pre-fill, and valuations.

Typical integration flow

  1. Bootstrap on page load when you already have partial listing data (from your URL, CRM, or ad feed):
    GET /valuations/catalog?bootstrap=1&caravan_type=static&manufacturer=Swift&model_name=Bordeaux&model_year=2017
  2. Step calls on user interaction when the user changes one dropdown:
    GET /valuations/catalog?step=models&caravan_type=static&manufacturer=Swift
  3. Resolve alias names when listing text may not match the published catalogue exactly:
    GET /valuations/resolve?manufacturer=…&model_name=…&model_year=2017
  4. Search for prices once selection is complete (use canonical values from catalogue selection or resolve):
    GET /valuations/search?manufacturer=Swift&model_name=Bordeaux&model_year=2017

Cascade order and parent parameters

StepRequired parent paramsReturns
caravan_types-Available caravan types in the published edition
manufacturerscaravan_type (optional, default static)Manufacturer names
modelsmanufacturerModel names (includes active alias mappings)
yearsmanufacturer, model_nameModel years (newest first); may include default_listing_year on step responses
sizesabove + model_yearSize display strings (e.g. 36×12)
bedroomsabove (+ optional size filter)Bedroom counts; may include null for unknown/varying counts

Pre-fill and validation

Any catalogue request may include optional pre-fill parameters: caravan_type, manufacturer, model_name, model_year, size_display (or sd, or lf+wf), and bedrooms (use __null__ when bedroom count is unknown).

Every catalogue response includes a selection object. Each field has:

  • provided - whether your request included this field
  • value - the value you sent (if provided)
  • valid - whether the value exists in the published catalogue (null when not provided)
  • canonical - the guide’s canonical spelling to use in downstream search calls (when valid)

Catalogue endpoints return filter values only - no retail or trade prices. Prices are returned by /valuations/search and /valuations/pricing.

Kill-switch keys (admin): valuations.catalog, valuations.resolve (or category valuations).

GET /api/v1/valuations/catalog

Stepwise catalogue options for partner cascading dropdowns (make → model → year → size → bedrooms). Returns filter values only - no retail or trade prices. Use with optional pre-fill parameters so each field can be populated individually from your listing data or URL query string.

Modes

  • Step - pass step to load one dropdown level.
  • Bootstrap - pass bootstrap=1 to hydrate all applicable option lists in one call (ideal for page load when you already know part of the spec).

Step values

caravan_types · manufacturers · models · years · sizes · bedrooms

Query Parameters

ParameterTypeRequiredDescription
stepstringStep modeOne of the step values above
bootstrap0|1Bootstrap modeWhen 1, returns all option lists for the supplied selection (omit step)
caravan_typestringNostatic | touring | motorhome (default: static)
manufacturerstringParent / pre-fillRequired for models and below; optional pre-fill on any call
model_namestringParent / pre-fillRequired for years and below
model_yearintParent / pre-fillRequired for sizes and bedrooms
size_displaystringNoPre-fill or narrow bedrooms; aliases: sd, or lf+wf
bedroomsint|stringNoPre-fill bedroom count; use __null__ when bedroom count is unknown

Step response

{
  "success": true,
  "data": {
    "edition_date": "2026-04-01",
    "step": "models",
    "values": ["Challenger", "Conqueror"],
    "selection": {
      "caravan_type": { "provided": true, "value": "static", "valid": true, "canonical": "static" },
      "manufacturer": { "provided": true, "value": "Swift", "valid": true, "canonical": "Swift" },
      "model_name": { "provided": false, "value": null, "valid": null, "canonical": null }
    }
  },
  "meta": { "request_id": "...", "version": "v1" }
}

Bootstrap response

{
  "success": true,
  "data": {
    "edition_date": "2026-04-01",
    "mode": "bootstrap",
    "options": {
      "caravan_types": ["static"],
      "manufacturers": ["Swift", "ABI"],
      "models": ["Challenger"],
      "years": [2022, 2021, 2020],
      "sizes": ["36×12"],
      "bedrooms": [2, 3]
    },
    "selection": { "...": "per-field provided / valid / canonical" }
  }
}

Each selection field includes provided, value, valid, and canonical. Use canonical values when calling /valuations/search.

Example requests

GET /api/v1/valuations/catalog?step=manufacturers&caravan_type=static
GET /api/v1/valuations/catalog?step=years&manufacturer=Swift&model_name=Bordeaux
GET /api/v1/valuations/catalog?bootstrap=1&manufacturer=Swift&model_name=Bordeaux&model_year=2017&bedrooms=2

Errors

  • 400 invalid_request - missing step (and no bootstrap=1), unknown step, or missing parent params (e.g. manufacturer required for step=models)
  • 503 internal_error - no published guide edition available

GET /api/v1/valuations/resolve

Resolve trade or alias manufacturer/model/year to the canonical catalogue identity before pre-filling your form or calling search. Optional size and bedroom parameters match the guide alias resolver.

Query Parameters

ParameterTypeRequiredDescription
manufacturerstringYesAs shown on the partner listing
model_namestringYes
model_yearintYes1900–2100
caravan_typestringNodefault: static
size_display / sd / lf+wfstringNoOptional size filter
bedroomsint|stringNoOptional; __null__ for unknown count

Response (matched)

{
  "success": true,
  "data": {
    "edition_date": "2026-04-01",
    "matched": true,
    "resolution_type": "family",
    "family_id": 1234,
    "manufacturer": "Swift",
    "model_name": "Challenger",
    "model_year": 2020,
    "mapped_from": { "manufacturer": "…", "model_name": "…", "model_year": 2019 },
    "mapped_to": { "manufacturer": "Swift", "model_name": "Challenger", "model_year": 2020 },
    "mapping_note": ""
  },
  "meta": { "request_id": "...", "version": "v1" }
}

Other outcomes

  • matched: false - no mapping or direct catalogue match; HTTP 200
  • resolution_type: "note_only" - informational mapping only (no canonical family); includes mapping_note
  • multi_layout: true - multiple family IDs when alias resolves to several layouts; includes family_ids array

Search valuations by manufacturer, model name, model year, and caravan type. Returns retail and trade values for the current published edition. Automatically falls back to alias mappings when no direct match is found.

Query Parameters

ParameterTypeRequiredDescription
manufacturerstringYesManufacturer name (e.g. Swift); prefer selection.*.canonical from catalogue or resolve
model_namestringYesModel name (e.g. Bordeaux)
model_yearintYes4-digit year (1900–2100)
caravan_typestringNostatic | touring | motorhome (default: static)
pageintNoPage number (default: 1)
limitintNoResults per page, 1–50 (default: 24)

Response

{
  "success": true,
  "data": {
    "edition_date": "2026-04-01",
    "page": 1, "limit": 24, "total": 3,
    "market_pulse_pct": 100,
    "mapping": null,
    "results": [
      { "family_id": 1234, "manufacturer": "Swift", "model_name": "Bordeaux",
        "model_year": 2017, "variant_key": "SE", "caravan_type": "static",
        "bedrooms": 2, "size_label": "36×12", "length_ft": 36, "width_ft": 12,
        "retail": 18500, "trade": 15200, "retail_base": 18500, "trade_base": 15200 }
    ]
  },
  "meta": { "request_id": "...", "version": "v1" }
}

When a mapping applies, mapping.mapped is true and includes mapped_from, mapped_to, and public_note for display to end users.

GET /api/v1/valuations/cascade

All variants for a given manufacturer + model across all years (flat list with sizes, bedrooms, and prices). For interactive dropdowns and individual field pre-fill, prefer /valuations/catalog.

Query Parameters

ParameterTypeRequiredDescription
manufacturerstringYes
model_namestringYes
caravan_typestringNodefault: static

GET /api/v1/valuations/pricing

Current and previous edition pricing for a specific family. Includes market_pulse_pct adjustment.

Query Parameters

ParameterTypeRequiredDescription
family_idintYesFrom search, resolve, or cascade results

Response fields

  • retail - market-pulse-adjusted retail price
  • retail_base - guide retail price before market pulse
  • trade - market-pulse-adjusted trade price
  • previous - same fields for the prior edition (null if first appearance)

Certificates

Read endpoints require: certificates:read · Write requires: certificates:write (enterprise only)

GET /api/v1/certificates/verify

Verify a certificate by its number.

Query Parameters

ParameterTypeRequiredDescription
certificate_numberstringYes

Response

{
  "data": {
    "certificate_number": "CG-2026-abc123",
    "valid": true, "status": "active",
    "issued_at": "2026-01-15 10:00:00", "expires_at": "2027-01-15 10:00:00",
    "manufacturer": "Swift", "model_name": "Challenger", "model_year": 2020,
    "caravan_type": "touring"
  }
}

POST /api/v1/certificates/issue

Issue a new certificate. Enterprise / write access only.

This is a write endpoint. An Idempotency-Key header is required.

Request Body (JSON)

{
  "family_id": 1234,
  "valid_months": 12,
  "notes": "Issued via API for dealer ref #45678"
}

Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
Idempotency-KeyYesClient-chosen unique key for this operation (max 190 chars). Same key + same body = replay. Same key + different body = 409.

Response

201 Created on first successful issue. 200 with X-Idempotency-Replayed: true on replay.

Trust Badge

Requires scope: trust_badge:read

GET /api/v1/trust-badge/status

Returns active trust badge status for a domain.

Query Parameters

ParameterTypeRequiredDescription
domainstringYese.g. acme-caravans.co.uk (no scheme, no trailing slash)

GET /api/v1/trust-badge/verify

Returns a simple verified: true/false with the verification timestamp. Use this for lightweight programmatic checks.

Query Parameters

ParameterTypeRequiredDescription
domainstringYes

Valuation History

Requires scope: valuations:read

GET /api/v1/valuations/history

Returns retail and trade price history across published editions for a specific caravan family. Ideal for rendering price-movement charts and trend graphs.

Query Parameters

ParameterTypeRequiredDescription
family_idintYesID from /valuations/search results
limitintNoNumber of editions to return, 1–24 (default: 12)

Response

{
  "success": true,
  "data": {
    "family_id": 1234,
    "manufacturer": "Swift",
    "model_name": "Challenger",
    "model_year": 2020,
    "caravan_type": "touring",
    "variant_key": "SE",
    "total": 12,
    "history": [
      { "edition_date": "2025-04-01", "retail": 14995, "trade": 11500 },
      { "edition_date": "2025-10-01", "retail": 15250, "trade": 11750 },
      { "edition_date": "2026-04-01", "retail": 15495, "trade": 12000 }
    ]
  },
  "meta": { "request_id": "...", "version": "v1" }
}

History is returned oldest-first, suitable for direct use in chart libraries.

Certificate History

Requires scope: certificates:read

GET /api/v1/certificates/history

Returns certificates issued for a specific caravan family, identified by family_id. Shows how many times a caravan has been independently valued and certificated.

Query Parameters

ParameterTypeRequiredDescription
family_idintYesID from /valuations/search results
limitintNoMax results, 1–50 (default: 20)

Response

{
  "success": true,
  "data": {
    "family_id": 1234,
    "manufacturer": "Swift",
    "model_name": "Challenger",
    "model_year": 2020,
    "caravan_type": "touring",
    "total": 2,
    "certificates": [
      {
        "certificate_number": "CGV-20260101-A1B2C3D4E5F6",
        "issued_at": "2026-01-01 10:30:00",
        "issued_for": "John Smith",
        "edition_date": "2026-04-01"
      }
    ]
  },
  "meta": { "request_id": "...", "version": "v1" }
}

Announcements

No specific scope required - available to all authenticated API clients.

GET /api/v1/announcements

Returns active announcements from Caravan Guide - platform news, valuation edition releases, or partner notices. Suitable for displaying in-app banners or notification feeds.

Query Parameters

ParameterTypeRequiredDescription
limitintNoMax results, 1–50 (default: 10)

Response

{
  "success": true,
  "data": {
    "total": 1,
    "announcements": [
      {
        "id": 12,
        "title": "Spring 2026 edition now live",
        "body": "The April 2026 valuation edition has been published...",
        "published_at": "2026-04-01 09:00:00",
        "current_until": "2026-04-30 23:59:59"
      }
    ]
  },
  "meta": { "request_id": "...", "version": "v1" }
}

Account

No specific scope required beyond a valid authenticated credential.

GET /api/v1/account/me

Returns details about the authenticated API client: identity, access tier, granted scopes, and current-month usage. Use this to display subscription status in your app or to verify your integration is using the correct credentials.

The docs_access_enabled field is retained for compatibility and is always true - API documentation is public and no longer gated by commercial access.

Response

{
  "success": true,
  "data": {
    "client": {
      "id": "d05aed00-2ef9-4ff5-ab50-38e61bda55ac",
      "name": "UK Caravan Portal",
      "environment": "live",
      "status": "active",
      "created_at": "2026-04-01 12:00:00"
    },
    "access": {
      "commercial_status": "live_enabled",
      "commercial_tier": "partner_pro",
      "live_enabled": true,
      "sandbox_enabled": true,
      "write_scopes_enabled": false,
      "docs_access_enabled": true,
      "monthly_request_allowance": 50000,
      "access_ends_at": null
    },
    "scopes": ["valuations:read", "certificates:read", "trust_badge:read", "announcements:read"],
    "usage": {
      "month": "2026-04",
      "requests_this_month": 1842,
      "allowance": 50000
    }
  },
  "meta": { "request_id": "...", "version": "v1" }
}

User Authentication

Phase 2 - Coming Soon User-facing OAuth (Authorization Code Flow) to allow your app to act on behalf of a Caravan Guide subscriber is planned for a future release. The current API uses machine-to-machine credentials only. Contact api@caravanguide.co.uk to register interest.