CarsXECarsXE

Submit up to 10,000 VINs in one request for bulk recall checking. Unlike the single-VIN Recalls API, this endpoint is built for high-volume workflows — fleet management, dealership inventory scans, and wholesale auction processing.

Recalls Batch is asynchronous: submit your VINs, poll for status (or use a webhook), then retrieve results when the job is completed or partial. Uncached VINs are queued for full processing; turnaround is typically 30–60 minutes depending on batch size and load.

How it works

  1. SubmitPOST VINs (JSON array, inline CSV, or HTTPS URL to a CSV). You receive a batchId immediately (202 Accepted).
  2. Poll — Call the status endpoint with batchId until completed, partial, or failed (or wait for your customer webhook).
  3. RetrieveGET results as JSON, or download CSV from /v1/recalls-batch/download.

Caching: Recently checked VINs may be served from cache. If every VIN in the batch is cached, the submit response can already show status: "completed" with full processedVins — no uploading / processing phase.

Full processing path: Uncached VINs move through uploading, then processing, while CarsXE prepares and runs the batch; results are written when processing finishes.

For interactive try-it-live, see the API Reference.

Parameters

Provide at least one of vins, csv, or csvUrl. You can combine them — all VINs are merged and deduplicated. The combined total must not exceed 10,000.

ParameterRequiredDescription
vinsNo*JSON array of 17-character VIN strings
csvNo*Inline CSV text (one VIN per line, or a single vin column)
csvUrlNo*HTTPS URL to a CSV file (max 5 MB). Supported hosts: Google Sheets, Google Cloud Storage, AWS S3, Dropbox, Azure Blob, DigitalOcean Spaces, and Box. Google Sheets and Dropbox sharing links are auto-converted to direct download
webhookUrlNoHTTPS URL for a customer webhook when the batch finishes
keyYesYour CarsXE API key (query parameter; official SDKs may send x-api-key instead)

* At least one of vins, csv, or csvUrl is required.

Step 1: Submit a batch

Submit a batch

Code
curl -X POST "https://api.carsxe.com/v1/recalls-batch/submit?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "vins": [
      "1HGBH41JXMN109186",
      "5YJSA1E26HF000001",
      "1C4JJXR64PW696340"
    ],
    "webhookUrl": "https://your-server.com/webhook"
  }'

Submit with a CSV URL

# Google Sheets sharing link (auto-converted to CSV export)
curl -X POST "https://api.carsxe.com/v1/recalls-batch/submit?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "csvUrl": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit"
  }'

Submit response fields

Successful submission returns HTTP 202 with:

Step 2: Check status

Poll until the batch reaches a terminal state. Recommended interval: every 30–60 seconds while uploading or processing.

StatusDescription
pendingReserved for future use; batches from this API typically start as uploading or completed
uploadingBatch accepted; CarsXE is preparing it for processing
processingRecall check in progress
completedAll VINs processed; results are ready
partialResults available, but fewer VIN rows than totalVins (treat as complete for retrieval)
failedProcessing failed; see errorMessage

Check batch status

Code
curl -G "https://api.carsxe.com/v1/recalls-batch/status" \
  -d key=YOUR_API_KEY \
  -d batchId=brb_mnablbn7_wvbaqv

Status response fields

Step 3: Retrieve results

Once status is completed or partial, fetch full recall rows as JSON or download CSV.

Get results (JSON)

Code
curl -G "https://api.carsxe.com/v1/recalls-batch/results" \
  -d key=YOUR_API_KEY \
  -d batchId=brb_mnablbn7_wvbaqv

Results shape

Each VIN has vin, hasRecalls (true if there is at least one safety recall), recallCount, and recalls — an array of sparse camelCase objects:

Common keys when present: recallNhtsaNumber, recallOemNumber, recallTitle, recallDescription, recallRiskDescription, recallRemedyDescription, recallType, recallState, recallStatus, recallIssueDate, severityCode, vehicleYear, vehicleMake, vehicleModel, isRemedied.

