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.

GET /api/v1/status

Returns uptime percentages, component health, and recent incidents for the public status page. No authentication required. Cached for 60 seconds.

Human-readable dashboard: Platform status.

Response (abbreviated)

{
  "overall": "operational",
  "timestamp": "2026-06-04T12:00:00Z",
  "monitoring_since": "2026-06-01 08:00:00",
  "uptime": { "24h": { "platform": 100 }, "7d": { "platform": 99.98 } },
  "components": [{ "id": "api", "name": "API", "status": "operational", "uptime": { "90d": 99.99 } }],
  "incidents": []
}

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 for form pre-fill and mapping metadata. Optional size and bedroom parameters match the guide alias resolver. For prices, call /valuations/search with the original listing make/model/year (or pass mapping_id when using the canonical identity).

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
listing_dg / listing_ch0|1NoFor mappings conditioned on double glazing + central heating

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,
    "mapping_id": 56,
    "delta_retail": -4000,
    "delta_trade": -4000,
    "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" }
}

delta_retail / delta_trade are fixed pounds applied after Market Pulse (same as the public guide). Pass mapping_id into search, pricing, or history when you look up by canonical family instead of the alias text.

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 (Market Pulse, then any mapping £ adjustment). Automatically falls back to alias mappings when no direct match is found — prefer the original listing text so mapped prices apply.

Query Parameters

ParameterTypeRequiredDescription
manufacturerstringYesListing or catalogue manufacturer (e.g. Swift). Prefer original listing text for aliases
model_namestringYesModel name (e.g. Bordeaux)
model_yearintYes4-digit year (1900–2100)
caravan_typestringNostatic | touring | motorhome (default: static)
mapping_idintNoFrom resolve; applies mapping £ deltas when searching by canonical identity
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 mapping_id, mapped_from, mapped_to, public_note, delta_retail, and delta_trade.

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, then optional fixed guide-mapping £ deltas when mapping_id is supplied.

Query Parameters

ParameterTypeRequiredDescription
family_idintYesFrom search, resolve, or cascade results
mapping_idintNoFrom resolve or search.mapping; applies mapping £ to current and previous

Response fields

  • retail - market-pulse-adjusted retail price (+ mapping £ when applicable)
  • retail_base - guide retail price before market pulse / mapping
  • trade - market-pulse-adjusted trade price (+ mapping £ when applicable)
  • mapping - present when mapping_id applied (delta_retail / delta_trade)
  • 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.