# DailyMed Drug Labels Scraper (`automation-lab/dailymed-drug-labels-spl-records`) Actor

Search official DailyMed labels and export current SPL identities, NDCs, ingredients, dosage forms, manufacturers, warnings, normalized sections, dates, and source URLs.

- **URL**: https://apify.com/automation-lab/dailymed-drug-labels-spl-records.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.86 / 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

## DailyMed Drug Labels Scraper

Search **DailyMed drug labels** and export current Structured Product Labeling (SPL) records from the official U.S. National Library of Medicine service. Each result combines label identity, product and package NDCs, ingredients, dosage forms, manufacturer, warning sections, normalized label sections, dates, and authoritative source links.

The Actor uses DailyMed's public REST and XML services directly. It needs no API key, browser, login, or proxy.

### What can you do with this Actor?

- Search current labels by brand name, generic drug name, or NDC.
- Resolve an exact SPL set ID or DailyMed label URL.
- Build recurring snapshots for pharmaceutical research and safety-data pipelines.
- Export normalized warning, contraindication, and precaution sections.
- Join SPL identity, product identifiers, ingredients, forms, and source documents in one row.

The Actor creates current snapshots. Schedule repeated runs and compare datasets in your own workflow when you need change monitoring; it does not send alerts or calculate diffs itself.

### Who is it for?

Pharmaceutical researchers can collect consistent label evidence for analysis. Drug-safety and regulatory teams can refresh warning and section text. Data engineers can feed stable SPL IDs and NDC fields into warehouses. Healthcare software teams can resolve source records without implementing HL7 SPL XML parsing.

This is source data, not medical advice and not a substitute for professional clinical or regulatory judgment.

### Data extracted

| Field | Meaning |
| --- | --- |
| `setId`, `splId`, `splVersion` | Stable label set, current document, and version identities |
| `title`, `documentType` | Official label title and SPL document type |
| `effectiveDate`, `publishedDate` | Dates exposed by the SPL and DailyMed index |
| `manufacturer` | Represented label organization |
| `productNames`, `genericNames` | Product and generic medicine names |
| `dosageForms` | Coded dosage-form display names |
| `productNdcCodes`, `packageNdcCodes` | Product-level and package-level NDC identifiers |
| `ingredients` | Ingredient names, UNII codes, and available strengths |
| `warnings` | Warning, contraindication, and precaution sections |
| `sections` | All normalized coded label sections when requested |
| `sourceUrl`, `xmlUrl`, `pdfUrl` | Human-readable and downloadable official sources |
| `scrapedAt` | UTC extraction timestamp |

### Getting started

1. Open the Actor in Apify Console.
2. Enter one or more drug/NDC searches, SPL set IDs, or DailyMed URLs.
3. Choose whether to include every normalized section.
4. Set `maxItems` to bound the dataset and run cost.
5. Click **Start** and open the default dataset.
6. Export JSON, CSV, Excel, XML, or RSS through Apify dataset exports.

A useful first input is:

```json
{
  "queries": [{ "term": "aspirin", "type": "drugName" }],
  "maxItems": 10,
  "includeSections": true
}
```

### Input parameters

#### `queries`

An array of `{ "term", "type" }` searches. `drugName` searches brand and generic terms through DailyMed. `ndc` interprets the term as an NDC. Results from all searches are deduplicated by set ID.

#### `setIds`

An array of exact UUID-form DailyMed SPL set IDs. Use this for reproducible identity-based retrieval.

#### `labelUrls`

DailyMed label URLs containing a valid `setid`. URLs from other hosts fail validation.

#### `publishedAfter`

An optional date filter for discovered search results. Exact set IDs and URLs are returned even when the list endpoint does not supply their publication date.

#### `includeSections`

Defaults to `true`. Disable it for smaller rows when you only need identity, product fields, ingredients, and the always-included warning-related sections.

#### `maxItems`

Maximum unique labels saved across all inputs, from 1 to 1,000. The default is 25.

### Example output

```json
{
  "setId": "7ce4807e-7bd5-41f1-a9c7-1f3af6acdc09",
  "splId": "63a94bb1-ef72-4982-b862-567d4a2949ad",
  "splVersion": 6,
  "title": "Drug Facts",
  "documentType": "HUMAN OTC DRUG LABEL",
  "effectiveDate": "2026-09-09",
  "publishedDate": "Sep 10, 2026",
  "manufacturer": "Strategic Sourcing Services LLC",
  "productNames": ["Low Dose Aspirin"],
  "genericNames": ["Aspirin"],
  "dosageForms": ["TABLET, COATED"],
  "productNdcCodes": ["70677-1150"],
  "ingredients": [{ "name": "ASPIRIN", "unii": "R16CO5Y76E", "strength": "81 mg" }],
  "warnings": [{ "code": "50565-1", "title": "Warnings", "text": "..." }],
  "sourceUrl": "https://dailymed.nlm.nih.gov/dailymed/drugInfo.cfm?setid=7ce4807e-7bd5-41f1-a9c7-1f3af6acdc09"
}
```

Long section text is shortened above only for readability. Dataset rows contain the returned normalized text.

### How much does it cost to extract DailyMed drug labels?

Pay-per-event billing has a small one-time Actor start fee plus one `item` event for each successfully parsed label saved. Failed, duplicate, or filtered labels are not charged as items. Your Apify plan determines the active event tier shown in Console.

At the BRONZE rate of $0.00144 per label plus the $0.002 start event, 10 labels cost about $0.0164, 100 cost about $0.146, and 1,000 cost about $1.442. Platform compute is included under PPE billing. Check the live pricing panel before a production run because published prices and plan tiers can change.

### Reliability and limits

