# PCGS Population Report Scraper — Coin Pops, Grades & Totals (`scrapersdelight/pcgs-pop-scraper`) Actor

Scrape PCGS coin population reports by series URL, category, or name search — one row per coin with PCGS #, designation, per-grade pops incl. plus grades, and certified totals. No login or API key needed; optional CoinFacts enrichment with your own token. From $4 per 1,000 coins.

- **URL**: https://apify.com/scrapersdelight/pcgs-pop-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Automation, E-commerce, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 coin population rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## 🪙 PCGS Population Report Scraper — Coin Pops, Grades & Totals

**Turn the [PCGS Population Report](https://www.pcgs.com/pop) into clean, structured data: one row per coin line with the PCGS number, full coin description, designation (MS/PR), the population at every grade — including plus-grade sub-counts — and the certified total. Point it at a series, a whole category (US, Chinese, Canadian, British coins…), the entire Pop Report, or just search a series by name ("morgan dollar", "buffalo nickel").**

No login, no API key, no browser automation — every field comes straight from PCGS's server-rendered pop-report pages. Optional BYOK lane: add your own free PCGS Public API token and each row is enriched with official CoinFacts data.

***

### What does PCGS Population Report Scraper do?

It scrapes the PCGS Pop Report — the census of how many coins PCGS has certified at each grade — into rows you can export to **JSON, CSV, Excel, or pull via API**. Population data is the supply side of coin pricing: a coin with pop 7 in MS67 trades very differently from one with pop 7,000.

- 🔗 **By series URL** — `https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83` → every coin line in the series.
- 🗂️ **By category** — `https://www.pcgs.com/pop/uscoins` (or `canadiancoins`, `chinesecoins`, `greatbritaincoins`…) → every series inside.
- 🌍 **The whole report** — pass `https://www.pcgs.com/pop` to walk every category and world country.
- 🔎 **Or search by name** — `searchTerm: "morgan dollar"` finds and scrapes every matching series, no URL needed.
- 🎚️ **Pick the grade band** — MS/PR 60–70 (default), circulated bands, the compact Summary, or the full Comprehensive table.
- ➕ **Plus-grade pops included** — the small sub-counts (MS65+, MS66+…) other tools drop.
- 🧾 **BYOK CoinFacts enrichment** *(optional)* — supply your own free PCGS Public API token and get the official `GetCoinFactsByGrade` payload on every row.

***

### What data does it extract?

For every coin line in the report:

- 🆔 `pcgs_no`, `spec_no` — the PCGS catalog numbers
- 🏷️ `description` — e.g. `1913-S 5C Type 1`
- 🎖️ `designation` (MS/PR) and `has_plus_grades`
- 📊 `populations` — object mapping each grade to its pop, e.g. `{ "60": 7, "61": 22, "62": 236, … }`
- ➕ `plus_populations` — the plus-grade sub-counts, e.g. `{ "65": 12, "66": 38 }`
- 🧮 `total` — total certified population for the line
- 📚 `section_title` — the subseries header, e.g. `Type 1, "FIVE CENTS" On Raised Ground, MS`
- 🗂️ `series_name`, `series_slug`, `series_id`, `category`, `grade_tab`, `page`
- 🔗 `pop_url`, `coinfacts_url`
- 🧾 `coin_facts` *(only with your own PCGS API token)*, 🕒 `scraped_at`

#### Example record

```json
{
  "pcgs_no": "3917",
  "spec_no": "3917",
  "description": "1913-S 5C Type 1",
  "designation": "MS",
  "has_plus_grades": true,
  "section_title": "Type 1, \"FIVE CENTS\" On Raised Ground, MS",
  "grade_tab": "Grades 60-70 (MS/PR)",
  "populations": { "60": 7, "61": 22, "62": 236, "63": 661, "64": 1048, "65": 466, "66": 235, "67": 45, "68": 7, "69": 0, "70": 0 },
  "plus_populations": { "63": 2, "64": 7, "65": 12, "66": 38, "67": 12 },
  "total": 3775,
  "series_name": "Buffalo Nickel 1913-1938",
  "series_slug": "buffalo-nickel-1913-1938",
  "series_id": "83",
  "pop_url": "https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83/0?t=3&pn=1",
  "coinfacts_url": "https://www.pcgs.com/coinfacts/coin/detail/3917"
}
```

***

### Who is it for?

- 🪙 **Coin dealers & auction houses** pricing inventory against real certified supply.
- 📈 **Collectors & registry-set builders** hunting condition rarities (low-pop grades) before the market does.
- 🤖 **Numismatic app & ML builders** who need the census as structured data, not screenshots.
- 📰 **Market analysts & newsletter writers** tracking pop changes across series over time.

***

### How to use it (step by step)

1. Click **Try for free**.
2. Paste one or more **Pop Report URLs** — a series detail page, a category, or `https://www.pcgs.com/pop` — or type a **Series search** like `morgan dollar`.
3. *(Optional)* pick a **Grade band**: MS/PR 60–70 (default), Summary, or Comprehensive.
4. *(Optional)* set **Max coin rows** (prefilled to 100; 0 = unlimited).
5. Click **Start**, then open the **Dataset** tab to view/export.

#### Quick start

```json
{ "popUrls": ["https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83"], "maxRecords": 100 }
```

#### Whole-category run (Summary view)

```json
{ "popUrls": ["https://www.pcgs.com/pop/uscoins"], "gradeTab": "4", "maxRecords": 0 }
```

#### Search + BYOK CoinFacts enrichment

```json
{
  "searchTerm": "morgan dollar",
  "gradeTab": "3",
  "pcgsApiToken": "YOUR_FREE_TOKEN_FROM_pcgs.com/publicapi",
  "apiGradeNo": 65
}
```

***

### Input

| Field | What it does |
|-------|--------------|
| `popUrls` | series detail URLs, category URLs, or `https://www.pcgs.com/pop` for everything |
| `searchTerm` | free-text series-name search across all categories ("morgan dollar") |
| `gradeTab` | `1` PO–VF · `2` VF–AU · `3` MS/PR 60–70 (default) · `4` Summary · `5` Comprehensive |
| `maxRecords` | hard cap on coin rows per run (0 = unlimited; prefilled 100) |
| `pcgsApiToken` | *(optional, BYOK)* your free PCGS Public API token → adds `coin_facts` per row |
| `apiGradeNo`, `apiPlusGrade` | which grade the CoinFacts enrichment asks for |
| `proxyConfiguration` | proxy settings (auto datacenter; switch to RESIDENTIAL if challenged) |
| `requestDelayMs` | polite spacing between page fetches (default 800 ms) |

***

### Output

Each coin line is one dataset record (fields above). Export to **JSON, CSV, Excel, HTML, or RSS**, or fetch via the **Apify API**. `populations` / `plus_populations` are objects keyed by grade label (`"60"`–`"70"`, or `"P/AG"`…`"MS/PR"` on the Summary tab).

***

### How much does it cost?

Pay-per-event — you pay for what you pull, no subscription.

| Event | What it covers | Price |
|-------|----------------|-------|
| `lot-scraped` | each coin row returned | $0.004 / row — **$4 per 1,000 coins** |
| `lot-detail-enriched` | each CoinFacts BYOK enrichment | $0.004 / row |

A premium per-lookup tier (~$0.015/lookup with bundled enrichment) is planned and will be configured on the actor's pricing page.

***

### Scheduling & monitoring pop changes

The Pop Report changes as PCGS grades new submissions. To track it, attach an **Apify Schedule** (e.g. weekly), keep the same input, and diff the exported datasets downstream (the `pcgs_no` + `grade_tab` pair is a stable key). Each run is a fresh, complete snapshot of the series you target — ideal for building a pop-history time series.

***

### Is it legal to scrape PCGS?

This actor reads **public, login-free census statistics** (aggregate counts of certified coins) — no accounts, no personal data. Scraping publicly available data is generally legal, but you are responsible for your use: **review the current PCGS Terms of Service before commercial use or redistribution of the data.** The optional CoinFacts enrichment uses *your own* PCGS Public API token under *your* API agreement.

***

### FAQ

**What is the PCGS Population Report?**
PCGS's public census of every coin it has ever graded: for each catalog number, how many examples exist at each grade. It's the standard supply-side reference for rare-coin pricing.

**Do I need a login or an API key?**
No. The Pop Report pages are public. The PCGS API token is an optional extra for CoinFacts enrichment — bring your own free token from pcgs.com/publicapi.

**What's a "plus" population?**
PCGS awards `+` grades (e.g. MS65+) for high-end examples. The report shows them as sub-counts under each grade; this scraper returns them in `plus_populations`.

**Which grade tab should I use?**
`3` (MS/PR 60–70) for mint-state/proof pops, `4` (Summary) for one compact row per coin incl. circulated grades and the total, `5` (Comprehensive) for every grade column at once.

**Can it scrape world coins?**
Yes — categories like `chinesecoins`, `canadiancoins`, `greatbritaincoins`, plus every world country listed on the `/pop` landing page.

**How do I scrape an entire category?**
Pass the category URL (e.g. `https://www.pcgs.com/pop/uscoins`) and set `maxRecords: 0`. Every series inside is walked page by page.

**How does the series search work?**
The actor crawls the Pop Report index and scrapes every series whose name contains your term — `"morgan dollar"` matches the Morgan Dollar series without you hunting for the URL.

**Does it handle pagination?**
Yes — series tables paginate (~25 rows/page); the actor walks every page and stops cleanly at the end.

**What about Cloudflare?**
The site sits behind Cloudflare Bot Management. The actor keeps a cookie jar, uses a browser-grade fingerprint, paces requests, and retries challenges automatically. For very large runs, switch the proxy to RESIDENTIAL.

**How do I export the data?**
JSON, CSV, Excel, HTML, or RSS from the Dataset tab, or via the Apify API.

**Can I get CoinFacts values (prices, rarity) too?**
Yes — set `pcgsApiToken` to your own free PCGS Public API token and each row gains a `coin_facts` object from the official `GetCoinFactsByGrade` endpoint.

***

### Feedback

Found a missing field or want a new feature (pop-change diffing, CAC data, specific registry views)? Open an issue on the actor — fast fixes and feature requests welcome.

# Actor input Schema

## `popUrls` (type: `array`):

What to scrape: series detail URLs (https://www.pcgs.com/pop/detail/{slug}/{id}), whole-category URLs (https://www.pcgs.com/pop/uscoins, /pop/canadiancoins, …), or https://www.pcgs.com/pop for every category. One row per coin line is output.

## `searchTerm` (type: `string`):

Optional free-text series-name search, e.g. 'morgan dollar', 'lincoln cent', 'saint-gaudens'. Crawls the Pop Report index and scrapes every series whose name matches. Combine with, or use instead of, Pop Report URLs.

## `gradeTab` (type: `string`):

Which Pop Report tab to scrape. '3' (MS/PR 60-70) is the site default; '4' Summary gives the compact P/AG-MS/PR + Total view; '5' Comprehensive returns every grade column.

## `maxRecords` (type: `integer`):

Hard cap on coin rows scraped this run (cost/safety guard). 0 = unlimited. Prefilled to 100 for a fast first run.

## `pcgsApiToken` (type: `string`):

Optional: your own free token from pcgs.com/publicapi. When set, each coin row is enriched with official CoinFacts data (GetCoinFactsByGrade) under 'coin\_facts'. Never required — the Pop Report itself needs no key.

## `apiGradeNo` (type: `integer`):

Grade used for the optional CoinFacts enrichment call (e.g. 65 = MS/PR65). Only used when a PCGS API token is set.

## `apiPlusGrade` (type: `boolean`):

Ask the CoinFacts enrichment for the plus-grade variant (e.g. MS65+). Only used when a PCGS API token is set.

## `proxyConfiguration` (type: `object`):

Proxy settings. Automatic datacenter rotation is usually enough; switch to RESIDENTIAL if Cloudflare challenges persist at high volume.

## `requestDelayMs` (type: `integer`):

Polite spacing between page fetches. Keep at/above ~800 ms to stay under Cloudflare's radar on long runs.

## `diagnose` (type: `boolean`):

Dev only. Dumps raw landing + detail HTML to the key-value store and logs the parsed first row, then exits.

## Actor input object example

```json
{
  "popUrls": [
    "https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83"
  ],
  "gradeTab": "3",
  "maxRecords": 100,
  "apiGradeNo": 65,
  "apiPlusGrade": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestDelayMs": 800,
  "diagnose": false
}
```

# Actor output Schema

## `coins` (type: `string`):

The dataset of population-report rows (one item per coin line, with per-grade populations and totals).

# 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 = {
    "popUrls": [
        "https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83"
    ],
    "maxRecords": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/pcgs-pop-scraper").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 = {
    "popUrls": ["https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83"],
    "maxRecords": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/pcgs-pop-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "popUrls": [
    "https://www.pcgs.com/pop/detail/buffalo-nickel-1913-1938/83"
  ],
  "maxRecords": 100
}' |
apify call scrapersdelight/pcgs-pop-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapersdelight/pcgs-pop-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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