# PubChem Compounds Scraper (`automation-lab/pubchem-compound-batch-lookup`) Actor

Resolve PubChem compounds in batches by CID, name, SMILES, InChI, or formula. Export normalized identity, structures, molecular properties, bounded synonyms, input resolution, and official source provenance.

- **URL**: https://apify.com/automation-lab/pubchem-compound-batch-lookup.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Education
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.96 / 1,000 item extracteds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PubChem Compounds Scraper

Resolve PubChem compounds in batches by CID, chemical name, SMILES, InChI, or molecular formula.
The Actor calls the official anonymous PubChem PUG REST service and exports normalized compound identity,
structure identifiers, molecular properties, bounded synonyms, input-resolution context, and source provenance.
No PubChem API key, browser, account, or proxy is required.

Use it to turn recurring identifier lists into integration-ready chemistry records without building request pacing,
retry handling, one-to-many formula resolution, normalization, or Apify dataset delivery yourself.

### What does this Actor do?

For every submitted identifier, the Actor:

1. validates the declared identifier type;
2. resolves it to one or more PubChem CIDs;
3. bounds one-to-many matches with `maxResultsPerInput`;
4. retrieves normalized identity, structure, and molecular properties;
5. retrieves up to `maxSynonyms` synonyms;
6. preserves the original input and match rank;
7. emits explicit missing-result or lookup-failure status rows; and
8. links every resolved record to its PubChem page and official API endpoint.

The result is one default Apify dataset suitable for JSON, CSV, Excel, API, webhook, and automation integrations.

### Who is it for?

- **Cheminformatics teams** enriching structure registries or assay inputs.
- **Pharmaceutical researchers** normalizing names and structure identifiers to authoritative CIDs.
- **Data engineers** cleaning mixed identifier columns before warehouse ingestion.
- **Laboratory operations teams** adding formula, mass, structure, and synonym context to sample lists.
- **Toxicology and materials researchers** preparing reproducible compound datasets.
- **Developers** who want managed PubChem API pacing, retries, datasets, schedules, and webhooks.

This Actor resolves compound records. It does not scrape PubChem BioAssay data, patents, literature, vendor offers,
or perform similarity, substructure, or biological-activity analysis.

### Why use this PubChem compound lookup?

A single run can mix identifier namespaces while preserving exactly how every output was resolved.
The output includes both machine identifiers and practical molecular properties.
Formula searches are explicitly bounded because one formula can represent many compounds.
Synonym requests degrade safely: if only synonyms fail, the useful property record is still returned.
Transient network errors, rate limits, and temporary PubChem failures use bounded retries.

The implementation is HTTP-only, runs at 256 MB, and does not add browser or proxy overhead.

### Supported identifiers

| Type | Example | Resolution behavior |
| --- | --- | --- |
| `cid` | `2244` | Uses the exact PubChem Compound ID |
| `name` | `aspirin` | Resolves a chemical, common, or registry name through PubChem |
| `smiles` | `CC(=O)OC1=CC=CC=C1C(=O)O` | Uses the official form-encoded SMILES route |
| `inchi` | `InChI=1S/CH4/h1H4` | Uses the official form-encoded InChI route |
| `formula` | `C9H8O4` | Returns bounded ranked matches from PubChem fast formula search |
| `auto` | `2244` or `caffeine` | Detects numeric CIDs; other values are treated as names |

Declare `smiles`, `inchi`, and `formula` explicitly. Automatic mode intentionally does not guess among these
potentially ambiguous syntaxes.

### Data you receive

Each dataset row includes:

- original `inputIndex`, `inputValue`, and resolved `inputType`;
- `resolutionRank` for one-to-many matches;
- resolution status for successful, missing, or failed lookups;
- PubChem `cid`, preferred `title`, and `iupacName`;
- `molecularFormula`, `molecularWeight`, `exactMass`, and `monoisotopicMass`;
- `canonicalSmiles`, `isomericSmiles`, `inchi`, and `inchiKey`;
- `xlogp`, `tpsa`, and PubChem `complexity`;
- formal electrical state and hydrogen-bond donor/acceptor counts;
- rotatable-bond, heavy-atom, and covalent-unit counts;
- a bounded `synonyms` array;
- `sourceUrl`, `sourceApiUrl`, and `retrievedAt`; and
- a bounded `error` message when resolution does not succeed.

