# FDA 510(k) Scraper - Device Clearances Data (`dataio/openfda-510k-device-clearances`) Actor

Scrape FDA 510(k) medical device clearances from openFDA with the actual review time in days, plus the applicant's address and contact. Filter by product code, company, decision date, state and decision. Track competitors' clearances and regulatory timelines.

- **URL**: https://apify.com/dataio/openfda-510k-device-clearances.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 clearances

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does FDA 510(k) Scraper do?

Every FDA 510(k) medical device clearance — with **the actual review time in
days**, and the applicant's address and named contact.

**No login. No API key. No proxies.**

### The number openFDA has but never gives you

openFDA publishes `date_received` and `decision_date` on every 510(k). It
never subtracts them. So the one question every regulatory affairs team asks
before filing — *how long will this actually take in my product code?* — has
no published answer.

This Actor does the subtraction, on every row, and reports the distribution.

Measured on real data:

| Scope | Median | 90th percentile |
|---|---|---|
| All 2026 clearances | **131 days** | 274 days |
| Product code QJP (neurovascular catheters) | **164 days** | 258 days |
| Medtronic, 2024-2026 | **93 days** | 216 days |

A large sponsor clears in 93 days where the category takes 164. That gap is
competitive intelligence, and it is not in any export you can buy off the
shelf.

Coverage is excellent: in testing, **100 % of rows had a review time, an
address and a named contact**.

### Output

One row per clearance:

| Field | Example |
|---|---|
| `kNumber` | K261549 |
| `applicant` | MicroVention, Inc., d/b/a Terumo Neuro |
| `deviceName` | BOBBY Balloon Guide Catheter |
| `productCode` | QJP |
| `dateReceived` | 2026-05-11 |
| `decisionDate` | 2026-06-09 |
| **`reviewDays`** | **29** |
| `decisionCode`, `decisionDescription` | SESE, Substantially equivalent |
| `clearanceType`, `expeditedReview`, `thirdPartyReview` | |
| `advisoryCommittee` | Cardiovascular |
| `contact`, `address`, `city`, `state`, `postalCode`, `country` | |
| `fdaUrl` | direct link to the FDA record |

`reviewDays` is left empty rather than guessed when a date is missing or
inconsistent — a negative duration is a source error, not a fast review.

#### `expeditedReview` is almost always empty, and that is correct

Counted across the whole openFDA 510(k) database on 17 September 2026:
`expedited_review_flag` is set to `Y` on **28 records out of 176,070** —
0.016%. You will not see it in a sample, and its absence is not a
failure of the extraction. It is kept because those 28 records are
exactly what someone auditing expedited pathways is looking for; search
for them directly rather than expecting them to turn up.

For routing information that is actually populated, use `clearanceType`,
which is present on every record:

| `clearanceType` | Records |
|---|---|
| Traditional | 156,757 |
| Special | 16,144 |
| Abbreviated | 2,600 |
| Direct | 379 |
| Post-NSE | 110 |
| Dual Track | 80 |

### Input

```json
{
  "decisionFrom": "2026-01-01",
  "decisionTo": "2026-12-31",
  "productCode": "QJP",
  "maxItems": 500
}
```

| Field | Default | Notes |
|---|---|---|
| `decisionFrom` / `decisionTo` | 2026 | Decision date range |
| `productCode` | — | The sharpest filter — see below |
| `applicant` | — | Company name |
| `deviceName` | — | Free text on the device name |
| `decisionCode` | — | SESE, STNE, STWD and others |
| `state`, `country` | — | Applicant location |
| `maxItems` | `500` | Up to 25,000 |

**Use `productCode`.** A market-wide median is a vanity number; the
three-letter FDA code isolates your actual pathway, and that median is the
one you can plan against.

### Use cases

- **Regulatory planning** — the real review-time distribution for your
  product code, not a market average.
- **Competitive monitoring** — who cleared what, when, in your category.
- **Benchmarking** — compare your review times against the category and
  against named competitors.
- **Consulting and BD** — companies actively clearing devices in a category,
  with address and contact.
- **Market entry** — which foreign manufacturers are entering the US market
  and through which codes.

### Running this as a scheduled watch

Clearances are a competitive signal: a device cleared in your category
is a product about to reach the market, and `reviewDays` tells you how
long the pathway took.

```json
{
  "productCode": "QJP",
  "decidedWithinDays": 30,
  "maxItems": 200
}
```

Thirty days rather than seven: the FDA publishes in batches, and a
seven-day window is often empty.