CSV download

GET /v1/recalls-batch/download with the same key and batchId. Returns text/csv with a Content-Disposition filename. SDKs also expose a download URL helper (getBulkRecallBatchDownloadUrl / get_bulk_recall_batch_download_url).

curl -G "https://api.carsxe.com/v1/recalls-batch/download" \
  -d key=YOUR_API_KEY \
  -d batchId=brb_mnablbn7_wvbaqv \
  -o recalls_brb_mnablbn7_wvbaqv.csv

Agentic payment access

x402 callers can submit a batch without a CarsXE API key by sending only the JSON vins array. The payment requirement quotes the current bulk_recall_batch starter price multiplied by the number of unique, valid VINs. Inline CSV and csvUrl submissions still require API-key authentication.

After payment, the 202 response includes data.batchToken. Store it securely and send it on every follow-up request; polling, JSON results, and CSV download are included in the original batch payment.

curl -G "https://api.carsxe.com/v1/recalls-batch/results" \
  -d batchId=brb_mnablbn7_wvbaqv \
  -H "X-CarsXE-Batch-Token: <batch-token>"

The token is scoped to one batch, is not included in webhook payloads, and remains valid until the batch job is deleted.

Webhook notifications

If you pass webhookUrl on submit, CarsXE sends an HTTPS POST with Content-Type: application/json when the batch reaches a terminal state (completed or partial). Redirects are not followed. Respond quickly — the request times out on CarsXE’s side after about 30 seconds.

{
  "event": "bulk_recall_batch_complete",
  "batchId": "brb_mnablbn7_wvbaqv",
  "status": "completed",
  "totalVins": 100,
  "processedVins": 100,
  "hitCount": 25,
  "hitRate": 25,
  "downloadUrl": "https://api.carsxe.com/v1/recalls-batch/download?key=…&batchId=…",
  "timestamp": "2026-03-24T10:16:43.000Z"
}

The downloadUrl includes your API key in the query string so you can fetch the CSV without assembling the URL. Your API key is not repeated as a separate JSON field.

Complete example: submit, poll, and retrieve

Full workflow

Code
import { CarsXE } from "carsxe-api";

const carsxe = new CarsXE("YOUR_API_KEY");

const submitResponse = await carsxe.submitBulkRecallBatch({
  vins: [
    "1HGBH41JXMN109186",
    "5YJSA1E26HF000001",
    "1C4JJXR64PW696340",
  ],
});
const batchId = submitResponse.data?.batchId;
if (!batchId) throw new Error("No batchId");
console.log(`Batch submitted: ${batchId}`);

let status;
do {
  await new Promise((r) => setTimeout(r, 30_000));
  status = await carsxe.getBulkRecallBatchStatus(batchId);
  console.log(`Status: ${status.data?.status}`);
} while (
  status.data?.status === "processing" ||
  status.data?.status === "uploading"
);

if (status.data?.status === "completed" || status.data?.status === "partial") {
  const results = await carsxe.getBulkRecallBatchResults(batchId);
  console.log(`Processed: ${results.data?.job.processedVins} VINs`);
  console.log(`Safety recall hits: ${results.data?.job.hitCount}`);

  for (const result of results.data?.results ?? []) {
    if (result.hasRecalls) {
      console.log(`${result.vin}: ${result.recallCount} recall row(s)`);
    }
  }
}

Errors

StatusWhen it happens
400Missing VINs, too many VINs (>10,000), invalid VIN, invalid/disallowed/oversized csvUrl, or invalid webhookUrl
401Missing or invalid API key, or inactive account
404Batch not found or you don't have access
405Submit called with a method other than POST
409Batch still processing (results/download only)
429Usage limit exceeded
500Internal storage or batch handoff error — retry later
502Server could not fetch the CSV from csvUrl

See the Errors guide for general error handling guidance.