Fields can be null when PubChem does not report a value for a compound.

### How to run the Actor

1. Open the Actor in Apify Console.
2. Add one or more objects to **Compounds to resolve**.
3. Select the identifier `type` for each value.
4. Set the output, per-input match, and synonym limits.
5. Click **Start**.
6. Open the **Dataset** tab to inspect or export results.

Start small when testing broad molecular formulas, because a formula may map to many CIDs.

### Input parameters

| Field | Type | Default | Limit | Description |
| --- | --- | --- | --- | --- |
| `compounds` | array | sample mixed batch | 1–1,000 | Objects containing `value` and an identifier `type` |
| `maxItems` | integer | `100` | 1–5,000 | Maximum resolved or unresolved dataset rows |
| `maxResultsPerInput` | integer | `5` | 1–25 | Maximum CIDs retained for each submitted input |
| `maxSynonyms` | integer | `20` | 0–100 | Maximum synonyms per resolved compound; zero skips synonym calls |

Example input:

```json
{
  "compounds": [
    { "value": "aspirin", "type": "name" },
    { "value": "2244", "type": "cid" },
    { "value": "CC(=O)OC1=CC=CC=C1C(=O)O", "type": "smiles" },
    { "value": "C8H10N4O2", "type": "formula" }
  ],
  "maxItems": 10,
  "maxResultsPerInput": 3,
  "maxSynonyms": 10
}
```

### Output example

This abbreviated row comes from a real current run:

```json
{
  "inputIndex": 0,
  "inputValue": "aspirin",
  "inputType": "name",
  "resolutionRank": 1,
  "status": "resolved",
  "cid": 2244,
  "title": "Aspirin",
  "iupacName": "2-acetyloxybenzoic acid",
  "molecularFormula": "C9H8O4",
  "molecularWeight": 180.16,
  "canonicalSmiles": "CC(=O)OC1=CC=CC=C1C(=O)O",
  "inchiKey": "BSYNRYMUTXBXSQ-UHFFFAOYSA-N",
  "xlogp": 1.2,
  "tpsa": 63.6,
  "synonyms": ["aspirin", "ACETYLSALICYLIC ACID", "50-78-2"],
  "sourceUrl": "https://pubchem.ncbi.nlm.nih.gov/compound/2244",
  "error": null
}
```

An unresolved input still produces a traceable row, but has null compound fields and is not charged as a
resolved compound.

### How much does it cost to resolve PubChem compounds?

Pricing uses pay per event:

- a **$0.002 run-start fee** covers fixed startup work; and
- each successfully resolved compound uses the tiered **Compound resolved** event.

At the BRONZE tier, the target price is **$0.0016 per resolved compound**.
The exact active tier shown in Apify Console always controls billing.
Unresolved status rows have no compound-resolution event fee.

BRONZE billing examples use this formula:

`run total = $0.002 start + resolved compound count × $0.0016`

For one, ten, one hundred, or one thousand useful compounds, multiply the same active per-compound rate by the
resolved count and add the one-time active start fee. Missing or failed lookup rows do not add item events.

Higher Apify subscription tiers receive the lower event rates displayed on the Actor page.

### Identifier resolution details

A name or structure can resolve differently as PubChem updates its records.
The Actor preserves `inputValue`, `inputType`, and `resolutionRank` so downstream jobs can audit the mapping.
CID lookup is the most deterministic mode when you already know the compound identifier.

Formula lookup is naturally one-to-many. Use `maxResultsPerInput` to select the number of ranked CIDs retained.
The Actor does not claim that the first formula match is uniquely correct for your scientific context.

### Reliability, pacing, and retries

