From a vehicle to a buying decision.

POXA’s Scrap Car Quote API returns vehicle and part valuations as JSON. Send a VIN or UK registration, add damage areas or photos, and get low and average part values, revenue estimates over 1, 3, 6, 9 and 12 months, demand scores and your connected inventory overlap. Create your own API key instantly in the dashboard. No access request is needed.

1. Create your key

Open the API console. Create a sandbox key first. Keys are shown once, stored as hashes, scoped to their creator’s current account and environment, and expire after 90 days. Each user can have 10 active keys. Revocation blocks subsequent requests; requests already running may finish. Live keys belong on your server, never in browser source, URLs, logs or version control.

2. Send your first request

Production: https://poxa.co.uk/api/v1. Development: https://dev.poxa.co.uk/api/v1. Use a key created in the same environment. Set POXA_API_KEY securely in your server environment.

curl --request POST 'https://poxa.co.uk/api/v1/breaker-value' \
  --header "Authorization: Bearer $POXA_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: your-unique-request-id' \
  --max-time 120 \
  --data '{"vin":"WVWZZZAUZFW321566","damage":[{"area":"front_end","side":"nearside"}],"min_part_value":40,"vat":"inc","detail":"full","reference":"your-stock-reference"}'

The sandbox returns an explicitly labelled synthetic fixture, regardless of the vehicle submitted. It validates inputs but does not run photo analysis, inspect inventory or record API vehicle usage.

3. Request fields

Field Type Description
vin string Exactly one of VIN or reg. 17 characters after removing spaces; I, O and Q are invalid.
reg string Exactly one of VIN or reg. UK plate, 2–8 letters/digits after removing spaces.
damage array Optional damaged areas. Can be combined with photos; exclusions are combined once.
damage_images array Up to 6 images, 1 MiB each. JSON body at most 9 MiB. Photos are processed in memory and sent to the image-analysis provider; POXA does not save them in valuation history.
min_part_value number Exclude parts whose conservative low value INCLUDING VAT, rounded to the nearest pound as in the app, is below this amount. Applied before VAT conversion and duplicate selection. Use 0 to disable the minimum.
vat string inc: displayed market values. ex: divide by 1.20. Not a margin-scheme tax calculation.
detail string summary omits the parts and removed arrays; all totals and inventory overlap remain.
reference string Your stock/lot reference, returned unchanged. Never send secrets or personal details.

Send exactly one of vin or reg. Damage areas: powertrain, front_end, doors, body, interior, wheels, rear, misc. Damage sides: both, nearside (left), offside (right). Parts with no known side, or spanning the car, are excluded on either side. Area and image exclusions are combined once. Images use data:image/jpeg;base64,..., data:image/png;base64,... or data:image/webp;base64,...; no remote URLs. Six images maximum, 1 MiB each, 9 MiB JSON body. Images are held in memory for analysis and sent to the image-analysis provider; POXA does not save them to valuation history.

4. Read the response

value.low and value.average sum the retained parts. value.horizons contains low, average and part counts for 1, 3, 6, 9 and 12 months (30, 90, 180, 270, 365 days). These are cumulative estimates from listing now, not historical lookbacks, profit, or guarantees. Parts expected to take longer than 365 days remain in the all-parts total only.

Each part has a demand score from 1 to 10 (8–10 hot, 4–7 mid, 1–3 low). Missing evidence returns null. sells_in_days is uncapped. The whole-car score is value-weighted. Inspect data.market_stock_as_of and pricing_updated_at for data age. Review all photo assessments; hidden damage may be missed.

