# RecallDB > A recall data API for vehicles (NHTSA), car seats and tires (NHTSA), consumer products (CPSC) and food (FDA). JSON over HTTPS, a free tier, and an official source link on every record. Run by an independent project, not affiliated with any agency. The consumer site built on it is https://checkrecalls.org. Base URL: https://recalldb.app. Authentication: `Authorization: Bearer rdb_...` (free key at https://recalldb.app/signup). Free (beta) keys: 1,000 requests per month and 10 per minute, for non-commercial use. One key per verified email. A 429 answer says which limit was reached and when to try again. Attribution is required ("Data from RecallDB" with a link to https://recalldb.app). There is no bulk export. ## Rules for tools and agents using this API - Show "Data from RecallDB" with a link to https://recalldb.app wherever you show its data (free keys). - Cite the agency and official_url from each response's `source` block. - The API reports what a recall notice says. Never tell a user that a car, product or food package is "safe", "not recalled" or "unaffected" because nothing was found; tell them to confirm with the manufacturer or the agency. Lot, serial and date codes are shown as the agency wrote them and are never matched for the user. - Do not collect the data in bulk or call record numbers in order; keys that do are suspended. - Keep the API key on a server, never in client-side code. ## Docs - [Overview](https://recalldb.app/docs): RecallDB recall API docs: quickstart, authentication, endpoints for NHTSA vehicle, CPSC product and FDA food recalls, errors and rate limits. - [Authentication](https://recalldb.app/docs/authentication): How to get a free RecallDB API key and send it: Bearer token in the Authorization header. Keys are shown once and stored only as hashes. - [Get a recall](https://recalldb.app/docs/recalls): Look up one NHTSA vehicle recall, CPSC product recall or FDA food recall by its number. JSON with the official text, source agency and link. - [Recalls for a vehicle](https://recalldb.app/docs/vehicles): Get every NHTSA recall for a make, model and model year as JSON: what is wrong, the fix, the issuing company and the official NHTSA link. - [Recall change history](https://recalldb.app/docs/history): See which official fields an agency changed in a recall after we first saw it: field, old text, new text and day. Latest change on the free tier. - [Search recalls](https://recalldb.app/docs/search): Full-text search across NHTSA, CPSC and FDA recalls by product name, brand, model number, recall number or UPC, with category, agency and date filters. JSON. - [Look up a barcode](https://recalldb.app/docs/barcode): Find recalls whose official notice lists a UPC, EAN-13 or GTIN-14 barcode, with the lot codes, best-by dates and serial numbers written beside it. JSON. - [New recalls feed](https://recalldb.app/docs/new): Poll for recalls we first saw since a date, newest first, with stable ids and category and agency filters. Built for Zapier, Make, n8n and scripts. JSON. - [Recalls by company](https://recalldb.app/docs/company): Every U.S. agency recall filed under one company name across NHTSA, CPSC, FDA and USDA FSIS, newest 100 with counts by agency. JSON. - [Check many VINs](https://recalldb.app/docs/vins-batch): Check many VINs in one call: check digit, NHTSA vPIC decode, and the recalls filed for each make, model and year with the remedy. VINs are never stored. - [Decode a VIN](https://recalldb.app/docs/vin): Decode a VIN with NHTSA vPIC and get the model's recalls page. The VIN goes in the request body and is never stored or logged. - [Your usage](https://recalldb.app/docs/usage): See how many requests your RecallDB key has used this month, your limit, and when it resets. Calling it does not use up your quota. - [Data freshness](https://recalldb.app/docs/health): See when RecallDB last refreshed each official source (NHTSA, CPSC, FDA, USDA FSIS and more) and whether it is current. No API key needed. - [Create a watchlist](https://recalldb.app/docs/create-watchlist): Create a watchlist of makes, models, brands, categories and UPCs. When a matching recall is added or changed, your webhook gets a signed message. - [List your watchlists](https://recalldb.app/docs/list-watchlists): List your RecallDB watchlists with the makes, models, brands, categories or UPCs each one follows and the webhook it sends to, in one API request. - [Delete a watchlist](https://recalldb.app/docs/delete-watchlist): Delete one of your RecallDB watchlists with an authenticated API request. The webhook it used keeps working for your other watchlists. - [Create a webhook](https://recalldb.app/docs/create-webhook): Register an HTTPS address and get HMAC-signed JSON messages when a watchlist matches a new or changed recall. Retries with backoff and a delivery log. - [List your webhooks](https://recalldb.app/docs/list-webhooks): List your RecallDB webhooks with the URL, status and how many deliveries have failed in a row, in one authenticated API request. - [Delete a webhook](https://recalldb.app/docs/delete-webhook): Delete a RecallDB webhook and its delivery log with one API request. Watchlists that used it are kept, but they no longer send anywhere. - [Send a test message](https://recalldb.app/docs/test-webhook): Queue a signed test message to your RecallDB webhook to check that your endpoint receives it and your signature-checking code accepts it. - [Delivery log](https://recalldb.app/docs/webhook-deliveries): See the last 50 deliveries for a RecallDB webhook: whether each was sent, how many attempts it took, the response status and the next retry. - [All tutorials](https://recalldb.app/docs/tutorials): Step-by-step RecallDB API tutorials with tested code: VIN recall check in Python, barcode lookup in JavaScript, webhook alerts, MCP with Claude, and n8n or Zapier. - [Python: VIN to recalls](https://recalldb.app/docs/tutorials/python-vin-check): Decode a VIN and list the NHTSA recalls for that model and year in about 30 lines of Python, using the free RecallDB API. - [JavaScript: barcode lookup](https://recalldb.app/docs/tutorials/js-barcode-lookup): Look up a UPC, EAN or GTIN barcode in official recall notices with Node.js and the free RecallDB API, and show lot codes as the notice wrote them. - [Webhook alerts](https://recalldb.app/docs/tutorials/webhook-alerts): Get a signed message when a recall mentions your makes, brands or UPCs: register a webhook, create a watchlist, and verify the HMAC signature in Node.js. - [MCP with Claude](https://recalldb.app/docs/tutorials/mcp-claude): Connect Claude Code or Claude Desktop to the RecallDB MCP server with your API key, check the connection, and ask about vehicle, product and food recalls. - [n8n and Zapier](https://recalldb.app/docs/tutorials/n8n-zapier): Build a no-code new-recall alert in n8n or Zapier: poll /v1/new hourly or catch RecallDB webhooks, skip duplicates, and send the official link to Slack or email. - [All endpoints (curl)](https://recalldb.app/docs/endpoints): Every RecallDB API endpoint on one page with a ready-to-paste curl command: recalls, vehicles, VIN, barcode, search, new recalls, webhooks and usage. - [Errors](https://recalldb.app/docs/errors): Every RecallDB API error: status codes, error codes and what to do, including quota, rate limit and suspended-key responses. - [Rate limits](https://recalldb.app/docs/rate-limits): RecallDB rate limits: 1,000 free requests a month, 10 per minute, rate-limit response headers, and how fair-use checks warn, throttle and suspend keys. - [Attribution](https://recalldb.app/docs/attribution): Free RecallDB keys require "Data from RecallDB" with a link to recalldb.app wherever the data is shown. How to display it and what not to do. - [Data coverage](https://recalldb.app/docs/coverage): What recall data RecallDB covers: NHTSA vehicles, CPSC products, FDA food, drugs and devices, USDA FSIS, Canada and the UK, and what is not covered yet. ## MCP server - [RecallDB MCP server](https://recalldb.app/mcp): a hosted MCP server with the tools search_recalls, get_recall, barcode_lookup and vehicle_recalls, using your own API key (setup for Claude, Claude Code and other clients). ## Endpoints - GET /v1/recalls/{id}: One recall by its official number. - GET /v1/vehicles/{make}/{model}/{year}: The NHTSA recalls for one make, model and model year (up to 50). - GET /v1/recalls/{id}/history: What the agency changed in a recall since we first saw it. - GET /v1/search: Full-text search across every category, with filters. - GET /v1/barcode/{code}: Recalls whose official notice lists this barcode. - GET /v1/new: Recalls first seen since a date, newest first, for polling integrations. - GET /v1/companies/{id}: All recalls filed under one company name, across agencies. - POST /v1/vins/batch: Decode many VINs and list the recalls filed for each one's make, model and year. - POST /v1/vin: Decode a VIN to the vehicle and its model's recalls. - GET /v1/usage: Your key's usage this month, your limit and the reset date. - GET /v1/health: How fresh each data source is. No key needed. (no key needed) - POST /v1/watchlists: Create a watchlist of makes, models, brands, categories and UPCs. - GET /v1/watchlists: Your watchlists and your plan limits. - DELETE /v1/watchlists/{id}: Delete a watchlist. - POST /v1/webhooks: Register an HTTPS address that receives signed messages. - GET /v1/webhooks: Your webhooks and their status. - DELETE /v1/webhooks/{id}: Delete a webhook and its delivery log. - POST /v1/webhooks/{id}/test: Queue a signed test message. - GET /v1/webhooks/{id}/deliveries: The last 50 deliveries for a webhook. ## Specs - [OpenAPI 3.1](https://recalldb.app/openapi.json) - [Postman collection](https://recalldb.app/postman.json) - [Monthly data downloads](https://recalldb.app/data) and [Zapier, Make and n8n](https://recalldb.app/integrations) - [Changelog](https://recalldb.app/changelog) and [Status](https://recalldb.app/status): what changed, and when each source was last refreshed - [Pricing](https://recalldb.app/pricing): Free (beta), 1,000 requests a month for non-commercial use; Pro and Business are planned (waitlist). - [Full documentation in one file](https://recalldb.app/llms-full.txt): every endpoint with parameters, a curl example and notes, the limits, and the common questions. ## Coverage - Vehicles (NHTSA): 89 makes of passenger cars, SUVs, minivans and pickups, all model years, with the issuing company named - Other vehicles (NHTSA): heavy trucks, buses, trailers and every other NHTSA vehicle recall, by maker - Motorcycles (NHTSA): motorcycle and scooter recalls by brand, with model names and model years as NHTSA lists them - RVs (NHTSA): motorhome, travel trailer, fifth wheel and truck camper recalls from a reviewed list of RV makers - Car seats, tires and car equipment (NHTSA): child car seat, tire and other car equipment (lighting, wheels, hitches, accessories) recalls by brand - Consumer products (CPSC): recalls of toys, appliances, furniture, bikes and more, with model numbers and UPCs where listed - Pet food and cosmetics (FDA): pet food, animal feed and cosmetics recalls as FDA tags them in its recalls list (recalls only) - Dietary supplements (FDA): recall events whose FDA text calls the product a dietary supplement (recalls only) - Drugs (FDA): drug recall events from the FDA enforcement reports, recalls only, with lot and expiration codes as listed - Medical devices (FDA): medical device recall events from the FDA enforcement reports, recalls only, with model and lot codes as listed - Canada (Transport Canada, Health Canada, CFIA): vehicle, consumer product and food recall notices from the Government of Canada recalls and safety alerts open data (Open Government Licence – Canada); drugs, medical devices and natural health products are not included - United Kingdom (Food Standards Agency): food alerts (allergy alerts, recall information notices, food alerts for action) since 2018 (Open Government Licence v3.0) - Australia (ACCC (Product Safety Australia)): consumer product recalls from the official recalls feed, which holds only the most recent 100 (Creative Commons Attribution 4.0; source: ACCC © Commonwealth of Australia); older Australian recalls are not included - USDA meat, poultry and eggs (USDA FSIS): FSIS recalls (meat_poultry) and public health alerts (public_health_alert, not recalls) from 2014, imported by hand and updated periodically, not daily - Barcodes (CPSC and FDA): UPC, EAN and GTIN numbers read from CPSC and FDA notices (check digit verified), with the lot codes, best-by dates and serial numbers written beside them, for GET /v1/barcode/{code} - Food (FDA): food recall events from the FDA enforcement reports, with UPCs and lot codes as listed Last updated 2026-11-13. ## Common questions ### Is there a free recall API? Yes. RecallDB has a free (beta) tier: 1,000 requests a month and 10 a minute for non-commercial use, with a "Data from RecallDB" credit. Sign up at recalldb.app/signup and the key is shown at once after you confirm your email. A paid plan for commercial use is planned. ### How do I check VIN recalls programmatically? Send the VIN in the body of POST /v1/vin. It decodes the vehicle with NHTSA vPIC (the VIN is not stored) and returns the model-year recalls page; GET /v1/vehicles/{make}/{model}/{year} lists each NHTSA recall. To know whether one exact vehicle has an open recall, the owner still checks the VIN at nhtsa.gov/recalls. See the Python VIN tutorial. ### Is there recall data for the US, Canada, UK, EU and Australia? Yes: NHTSA, CPSC, FDA and USDA FSIS in the U.S.; Transport Canada, Health Canada and CFIA; the UK Food Standards Agency, OPSS and MHRA; EU Safety Gate; and Australia's ACCC. Every record names its agency and links the official notice. Filter with agency= on /v1/search and /v1/new. ### Can I look up a product recall by barcode (UPC or EAN)? Yes: GET /v1/barcode/{code} returns the recall notices that list that UPC, EAN or GTIN, with the lot codes and best-by dates exactly as the notice wrote them. A wrong check digit is refused. No match does not mean a product has no recall. ### How do I get notified about new recalls? Poll GET /v1/new (new recalls since a time, with category and agency filters), or register a webhook and a watchlist of makes, models, brands, categories or UPCs. Webhook messages are signed with HMAC-SHA256; on the free tier they are sent in an hourly batch. ### Can AI agents use RecallDB? Yes. The MCP server at recalldb.app/mcp (Streamable HTTP, your API key in the Authorization header) gives agents four read-only tools: search recalls, get a recall, look up a barcode and list vehicle recalls. It is listed in the official MCP Registry as app.recalldb/recalldb. ## Limits (Free, beta) Free (beta) keys: 1,000 requests per month and 10 per minute, for non-commercial use. One key per verified email. A 429 answer says which limit was reached and when to try again. Attribution is required ("Data from RecallDB" with a link to https://recalldb.app). There is no bulk export. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Policy. A 429 says which limit was reached (rate_limited or quota_exceeded) and when to retry. GET /v1/usage shows what is left and is not counted. ## Authentication Send your key as Authorization: Bearer rdb_... (or X-API-Key). Keys are never accepted in a URL. Keep the key on a server. ## Rules for using the data - Show "Data from RecallDB" with a link to https://recalldb.app wherever you show the data (free keys). - Show the agency and the official link from each record's source block. - Never tell anyone a car, product or food is "safe", "not recalled" or "unaffected" because nothing was found. Lot, serial and date codes are shown as the notice wrote them and are never matched for you. ## Errors - 400 bad_request: The request was not shaped right (a bad path value or body). The message says how to fix it. - 400 bad_barcode: The barcode number is not valid: it must be 8, 12, 13 or 14 digits with a correct check digit. - 400 bad_vin: The VIN is not 17 valid characters. - 401 missing_key: No API key was sent. Use the Authorization header. - 401 invalid_key: The key is not valid. - 401 revoked_key: The key was revoked. Write to support@recalldb.app. - 403 suspended_key: The key is suspended for usage that looked like bulk collection. Write to support@recalldb.app with your key id. - 403 plan_limit: A free key can have 1 watchlist and 1 webhook. Delete the existing one first; more is a planned Pro feature. - 404 not_found: We do not have that record. - 429 rate_limited: More than 10 requests in a minute (3 if the key was throttled). Wait for Retry-After. - 429 quota_exceeded: The key used its 1,000 free requests for the month. It resets on the 1st (UTC). - 503 unavailable: The data service could not answer. Try again. ## Endpoints in detail ### GET /v1/recalls/{id}: Get a recall Returns one recall with the agency's own text, a plain-English summary, and where the data came from. Use the NHTSA campaign number for vehicles and car equipment (21V215000), cpsc- plus the CPSC recall number for consumer products (cpsc-27064), and fda- plus the FDA event number for food (fda-98506). Parameters: - id (path, required): NHTSA campaign number, cpsc- or fda-. Not case sensitive. Example: 21V215000 Example: ```bash curl https://recalldb.app/v1/recalls/21V215000 \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - distribution says where the notice says it was sold: type is nationwide, states (with state codes) or not_specified, and as_listed is the notice's own wording. It is null for recalls with no distribution (vehicles, tires and others). A state list is only what the notice names: never a statement that an item was or was not sold to you. - The id in the response is exactly the id in the URL: NHTSA numbers in capitals (21V215000), cpsc- and fda- in lower case. source.official_id is the agency's own number (for CPSC and FDA, without the prefix). - units is the agency's wording (for example "About 265,000"). units_affected is the same count as a whole number, or null when the wording is not a clear single count (ranges, amounts in cases or pounds, no number). It is never a guess. - Lot, serial and date codes appear only as codes_as_listed, copied exactly as the agency wrote them. RecallDB never compares them with anything and never says whether a particular item is affected. - Recalls are added as they are published: NHTSA, CPSC and FDA food updates run every day. ### GET /v1/vehicles/{make}/{model}/{year}: Recalls for a vehicle Returns the recalls NHTSA lists for a model and model year, newest first, each with its own source block. Coverage: 89 makes of passenger cars, SUVs, minivans and pickups, all model years. Recalls are listed by model and year, so not every vehicle of that model is part of each recall: use the VIN endpoint plus NHTSA or the carmaker to check a specific car. Parameters: - make (path, required): Lowercase make name as on checkrecalls.org (honda, mercedes-benz, land-rover). Example: honda - model (path, required): Lowercase model name (civic, f-150, cx-5). Example: civic - year (path, required): Model year, any year NHTSA lists (for example 2019). Example: 2019 Example: ```bash curl https://recalldb.app/v1/vehicles/honda/civic/2019 \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Make and model names follow checkrecalls.org addresses, so /cars/honda/civic/2019 there is /v1/vehicles/honda/civic/2019 here. - A model-year page that is not published yet answers 404; check again later. ### GET /v1/recalls/{id}/history: Recall change history Agencies correct recalls: they widen the models, fix the remedy or change the number of units. We keep each change to an official field (problem, consequence, remedy, notes, units, issued by, date, components) as the field, the old value, the new value and the day we recorded it. The free tier returns the latest recorded change only. The full history of every change is a planned Pro feature (see pricing). A recall that has never changed returns an empty list. Parameters: - id (path, required): The recall id, as in /v1/recalls/{id}. Example: 21V215000 Example: ```bash curl https://recalldb.app/v1/recalls/21V215000/history \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. History starts on the day we began recording it (2026-11-13); changes before that are not known. ### GET /v1/search: Search recalls Searches recall records with the same full-text index as checkrecalls.org. It matches product names, brands, model numbers, recall numbers and UPCs across vehicles, motorcycles, RVs, car seats, tires, car equipment, consumer products, food, dietary supplements, drugs and medical devices. Each result has the same id you would use in /v1/recalls/{id}, and a source block with the agency, its own number and a link to the official notice. A search shows what the official notices mention. A search with no results never means a product has no recall. Parameters: - q (query, required): What to search for: at least 2 letters or numbers, at most 100 characters. Letters and numbers only are used. Example: bunk bed - category (query): vehicle, motorcycle, rv, car_seat, tire, equipment, consumer_product, food, dietary_supplement, drug, medical_device, ca_vehicle, ca_product, ca_food, uk_food, au_product, eu_product, uk_product, uk_medicine, meat_poultry or public_health_alert. Example: consumer_product - agency (query): nhtsa, cpsc, fda, usda, tc, hc, cfia or fsa. Example: cpsc - fuzzy (query): true (default) or false. When nothing matches, names (makes, models, brands, companies, product and food names) are tried with a corrected spelling, for example toyta becomes toyota, and meta.corrected_query says what was searched. Recall numbers, UPCs, model numbers, VINs and anything with a digit are always exact. fuzzy=false turns the correction off. Example: false - state (query): A U.S. state code such as TX. Keeps recalls sold nationwide, in that state, or with no clear distribution. A recall is only dropped when its notice clearly lists other states and not this one. Example: TX - from (query): Only recalls dated on or after this day (YYYY-MM-DD, as the agency dates them). Example: 2026-01-01 - to (query): Only recalls dated on or before this day. Example: 2026-06-30 - page (query): Page number, 1 to 20 (default 1). Example: 1 - per_page (query): Results per page, 1 to 50 (default 20). Example: 20 Example: ```bash curl https://recalldb.app/v1/search?q=bunk+bed&category=consumer_product \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Each search counts as one request against your quota and is checked by the same fair-use rules as every other endpoint. Paging is capped at 20 pages of 50 (1,000 matches): narrow the search instead of paging further. meta.total is the real number of matches up to 10,000; when there are more, meta.total is 10000 and meta.capped is true (read it as "10,000 or more"). Only the first 1,000 matches can be paged, whatever the total. - Dates in the results are the agencies' own dates (ISO, no time zone). Other dates in the API are ISO dates in UTC; the checkrecalls.org pages show "last updated" in U.S. Eastern time. - Only published records are searched. Bulk collection by searching term after term is not allowed (see acceptable use). ### GET /v1/barcode/{code}: Look up a barcode Send any barcode number: UPC-A (12 digits), EAN-13, GTIN-14, or the short UPC-E and EAN-8, with or without spaces and dashes. We check the last digit (the check digit), turn the number into one standard form, and return the recalls whose official notice lists it. A number whose check digit is wrong is refused, because it is not a real barcode. A match means the code appears in a notice. Notices often list a barcode for a whole product line while only certain lots or dates are recalled, so each match includes the lot codes, best-by dates and serial numbers written near the barcode, exactly as the notice words them. We never compare them with your item and never say an item is or is not affected. No match is not an answer about your item: not every recall lists barcodes, so also search by product name with /v1/search. Parameters: - code (path, required): A barcode number, 8, 12, 13 or 14 digits. Spaces and dashes are ignored. Example: 036000291452 Example: ```bash curl https://recalldb.app/v1/barcode/036000291452 \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. A bad check digit returns 400 with code bad_barcode. - The lot, best-by and serial lists are the notice's own words found near the barcode; they can be empty even when the notice lists lots elsewhere, so always read the official notice. ### GET /v1/new: New recalls feed Returns the recalls we first saw on or after since (default: the last 7 days, never more than 30), newest first. Each has a stable id, so a tool can skip ones it already has. Filter with category and agency. This is the endpoint Zapier, Make and n8n use as a "New recall" trigger: poll it, treat each id as a new item once. For instant delivery instead of polling, use a webhook (see the Webhooks docs). Parameters: - since (query): A date or time, like 2026-11-01 or 2026-11-01T12:00:00Z. Default: 7 days ago. Older than 30 days is treated as 30 days. Example: 2026-11-01 - category (query): Only this category, as in /v1/search (vehicle, consumer_product, food, drug, and so on). Example: consumer_product - agency (query): Only this agency: nhtsa, cpsc, fda, usda, tc, hc, cfia, fsa, accc, eusg, opss or mhra. Example: cpsc - limit (query): How many, 1 to 50 (default 20). Example: 5 Example: ```bash curl https://recalldb.app/v1/new?category=consumer_product&limit=5 \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Each call counts as one request against your quota: a poll every 15 minutes is about 2,900 requests a month, so poll no faster than once an hour on a free key, or use a webhook. - Free keys get this feed from a copy that is up to 1 hour old (meta.cache says when it was made). A live feed is a planned Pro feature. - first_seen is when we first saw the recall, which can be days after the agency's date. ### GET /v1/companies/{id}: Recalls by company The id is the company address on checkrecalls.org (/company/ford-motor). Companies need at least two recalls. Names are matched as the agencies wrote them (case, punctuation and endings like Inc or LLC are ignored); companies with similar names can be listed separately. A listing is a notice that names the company. It does not say whether an item is or is not affected. Parameters: - id (path, required): The company id from its checkrecalls.org address. Example: ford-motor Example: ```bash curl https://recalldb.app/v1/companies/ford-motor \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. A company with fewer than two recalls returns 404. ### POST /v1/vins/batch: Check many VINs Send up to 5 VINs per call on a free key (each VIN counts as one request); up to 100 per call is planned for Pro. Each VIN is checked (17 characters, no I, O or Q, and the North American check digit), decoded with NHTSA vPIC, and matched to the NHTSA recalls filed for its make, model and model year, with the remedy as NHTSA wrote it. This lists recalls filed for the model year. It does not say whether one exact vehicle still has an open recall: no official free API offers that, so check each VIN at nhtsa.gov/recalls or with a dealer. VINs are used in memory only and are never logged or stored. Parameters: - vins (body, required): The VINs, 17 characters each. Example: 1HGCM82633A004352 Example: ```bash curl -X POST https://recalldb.app/v1/vins/batch \ -H "Authorization: Bearer $RECALLDB_KEY" \ -H "Content-Type: application/json" \ -d '{"vins": ["1HGCM82633A004352", "5YJ3E1EA7KF317000"]}' ``` Notes: - status is one of ok, invalid, check_digit_mismatch, not_decoded, not_covered, unavailable. None of them means a vehicle has no recall. - More VINs than your plan allows per call answers 400 batch_too_large; a call that would pass the monthly quota answers 429 quota_exceeded before anything is counted. ### POST /v1/vin: Decode a VIN Decodes a 17-character VIN with NHTSA vPIC and points to the model's recalls. The VIN is sent in the request body (never in a URL), is used in memory only, and is never stored, logged or echoed. This identifies the model. It does not say whether that exact vehicle has an open recall: check the VIN with NHTSA (nhtsa.gov/recalls) or the carmaker. Parameters: - vin (body, required): A 17-character VIN (letters and digits, no I, O or Q). Example: 1HGCM82633A004352 Example: ```bash curl -X POST https://recalldb.app/v1/vin \ -H "Authorization: Bearer $RECALLDB_KEY" \ -H "Content-Type: application/json" \ -d '{"vin": "1HGCM82633A004352"}' ``` Notes: - status is one of ok, none-found, not-decoded, not-covered, unavailable. none-found never means a vehicle has no recalls. ### GET /v1/usage: Your usage Returns how many requests the key has used this month, the monthly limit, how many are left, and when the count resets. Calling this endpoint does not count against your quota and is not part of the fair-use checks, and it still answers when the quota is used up. Example: ```bash curl https://recalldb.app/v1/usage \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - The same numbers are in the X-RateLimit-* headers of every keyed response. ### GET /v1/health: Data freshness Returns each source and when it last refreshed successfully. A source marked stale has not refreshed within its window; treat its absence-of-recalls answers with care. Example: ```bash curl https://recalldb.app/v1/health ``` ### POST /v1/watchlists: Create a watchlist A watchlist is the list of things you want to hear about. Add at least one of makes, models, brands, categories or upcs (up to 10 values in all on a free key). When a recall that mentions any of them is added or changed, the watchlist's webhook is sent a message. A match means the notice mentions your value. It never says that your item is or is not affected: your customers should read the official notice and compare lot codes and dates. Parameters: - name (body, required): A name for the watchlist, 1 to 60 characters. Example: My brands - makes (body): Vehicle makes, as on checkrecalls.org (for example Honda). Matches recalls that list that make. Example: ["Honda"] - models (body): Vehicle models. Matches the model name exactly (Civic matches Civic, not Civic Type R). Example: ["Civic"] - brands (body): Brand or company names. Matches whole words in the notice title or the issuing company. Example: ["Graco"] - categories (body): Categories as used by /v1/search: vehicle, motorcycle, rv, car_seat, tire, equipment, other_vehicle, consumer_product, food, dietary_supplement, pet_food, cosmetic, drug, medical_device. Example: ["car_seat"] - upcs (body): Barcode numbers (UPC-A, EAN-13, GTIN-14, with a correct check digit). Matches notices that list the barcode. Example: ["036000291452"] - webhook_id (body): The id of one of your webhooks. Matches are sent there. Example: wh_3f9a1c07b2d4 Example: ```bash curl -X POST https://recalldb.app/v1/watchlists \ -H "Authorization: Bearer $RECALLDB_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "My brands", "brands": ["Graco"], "categories": ["car_seat"], "webhook_id": "wh_3f9a1c07b2d4"}' ``` Notes: - Free keys can have 1 watchlist of up to 10 values and 1 webhook; unlimited watchlists are a planned Pro feature (see pricing). A second watchlist, or too many values, answers 403 plan_limit or 400. - Counts as one request. ### GET /v1/watchlists: List your watchlists Returns your watchlists with their values and webhook, and the limits of your plan. Example: ```bash curl https://recalldb.app/v1/watchlists \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ### DELETE /v1/watchlists/{id}: Delete a watchlist Deletes the watchlist and its values. The webhook is kept. Parameters: - id (path, required): The watchlist id, such as wl_8c1d2e3f4a5b. Example: wl_8c1d2e3f4a5b Example: ```bash curl -X DELETE https://recalldb.app/v1/watchlists/wl_8c1d2e3f4a5b \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ### POST /v1/webhooks: Create a webhook Register a public HTTPS address (port 443, no IP addresses or local names). The response includes a secret that is shown only once; keep it to check the signature on every message. Each message is a POST with a JSON body and these headers: X-RecallDB-Event (recall.added, recall.changed or test), X-RecallDB-Delivery, X-RecallDB-Timestamp (Unix seconds) and X-RecallDB-Signature, which looks like t=1763035200,v1=. The signature is the HMAC-SHA256 of the timestamp, a dot and the exact body text, keyed with your secret. Recompute it, compare it in constant time, and reject messages whose timestamp is more than 5 minutes old. Answer with any 2xx status within 8 seconds. Redirects are not followed. Anything else is retried up to 6 times in all, waiting 1, 5, 30, 120 and 360 minutes. Use X-RecallDB-Delivery or the body id to ignore a message you already handled. A webhook that fails 30 times in a row is switched off. Parameters: - url (body, required): The https address that receives the messages. Example: https://example.com/recalls Example: ```bash curl -X POST https://recalldb.app/v1/webhooks \ -H "Authorization: Bearer $RECALLDB_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/recalls"}' ``` Notes: - Node example to check a message: compute crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex") and compare it with v1. - Free keys can have 1 webhook. Its messages are sent together once an hour (at the top of the hour, UTC), each still as its own signed POST; delivery within minutes is a planned Pro feature. - Counts as one request. ### GET /v1/webhooks: List your webhooks Returns your webhooks with their status (active or disabled) and consecutive failures. Secrets are never shown again. Example: ```bash curl https://recalldb.app/v1/webhooks \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ### DELETE /v1/webhooks/{id}: Delete a webhook Deletes the webhook and its delivery log. Watchlists that sent to it are kept and have no webhook until you create one. Parameters: - id (path, required): The webhook id, such as wh_3f9a1c07b2d4. Example: wh_3f9a1c07b2d4 Example: ```bash curl -X DELETE https://recalldb.app/v1/webhooks/wh_3f9a1c07b2d4 \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ### POST /v1/webhooks/{id}/test: Send a test message Queues a message of type test with no recall attached. It is sent within about 5 minutes, signed like every other message, and shows in the delivery log. Parameters: - id (path, required): The webhook id. Example: wh_3f9a1c07b2d4 Example: ```bash curl -X POST https://recalldb.app/v1/webhooks/wh_3f9a1c07b2d4/test \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ### GET /v1/webhooks/{id}/deliveries: Delivery log Returns the last 50 deliveries with their state (pending, delivered or failed), number of attempts, the last response status or error and the time of the next retry. Entries are kept for 30 days. Parameters: - id (path, required): The webhook id. Example: wh_3f9a1c07b2d4 Example: ```bash curl https://recalldb.app/v1/webhooks/wh_3f9a1c07b2d4/deliveries \ -H "Authorization: Bearer $RECALLDB_KEY" ``` Notes: - Counts as one request. ## Tutorials - [Python Tutorial: Check a VIN for Recalls with the RecallDB API](https://recalldb.app/docs/tutorials/python-vin-check): Decode a VIN and list the NHTSA recalls for that model and year in about 30 lines of Python, using the free RecallDB API. - [JavaScript Tutorial: Look Up a Barcode in Recall Notices](https://recalldb.app/docs/tutorials/js-barcode-lookup): Look up a UPC, EAN or GTIN barcode in official recall notices with Node.js and the free RecallDB API, and show lot codes as the notice wrote them. - [Tutorial: Recall Alerts with Webhooks and Signature Checks](https://recalldb.app/docs/tutorials/webhook-alerts): Get a signed message when a recall mentions your makes, brands or UPCs: register a webhook, create a watchlist, and verify the HMAC signature in Node.js. - [Tutorial: Use the RecallDB MCP Server with Claude](https://recalldb.app/docs/tutorials/mcp-claude): Connect Claude Code or Claude Desktop to the RecallDB MCP server with your API key, check the connection, and ask about vehicle, product and food recalls. - [Tutorial: New Recall Alerts in n8n and Zapier](https://recalldb.app/docs/tutorials/n8n-zapier): Build a no-code new-recall alert in n8n or Zapier: poll /v1/new hourly or catch RecallDB webhooks, skip duplicates, and send the official link to Slack or email.