# ChEMBL Drug Pipeline Scraper - Phases & Approvals (`dataio/chembl-drug-pipeline-approvals`) Actor

Extract drug pipeline data from ChEMBL: which molecules target which disease, at what development phase, with approval year, drug class, route and safety flags such as boxed warnings and withdrawals. Search by indication and minimum phase. Public data, no API key.

- **URL**: https://apify.com/dataio/chembl-drug-pipeline-approvals.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** MCP servers
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 molecule rows

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 ChEMBL Drug Pipeline Scraper do?

Which molecules target which disease, **at what development phase** — with
approval year, drug class, route of administration and safety flags.

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

### The join ChEMBL does not make

ChEMBL publishes 2.9 million molecules on one side and 60,055 indications on
the other, and never joins them. The question a competitive intelligence
team actually asks lives in the join:

> *What is in development for Alzheimer's, at phase III or above, and who
> else is there?*

Give this Actor an indication and it queries the indications, collects the
molecules, enriches them in batches, and returns one row per
molecule-indication pair — with the phase reached **for that indication
specifically**, which is not the same as the molecule's highest phase
elsewhere.

| Molecule | Indication | Phase | Class |
|---|---|---|---|
| RIVASTIGMINE | Alzheimer disease | 4 | cholinesterase inhibitors |
| DONEPEZIL | Alzheimer disease | 4 | acetylcholinesterase inhibitors |
| SEMAGACESTAT | Alzheimer disease | 3 | enzyme inhibitors: gamma secretase |

306 molecules have been developed for Alzheimer's; 80 reached phase III or
beyond.

### Two fields made readable

**`developmentStage`.** ChEMBL returns `max_phase: 4.0` and stops. Here that
also arrives as *Approved*, *Phase III*, *Phase II*, *Phase I* or
*Preclinical*, so nobody has to carry the scale in their head.

**`drugClass`.** Drug names encode their pharmacology in the suffix — `-mab`
is a monoclonal antibody, `-tinib` a kinase inhibitor. ChEMBL records the
expansion in `usan_stem_definition`, and almost nobody surfaces it. Here it
is a plain column: *monoclonal antibodies: fully human*, *acetylcholinesterase
inhibitors*, *peroxisome proliferator activated receptor agonists*. Measured
on approved antibodies: **100 % populated**.

### Output

| Field | Example |
|---|---|
| `name`, `chemblId` | RIVASTIGMINE, CHEMBL636 |
| `indication`, `indicationPhase` | Alzheimer disease, 4 |
| `meshHeading`, `efoId` | ontology identifiers |
| `maxPhase`, `developmentStage` | 4.0, Approved |
| `firstApproval` | 1997 |
| `moleculeType` | Small molecule / Antibody / Protein |
| `drugClass`, `usanStem` | cholinesterase inhibitors, `-stigmine` |
| `atcCodes`, `atcLevel1` | N06DA03, N |
| `routes` | oral, parenteral, topical |
| `blackBoxWarning`, `withdrawn`, `orphanDrug` | safety and status flags |
| `firstInClass`, `prodrug`, `naturalProduct` | |
| `molecularWeight`, `alogp`, `polarSurfaceArea`, `ro5Violations`, `qedWeighted` | drug-likeness |
| `formula`, `smiles`, `inchiKey` | structure |
| `synonyms` | development codes and trade names |

### Input

```json
{
  "indication": "Alzheimer",
  "minPhase": "3",
  "maxItems": 500
}
```

| Field | Default | Notes |
|---|---|---|
| `indication` | `Alzheimer` | Switches to the pipeline view |
| `minPhase` | — | 3 and above is the near-term competitive set |
| `maxItems` | `500` | Rows, sorted most advanced first |
| `moleculeType` | `all` | No indication: small molecule, antibody, … |
| `approvedSince` | — | Only 391 molecules approved since 2020 |
| `withdrawnOnly` | `false` | 364 molecules withdrawn from a market |
| `blackBoxOnly` | `false` | 936 carry the strongest FDA warning |
| `firstInClassOnly` | `false` | 352 opened a new class |