**Why not fixed `decisionFrom` / `decisionTo`?** A schedule replays the
same input every time. A fixed range returns the same clearances at
every run. `decidedWithinDays` overrides both and moves on its own.

***

### Limits, honestly

- **openFDA refuses to paginate beyond 25,000 results.** Deeper history
  needs a narrower period or a product code; the Actor warns instead of
  looping silently.
- Review time measures **calendar days from receipt to decision**. It
  includes any hold or additional-information cycle, which is usually what
  you want to plan against, but it is not the FDA's internal review clock.
- Contact and address are as filed with the submission, so they can be
  years old for older clearances.
- 510(k) only. PMA and De Novo pathways are different datasets.
- Requests are paced out of courtesy to a free public service.
- Not affiliated with the FDA.

### How much does it cost?

You pay per clearance returned: **$0.006 each**, that is $6.00 per 1,000. There is no start fee, and subscription plans pay less per clearance.

The example input below asks for up to 200 clearances, so it costs **$1.20 at most**.

If a run reaches the spending limit you set, the output stops at that limit and never goes past it. You are never charged for rows that were not delivered.

### Use FDA 510(k) Scraper as an API

Call it from your own code with the Apify client, here in Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("DataIO/openfda-510k-device-clearances").call(run_input={
    'decisionFrom': '2026-01-01',
    'decisionTo': '2026-12-31',
    'maxItems': 200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

It also works from JavaScript, Make, Zapier, n8n, and from AI agents through the Apify MCP server.

### Other actors you might like

- [FDA Recalls Scraper](https://apify.com/DataIO/openfda-recalls-enforcement): openFDA Enforcement
- [NPI Registry Scraper](https://apify.com/DataIO/nppes-npi-provider-registry): US Healthcare Providers
- [CMS Open Payments Scraper](https://apify.com/DataIO/cms-open-payments-physicians): Physician Payments

### FAQ

#### Is it legal to use this data?

The actor reads public data from its official source, without logging in and without bypassing any access control. What you do with the data, for example contacting people listed in it, is your responsibility under the laws that apply to you, such as GDPR in Europe.

#### Can I run it on a schedule?

Yes. See *Running this as a scheduled watch* above: use the rolling-window setting so each run returns only what is new.

#### Can AI agents use it?

Yes. It is available through the Apify MCP server, and every input field is described in its input schema, so an agent can call it directly.

# Actor input Schema

## `decidedWithinDays` (type: `integer`):

Rolling window, for a scheduled watch: 30 returns clearances decided in the last thirty days. Unlike a fixed date range, this moves on its own. Overrides Decided from and Decided until.

## `decisionFrom` (type: `string`):

Start of the decision date range, as YYYY-MM-DD.

## `decisionTo` (type: `string`):

End of the decision date range, as YYYY-MM-DD.

## `productCode` (type: `string`):

The FDA three-letter device code, for example QJP or MOS. This is the sharpest filter there is: it isolates one device category, so the review times you get describe your own pathway rather than a market-wide average.

## `applicant` (type: `string`):

Applicant name, for example "Medtronic" or "Boston Scientific".

## `maxItems` (type: `integer`):

One row per clearance. openFDA refuses to paginate beyond 25,000 results, so narrow the period or the product code to reach deeper history.

## `deviceName` (type: `string`):

Free text matched against the device name, for example "catheter" or "glucose".

## `decisionCode` (type: `string`):

Leave empty for every decision. Most clearances are SESE.

## `state` (type: `string`):

Two-letter US state code, for example CA or MA.

## `country` (type: `string`):

Two-letter country code, for example US, DE, CN.

## Actor input object example

```json
{
  "decidedWithinDays": 30,
  "decisionFrom": "2026-01-01",
  "decisionTo": "2026-12-31",
  "maxItems": 500
}
```

# Actor output Schema

## `results` (type: `string`):

Every row produced by the run, in JSON.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "decidedWithinDays": 30,
    "decisionFrom": "2026-01-01",
    "decisionTo": "2026-12-31",
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/openfda-510k-device-clearances").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "decidedWithinDays": 30,
    "decisionFrom": "2026-01-01",
    "decisionTo": "2026-12-31",
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/openfda-510k-device-clearances").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "decidedWithinDays": 30,
  "decisionFrom": "2026-01-01",
  "decisionTo": "2026-12-31",
  "maxItems": 500
}' |
apify call dataio/openfda-510k-device-clearances --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataio/openfda-510k-device-clearances"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AjCg3VaqHgXIMHcs7/builds/Rz7nOW8pmmvROnlVI/openapi.json