The Actor paces official API requests below PubChem's published short-term request ceiling.
Network failures, HTTP 429, and temporary 5xx responses are retried up to three times with backoff.
Each request has a 30-second timeout.
Permanent invalid inputs and stable not-found results are not retried blindly.

If a synonym endpoint fails after the property endpoint succeeds, the row remains `resolved` with an empty
`synonyms` array. This avoids discarding useful identity and structure data because an optional enrichment failed.

### Limits and failure behavior

- A run accepts at most 1,000 submitted identifiers.
- Output is capped at 5,000 rows.
- One input can produce at most 25 matches.
- Synonyms are capped at 100 per compound.
- `maxItems` stops the run even when more formula matches exist.
- PubChem data may be corrected, merged, deprecated, or expanded over time.
- Some compounds do not expose every requested property.
- This Actor does not validate laboratory purity, hazards, dosage, or clinical suitability.

A completely malformed run input fails with a non-zero status.
An individual missing or failed identifier produces a status row so the rest of the batch can continue.

### Batch enrichment workflow

A practical recurring pipeline is:

1. export identifiers from a LIMS, ELN, inventory, or warehouse;
2. map each source column to the correct identifier type;
3. run this Actor with an output bound appropriate to the batch;
4. join results using `inputIndex` or `inputValue`;
5. retain `cid`, `inchiKey`, and provenance as stable normalization fields;
6. review one-to-many formula matches using `resolutionRank`; and
7. schedule the same Task when periodic PubChem refreshes are required.

Apify schedules, webhooks, dataset exports, and integrations can automate the downstream steps.

### API usage with cURL

Set `APIFY_TOKEN`, then run:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~pubchem-compound-batch-lookup/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"compounds":[{"value":"aspirin","type":"name"}],"maxItems":1,"maxResultsPerInput":1,"maxSynonyms":10}'
```

Use `/run-sync-get-dataset-items` instead of `/runs` when a caller should wait for the dataset response.

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/pubchem-compound-batch-lookup').call({
  compounds: [
    { value: '2244', type: 'cid' },
    { value: 'C8H10N4O2', type: 'formula' },
  ],
  maxItems: 5,
  maxResultsPerInput: 2,
  maxSynonyms: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/pubchem-compound-batch-lookup').call(run_input={
    'compounds': [
        {'value': 'caffeine', 'type': 'name'},
        {'value': 'InChI=1S/CH4/h1H4', 'type': 'inchi'},
    ],
    'maxItems': 2,
    'maxResultsPerInput': 1,
    'maxSynonyms': 5,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

### Use with MCP and AI agents

Add the Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/pubchem-compound-batch-lookup"
```