Leave `indication` empty and the filters below it apply to molecules
directly — useful for "every approved antibody" or "every withdrawn drug".

### Use cases

- **Competitive intelligence** — the full development set for an
  indication, by phase.
- **Business development and licensing** — molecules at phase II or III in
  a therapeutic area.
- **Safety and pharmacovigilance** — withdrawn drugs and black-box
  warnings, with their classes.
- **Chemistry and screening** — structures, drug-likeness and Lipinski
  violations for a filtered set.
- **Market and regulatory analysis** — approvals by year, class and route.

### Limits, honestly

- **ChEMBL is not a live clinical trial registry.** Phases reflect what has
  been curated from the literature and regulatory sources, and lag current
  trial status. For active recruitment, use ClinicalTrials.gov.
- **Indication search is text matching** on the EFO term, so "cancer"
  returns many distinct conditions. Check `indication` on the rows.
- **`indicationPhase` and `maxPhase` differ on purpose.** A drug approved
  for one condition may be at phase II for another; the first is
  indication-specific, the second is the molecule's highest anywhere.
- Antibodies, proteins and cell therapies have no SMILES — the structural
  columns are empty for them by nature, not by omission.
- `drugClass` is derived from the naming stem, so molecules without a USAN
  stem have it blank. Measured: 65 % on a mixed Alzheimer set, 100 % on
  approved antibodies.
- Requests are paced out of courtesy to a free public service run by the
  EMBL-EBI.
- Not affiliated with ChEMBL or the EMBL-EBI.

### How much does it cost?

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

The example input below asks for up to 500 molecule rows, so it costs **$3.00 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 ChEMBL Drug Pipeline 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/chembl-drug-pipeline-approvals").call(run_input={'indication': 'Alzheimer', 'maxItems': 500})
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 510(k) Scraper](https://apify.com/DataIO/openfda-510k-device-clearances): Device Clearances Data
- [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

### 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. Create a schedule in Apify Console, daily or weekly for example, and each run delivers a fresh dataset, which you can send by email, webhook or integration.

#### 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

## `indication` (type: `string`):

Disease or condition, for example Alzheimer, breast cancer, type 2 diabetes. Supplying one switches to the pipeline view: every molecule developed for that condition, with the phase reached for that indication specifically.

## `minPhase` (type: `string`):

Phase III and above is the near-term competitive set. Leave empty for every phase including preclinical.

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

With an indication, one row per molecule-indication pair. Without one, one row per molecule.

## `moleculeType` (type: `string`):

Only applies when no indication is given.

## `approvedSince` (type: `integer`):

Year, for example 2020. Only 391 molecules in ChEMBL have a first approval from 2020 onwards, so this is a sharp filter.

## `withdrawnOnly` (type: `boolean`):

364 molecules have been withdrawn from a market. Useful for safety and due-diligence work.

## `blackBoxOnly` (type: `boolean`):

936 molecules carry the FDA's strongest warning.

## `firstInClassOnly` (type: `boolean`):

352 molecules opened a new pharmacological class.

## Actor input object example

```json
{
  "indication": "Alzheimer",
  "maxItems": 500,
  "moleculeType": "all",
  "withdrawnOnly": false,
  "blackBoxOnly": false,
  "firstInClassOnly": false
}
```

# 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 = {
    "indication": "Alzheimer",
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/chembl-drug-pipeline-approvals").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 = {
    "indication": "Alzheimer",
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/chembl-drug-pipeline-approvals").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 '{
  "indication": "Alzheimer",
  "maxItems": 500
}' |
apify call dataio/chembl-drug-pipeline-approvals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataio/chembl-drug-pipeline-approvals"
        }
    }
}
```

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/dAViUSkz26ADJppi1/builds/SopA48VoDakOacSpH/openapi.json