{
  "id": "bv_example",
  "object": "breaker_value",
  "api_version": "2026-11-03",
  "mode": "test",
  "created_at": "2026-10-20T12:00:00.000Z",
  "expires_at": "2026-11-19T12:00:00.000Z",
  "reference": "your-stock-reference",
  "vehicle": {
    "vin": "WVWZZZAUZFW321566",
    "reg": "DEMO1",
    "make": "Demo",
    "model": "Hatchback",
    "variant": null,
    "year": 2015,
    "title": "Sandbox demonstration vehicle"
  },
  "value": {
    "currency": "GBP",
    "vat": "inc",
    "parts": 4,
    "low": 952,
    "average": 1640.5,
    "horizons": [
      {
        "months": 1,
        "within_days": 30,
        "parts": 0,
        "low": 0,
        "average": 0
      },
      {
        "months": 3,
        "within_days": 90,
        "parts": 1,
        "low": 630,
        "average": 1020
      },
      {
        "months": 6,
        "within_days": 180,
        "parts": 2,
        "low": 840,
        "average": 1402.5
      },
      {
        "months": 9,
        "within_days": 270,
        "parts": 4,
        "low": 952,
        "average": 1640.5
      },
      {
        "months": 12,
        "within_days": 365,
        "parts": 4,
        "low": 952,
        "average": 1640.5
      }
    ]
  },
  "demand": {
    "score": 8,
    "tier": "hot",
    "model_version": "sold-db-2026-10-08-v1-demand-v7"
  },
  "damage": {
    "areas": [
      {
        "area": "front_end",
        "side": "nearside"
      }
    ],
    "images_received": 0,
    "images_status": "not_requested",
    "excluded": {
      "parts": 1,
      "low": 56,
      "average": 102
    }
  },
  "inventory": {
    "status": "not_checked_in_test_mode",
    "systems": [],
    "as_of": null,
    "overlap": null
  },
  "parts": [
    {
      "id": "part_1",
      "name": "Engine",
      "area": "powertrain",
      "side": null,
      "quantity": 1,
      "oem_numbers": [
        "DEMO1"
      ],
      "low": 630,
      "average": 1020,
      "sold_12m": 40,
      "active_listings": 2,
      "demand": {
        "score": 10,
        "tier": "hot",
        "sells_in_days": 38
      },
      "photo_assessment": null,
      "excluded_reason": null
    },
    {
      "id": "part_2",
      "name": "Gearbox",
      "area": "powertrain",
      "side": null,
      "quantity": 1,
      "oem_numbers": [
        "DEMO2"
      ],
      "low": 210,
      "average": 382.5,
      "sold_12m": 8,
      "active_listings": 1,
      "demand": {
        "score": 6,
        "tier": "mid",
        "sells_in_days": 121
      },
      "photo_assessment": null,
      "excluded_reason": null
    },
    {
      "id": "part_4",
      "name": "Door (Right)",
      "area": "doors",
      "side": "offside",
      "quantity": 1,
      "oem_numbers": [
        "DEMO4"
      ],
      "low": 42,
      "average": 85,
      "sold_12m": 1,
      "active_listings": 0,
      "demand": {
        "score": 5,
        "tier": "mid",
        "sells_in_days": 202
      },
      "photo_assessment": null,
      "excluded_reason": null
    },
    {
      "id": "part_5",
      "name": "Tailgate",
      "area": "rear",
      "side": null,
      "quantity": 1,
      "oem_numbers": [
        "DEMO5"
      ],
      "low": 70,
      "average": 153,
      "sold_12m": 1,
      "active_listings": 1,
      "demand": {
        "score": 4,
        "tier": "mid",
        "sells_in_days": 243
      },
      "photo_assessment": null,
      "excluded_reason": null
    }
  ],
  "removed": [
    {
      "id": "part_3",
      "name": "Headlight (Left)",
      "area": "front_end",
      "side": "nearside",
      "quantity": 1,
      "oem_numbers": [
        "DEMO3"
      ],
      "low": 56,
      "average": 102,
      "sold_12m": 2,
      "active_listings": 0,
      "demand": {
        "score": 5,
        "tier": "mid",
        "sells_in_days": 180
      },
      "photo_assessment": null,
      "excluded_reason": "damage_area"
    },
    {
      "id": "part_6",
      "name": "Dashboard",
      "area": "interior",
      "side": null,
      "quantity": 1,
      "oem_numbers": [
        "DEMO6"
      ],
      "low": 28,
      "average": 59.5,
      "sold_12m": 1,
      "active_listings": 3,
      "demand": {
        "score": 3,
        "tier": "low",
        "sells_in_days": 333
      },
      "photo_assessment": null,
      "excluded_reason": "below_min_part_value"
    }
  ],
  "data": {
    "priced_at": "2026-10-20T00:00:00Z",
    "market_stock_as_of": "2026-10-20",
    "pricing_updated_at": "2026-10-20T00:00:00Z"
  },
  "warnings": [
    "Sandbox fixture. These are illustrative values, not a valuation of the supplied vehicle.",
    "Revenue estimates assume parts are listed now at competitive prices. They are not a sale guarantee or profit forecast.",
    "Low and average are conservative per-part estimates matching the Breaker Value app; the adjustments are already included. VAT ex applies a 20% adjustment, not a margin-scheme calculation."
  ]
}