Claude Desktop, Cursor, and VS Code can use this MCP server configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/pubchem-compound-batch-lookup"
    }
  }
}
```

Example prompts showing MCP usage include:

- “Resolve these CIDs and return formula, molecular weight, SMILES, and InChIKey.”
- “Normalize this list of chemical names to PubChem CIDs and keep source links.”
- “Find up to three PubChem compounds for each formula and compare exact masses.”

Always review generated scientific interpretations independently; the Actor returns source data, not scientific advice.

### Legality and responsible use

PubChem is a public scientific resource operated by the U.S. National Library of Medicine.
Use its records in accordance with PubChem policies and cite PubChem where appropriate.
Keep `sourceUrl`, `sourceApiUrl`, and `retrievedAt` when reproducibility matters.

Compound records are informational. Do not use this Actor as the sole basis for clinical, safety, regulatory,
or laboratory decisions. Validate critical identifiers and properties against authoritative domain procedures.

### Troubleshooting

**Why did a formula return several rows?**

Molecular formulas are not unique identifiers. Reduce `maxResultsPerInput`, inspect `resolutionRank`, and use
SMILES, InChI, or CID when you need structure-specific resolution.

**Why does a row say the compound was not found?**

Check the identifier namespace and spelling. Automatic mode only distinguishes numeric CIDs from names.
Declare formulas and structure identifiers explicitly.

**Why are synonyms empty on a resolved row?**

The synonym request may have returned no values or failed after properties succeeded. Increase nothing blindly;
rerun later or use the recorded CID to inspect PubChem directly.

**Why did the whole run fail?**

The Actor fails closed for an empty compounds list, more than 1,000 inputs, invalid bounds, blank values, or an
unsupported identifier type. Inspect the run log for the indexed validation error.

### FAQ

**Does it require a PubChem key or login?**

No. It uses official anonymous PUG REST routes.

**Does it use a proxy or browser?**

No. Direct structured HTTPS requests are sufficient for this workflow.

**Are unresolved rows charged as compounds?**

No. Only records with `status: resolved` emit the Compound resolved event. The one-time run-start fee still applies.

**Can I submit duplicate identifiers?**

Yes. The Actor preserves every input position. This is useful when joining output back to the original list.

**Can it perform similarity or substructure search?**

No. The supported workflow is exact identifier/formula resolution and record enrichment.

**Can results change?**

Yes. PubChem is maintained continuously. Schedule reruns when your workflow requires current source records.

### Related Automation Lab Actors

- [Open Food Facts EAN UPC GTIN Lookup](https://apify.com/automation-lab/ean-upc-gtin-product-lookup) for food-product barcode enrichment.
- [PubMed Article Search Scraper](https://apify.com/automation-lab/pubmed-article-search-scraper) for literature metadata and abstracts.
- [NIST NVD CVE Vulnerability Records](https://apify.com/automation-lab/nist-nvd-cve-vulnerability-records) for another official public-data batch export workflow.

Choose this Actor when your primary entity is a PubChem compound and you need normalized chemistry fields rather
than products, publications, or vulnerability records.

# Actor input Schema

## `compounds` (type: `array`):

Compound identifiers. Use a string for automatic CID/name detection, or an object with value and type for SMILES, InChI, formulas, or explicit names.

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

Stop after this many resolved or unresolved input-resolution records.

## `maxResultsPerInput` (type: `integer`):

Maximum PubChem CIDs returned for each input. Formula searches can match many compounds.

## `maxSynonyms` (type: `integer`):

Maximum number of PubChem synonyms included in each resolved record. Set to 0 to skip synonym requests.

## Actor input object example

```json
{
  "compounds": [
    {
      "value": "aspirin",
      "type": "name"
    },
    {
      "value": "2244",
      "type": "cid"
    },
    {
      "value": "C8H9NO2",
      "type": "formula"
    }
  ],
  "maxItems": 10,
  "maxResultsPerInput": 5,
  "maxSynonyms": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset view containing all resolved and unresolved compound lookup records.

# 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 = {
    "compounds": [
        {
            "value": "aspirin",
            "type": "name"
        },
        {
            "value": "2244",
            "type": "cid"
        },
        {
            "value": "C8H9NO2",
            "type": "formula"
        }
    ],
    "maxItems": 10,
    "maxResultsPerInput": 5,
    "maxSynonyms": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/pubchem-compound-batch-lookup").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 = {
    "compounds": [
        {
            "value": "aspirin",
            "type": "name",
        },
        {
            "value": "2244",
            "type": "cid",
        },
        {
            "value": "C8H9NO2",
            "type": "formula",
        },
    ],
    "maxItems": 10,
    "maxResultsPerInput": 5,
    "maxSynonyms": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/pubchem-compound-batch-lookup").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 '{
  "compounds": [
    {
      "value": "aspirin",
      "type": "name"
    },
    {
      "value": "2244",
      "type": "cid"
    },
    {
      "value": "C8H9NO2",
      "type": "formula"
    }
  ],
  "maxItems": 10,
  "maxResultsPerInput": 5,
  "maxSynonyms": 20
}' |
apify call automation-lab/pubchem-compound-batch-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/pubchem-compound-batch-lookup"
        }
    }
}

```

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/fpb3h6IwKZA4s2gP4/builds/6HMxRJWgb6PLjjiYF/openapi.json