DailyMed is the authoritative upstream source and controls freshness, availability, fields, and rate limits. The Actor retries transient network, HTTP 429, and server failures three times with bounded backoff. Deterministic client errors fail immediately. If retries are exhausted, the run fails rather than silently presenting a partial successful extraction.

Only current SPL documents are fetched. Historical version archives, label diffs, clinical interpretation, pill-image recognition, adverse-event records, and automated notifications are outside this Actor's scope.

### Tips for recurring pharmaceutical research

- Store `setId` and `splVersion` as your comparison keys.
- Use `publishedAfter` and conservative limits for frequent scheduled refreshes.
- Disable `includeSections` if downstream work needs identifiers rather than full text.
- Keep the official `sourceUrl` beside transformed data for auditability.
- Use Apify webhooks to trigger your own database load or comparison job after a scheduled run.

### Apify API with cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~dailymed-drug-labels-spl-records/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":[{"term":"aspirin","type":"drugName"}],"maxItems":10}'
```

### JavaScript API example

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/dailymed-drug-labels-spl-records').call({
  queries: [{ term: 'acetaminophen', type: 'drugName' }],
  maxItems: 25,
  includeSections: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Python API example

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/dailymed-drug-labels-spl-records').call(run_input={
    'setIds': ['7ce4807e-7bd5-41f1-a9c7-1f3af6acdc09'],
    'includeSections': True,
    'maxItems': 1,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/dailymed-drug-labels-spl-records"
```

#### Claude Desktop, Cursor, and VS Code setup

Use this HTTP MCP configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/dailymed-drug-labels-spl-records"
    }
  }
}
```

Example prompts: “Fetch the current SPL for this DailyMed set ID and summarize which warning sections changed in my stored copy” or “Export the first 20 current acetaminophen labels with NDC and manufacturer fields.” Treat model summaries as secondary analysis, not source or medical advice.

### Integrations

Connect datasets to Google Sheets, Make, Zapier, webhooks, cloud storage, SQL warehouses, or custom applications. Stable keys make the output suitable for upserts, while `splVersion` and dates support downstream comparison logic.

### Legality and responsible use

DailyMed provides public label information. Follow NLM/DailyMed terms and attribution guidance, respect service capacity, and keep source links. Do not use output alone for diagnosis, prescribing, dispensing, treatment, or emergency decisions. Validate material regulatory conclusions against the current official document and qualified experts.

### Troubleshooting

**Why did my run return no labels?** Check whether the drug spelling or NDC format appears in DailyMed. An empty genuine search is valid. Try a broader drug-name term.

**Why was my input rejected?** SPL IDs must be full UUIDs, and explicit URLs must use `dailymed.nlm.nih.gov` and contain a valid set ID.

**Why did the run fail after some upstream errors?** DailyMed may be unavailable or rate-limiting traffic. Retry later or lower the scheduled frequency. No proxy setting is required or exposed.

**Why is a section absent?** SPL content varies by document type and labeler. The Actor only emits sections present in the current source XML.

### FAQ

#### Does this Actor use the official DailyMed API?

Yes. Discovery uses the official DailyMed v2 REST index, and details come from the official current SPL XML resource.

#### Can it retrieve labels by NDC?

Yes. Set a query's `type` to `ndc`. The output includes product and package NDCs found in the resolved SPL.

#### Does it monitor label changes automatically?

It produces timestamped current snapshots that work well in scheduled tasks. Diffing, persistence between datasets, alert rules, and notifications remain downstream responsibilities.

#### Are warnings normalized?

Warning, contraindication, and precaution sections are selected from coded/title sections and emitted as structured `{ code, title, text }` objects. The complete normalized section list is optional.

#### Is this medical advice?

No. Output is public source data for research and automation. Consult qualified professionals and the current official label for decisions.

### Related Automation Lab Actors

- [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 a similar official-API data pipeline in security research.

These Actors solve separate jobs and do not enrich or validate DailyMed records automatically.

# Actor input Schema

## `queries` (type: `array`):

Searches against DailyMed's current SPL index. Use drugName for brand/generic terms and ndc for NDC identifiers.

## `setIds` (type: `array`):

Exact DailyMed SPL set IDs (UUIDs) to retrieve. These can be combined with searches.

## `labelUrls` (type: `array`):

Exact dailymed.nlm.nih.gov label URLs containing a setid parameter.

## `publishedAfter` (type: `string`):

Optional inclusive date filter for search results, for example 2026-01-01. Exact set IDs without an index publication date are still returned.

## `includeSections` (type: `boolean`):

Include the full normalized SPL section list. Warning-related sections are always returned separately.

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

Maximum number of unique current SPL label records to save across all inputs.

## Actor input object example

```json
{
  "queries": [
    {
      "term": "aspirin",
      "type": "drugName"
    }
  ],
  "includeSections": true,
  "maxItems": 10
}
```

# Actor output Schema

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

Open the default dataset view containing SPL identities, product identifiers, ingredients, warnings, sections, dates, and official links.

# 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 = {
    "queries": [
        {
            "term": "aspirin",
            "type": "drugName"
        }
    ],
    "includeSections": true,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/dailymed-drug-labels-spl-records").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 = {
    "queries": [{
            "term": "aspirin",
            "type": "drugName",
        }],
    "includeSections": True,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/dailymed-drug-labels-spl-records").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 '{
  "queries": [
    {
      "term": "aspirin",
      "type": "drugName"
    }
  ],
  "includeSections": true,
  "maxItems": 10
}' |
apify call automation-lab/dailymed-drug-labels-spl-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/dailymed-drug-labels-spl-records"
        }
    }
}
```

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/0zxQisnxb3UUZ7HXq/builds/IpodQNKx5YvYKGOtF/openapi.json