5. Connected inventory

Only your account’s connected inventory is checked. Stock comes from one source, so the same stock is never counted twice: a yard system first, then a stock upload, then an online store. inventory.systems names it as yard_system, stock_upload or online_store, and as_of is the snapshot time. Yard-system data requires the key owner’s Breaker Value analysis grant. OEM-number matches can miss unnumbered parts. overlap.parts counts matching part lines on this car; average_value is their value on this car, not the value of the stock on your shelf. A missing or inaccessible connection returns a status and null overlap, not zero stock.

A stock upload is a file of your stock, uploaded on Connections at least every week. Each upload replaces the last one. Until the first stock upload the status is sync_pending. An upload more than 7 days old is still used, and warnings says how old it is.

Field Description
overlap.items[].in_stock Units you have in stock with a matching OEM number. Every retained part is listed, including those you have none of.
overlap.items[].months_of_stock How long that stock lasts, in months, to one decimal place: units in stock × the time one takes to sell (see cover_basis). Null when there is no estimate of how fast the part sells; otherwise 0 when you have none.
overlap.items[].stock_status not_in_stock when you have none. stock_more when what you have, plus one more, would all sell within 13 months (so a part that sells in about a year counts), and one more is worth stocking. in_stock otherwise: you have enough, or there is no estimate of how fast the part sells. The 13 months is fixed.
overlap.not_in_stock, overlap.stock_more How many of this car’s parts you have none of, and how many you have where one more is worth stocking (stock_more).
overlap.cover_basis Where the time one takes to sell comes from. your_sales: your own sales over the last 12 months (a yard system or uploaded sales); a part you have not sold in that time uses its sells_in_days. market: you have no sales history, so every part uses its sells_in_days.

Live API valuations are recorded with the API channel for your account’s dashboard comparison. Sandbox calls are never included.

6. Limits and billing

Each live call uses 1 credit from your account: the same pot as Breaker Value on the website and Auctions, shared by everyone on the account. A call that fails gives its credit back. Sandbox (test) keys are free. GET reads and idempotent replays use no credit.

When the account has no credits left, live calls return 402 credits_exhausted with a credits object (used, total, remaining and when they reset). Nothing is charged automatically: buy more or change plan in Usage, then retry. An unpaid invoice returns 402 payment_overdue until it is paid.

Burst limits: 60 requests per minute in each mode and two concurrent valuations per account. Daily safety cap: 5,000 live calls per account, shared across all keys; keys may have lower limits. A call refused for credits does not count towards the cap. 1,000 sandbox attempts per account per day. Daily limits reset at 00:00 UTC. Accounts on an older plan use their monthly Breaker Value searches instead, with a default of 100 live calls a day, and get 402 quota_exceeded when they run out.

Live responses include POXA-Credits-Remaining, POXA-Credits-Limit and POXA-Credits-Reset for your account's credits, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset for the daily cap, X-Request-Id and POXA-Version. Rate-limit or temporary failures may include Retry-After in seconds.

7. Retries and saved results

Send a unique Idempotency-Key (8–128 letters, digits, underscores or hyphens) for each new valuation. Retry with the SAME key and unchanged body after a connection failure. A running request returns 409 request_in_progress; wait Retry-After. An identical finished request replays its response for 30 days without charging again. Changing its body returns 409 idempotency_conflict. After a stored failure, use a NEW idempotency key to intentionally try again. Interrupted requests are recovered and their credit given back when your account next uses the API or console after ten minutes.

GET /breaker-value/{id} fetches a saved response for 30 days. It must use a key belonging to the original key owner, account, mode and environment. Rotation preserves this access. Apply bounded exponential backoff with jitter and respect Retry-After. Allow 120 seconds for a valuation. No batch or webhook endpoints are currently offered.

Errors

  • 400 — invalid_request / invalid_json: fix the field indicated by param.
  • 401 — invalid_api_key: check the key, expiry, revocation and environment.
  • 402 — credits_exhausted / payment_overdue: no credits left this period, or the plan’s last payment failed (url is the invoice). Buy more or change plan in Usage, or pay the invoice, then retry. Older plans: quota_exceeded when the monthly searches run out.
  • 403 — account_required / account_unavailable: check your account membership.
  • 404 — not_found: check the valuation ID and key owner.
  • 409 — idempotency_conflict / request_in_progress: preserve the same key and payload when retrying an in-flight request.
  • 413 — payload_too_large: reduce images below the documented limits.
  • 415 — unsupported_media_type: send application/json.
  • 422 — insufficient_data / photo_analysis_too_large: no complete valuation could be returned.
  • 429 — rate_limited: obey Retry-After; daily requests reset at 00:00 UTC.
  • 503 — service_unavailable / limits_unavailable / valuation_unavailable / photo_analysis_unavailable / photo_analysis_failed / request_interrupted: retry after the service recovers.
  • 504 — valuation_timeout / photo_analysis_timeout: retry later.

Errors use {"error":{"code":"invalid_request","message":"Send exactly one of vin or reg.","param":"vin","request_id":"req_example"}}. Never send a key when asking for help; send X-Request-Id.

OpenAPI

Download the OpenAPI 3.1 specification. Import it into Postman, Insomnia or your client generator. The playground, docs, examples and published specification share this contract.

FAQ

How do I get an API key?

Sign in, open Breaker Value → Scrap Car Quote API, and create a sandbox or live key. No access request or approval is needed. Copy the key when it is created; it is only shown once.

What do the month totals mean?

Cumulative estimated revenue from parts expected to sell within 30, 90, 180, 270 and 365 days of listing now. These are forecasts, not historical lookback windows, profit or guaranteed sales.

Can I send damage photos?

Yes. Send up to six JPEG, PNG or WebP images as base64 data URLs, at most 1 MiB each. You can combine images with damage areas. Hidden damage may not be visible in photos.

Do I need connected inventory?

No. Valuations and demand work without a connection. Inventory overlap is returned only for your account’s connected, authorised inventory. Without it, overlap is null, never a fabricated zero.

What does a request cost?

One credit for each successful live valuation, from the same pot as Breaker Value on the website and Auctions. A failed call gives its credit back, and sandbox calls and saved-result reads are free. Plans start at £59.99 a month + VAT for 100 credits, and the Free plan gives 10 credits a month with no card. Out of credits, live calls return 402 credits_exhausted until you buy more; nothing is charged automatically.

How do I keep keys safe?

Keep live keys on your server in an environment variable or secret manager. Never include them in public browser code or commit them to source control. Keys expire after 90 days and can be revoked immediately from the dashboard.