# Coinbase Scraper (`publicmoney/coinbase-scraper`) Actor

Extract live Coinbase Exchange prices for any product with no API key or OAuth: last trade, best bid and ask, 24h high, low and base volume, and the exchange timestamp, off the order book. Export data, run via API, schedule and monitor runs, or integrate with other tools.

- **URL**: https://apify.com/publicmoney/coinbase-scraper.md
- **Developed by:** [Public Money](https://apify.com/publicmoney) (Apify)
- **Categories:** Business
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 records

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

Coinbase runs two different APIs, the retail one and Coinbase Exchange, and the docs send you to a key and an OAuth flow before you get a price. This Actor reads the public Coinbase Exchange ticker for any product and returns one structured record: last trade, best bid and ask, 24h high, low and base volume, and the exchange timestamp.

### What it does

- Returns **one record per requested product**, in order. A product Coinbase does not list comes back with `status: "failed"` and a reason.
- Reads **Coinbase Exchange**, the institutional venue, rather than the retail app, so the prices are the ones the order book actually traded at.
- Keeps both names: `requested` is what you asked for (`BTC/USD`) and `symbol` is Coinbase's product id (`BTC-USD`).
- Quotes in **USD, EUR and GBP** for the products Coinbase lists in them, so fiat pairs need no stablecoin hop.
- Needs **no API key and no OAuth**. The public product ticker is unsigned.
- Stamps every record with `validFrom`, Coinbase's own exchange time for that tick.

### Use cases

| You need to | How this Actor does it |
| --- | --- |
| Price a portfolio in fiat | Pass `BTC/USD` or `ETH/EUR` and read `value` directly |
| Watch the spread on a pair | Subtract `bid` from `ask` on each run and alert on a widening book |
| Compare venues for the same pair | Run this next to the Binance, Bybit, OKX or Kraken Actor and diff `value` at `validFrom` |
| Mark a US-facing book | Coinbase is the reference venue for many US desks, so use it as the benchmark price |
| Feed a trading agent | Call the Actor over MCP and let the model ask for the product it needs |
| Build your own candles | Schedule the run and let the dataset accumulate one row per product per run |

### Quick start

1. Click **Try for free**.
2. Add your products, one per line, as `BASE/QUOTE`: `BTC/USD`, `ETH/EUR`, `SOL/USD`. Coinbase writes them with a hyphen and the Actor converts.
3. Click **Start**. Rows appear within seconds.
4. Export as JSON, CSV, Excel or XML, or read the dataset over the API.

### Input

| Field | Type | Default | What it controls |
| --- | --- | --- | --- |
| `pairs` | array | `BTC/USD, ETH/USD` | Trading pairs to read, written BASE/QUOTE. Slashes are optional and case does not matter. |
| `maxItems` | integer | `0` | Caps how many products are read. `0` reads them all |

```json
{
    "pairs": [
        "BTC/USD",
        "ETH/USD",
        "SOL/USD"
    ],
    "maxItems": 0
}
```

### Output

One dataset item per product. Fields Coinbase does not publish are dropped rather than returned as `null`.

| Field group | Fields |
| --- | --- |
| Identity | `status`, `requested`, `symbol`, `currency`, `url` |
| Price | `value`, `bid`, `ask` |
| 24 hour window | `high24h`, `low24h`, `baseVolume24h` |
| Timing | `validFrom`, `scrapedAt` |

```json
{
    "status": "ok",
    "requested": "BTC/USD",
    "symbol": "BTC-USD",
    "currency": "USD",
    "value": 104211.55,
    "bid": 104211.4,
    "ask": 104211.55,
    "high24h": 106488.0,
    "low24h": 103104.2,
    "baseVolume24h": 4188.92,
    "validFrom": "2026-09-04T20:00:01.000Z"
}
```

### Integrations

Run it over the API and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/publicmoney~coinbase-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pairs": ["BTC/USD", "ETH/USD", "SOL/USD"], "maxItems": 0}'
```

From Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("publicmoney/coinbase-scraper").call(run_input={"pairs": ["BTC/USD", "ETH/USD", "SOL/USD"], "maxItems": 0})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["symbol"], item["value"], item["validFrom"])
```

Give an AI agent the Actor over MCP:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?actors=publicmoney/coinbase-scraper"
        }
    }
}
```

Schedules run it on any cron, webhooks fire when a run finishes, and platform integrations push the
dataset to Google Sheets, Slack, Airtable, Zapier or your own endpoint.

### Cost

Pay per event, so you pay for records rather than compute time.

| Event | Free tier | Top volume tier |
| --- | --- | --- |
| Record with data | $0.002 | $0.0007 |
| Actor start | $0.00005 per GB | Same |

A record that returned no data is published as a failure row and is **never charged**. Six volume tiers apply, so the per-record price falls with monthly volume.

### Troubleshooting

| Issue | Solution |
| --- | --- |
| One pair returns `failed`, the rest are fine | That pair is not listed on this exchange, or the quote asset is wrong. Check it on the exchange first. |
| `symbol` does not match what I sent | By design. `requested` is your input and `symbol` is Coinbase's product id, so `BTC/USD` becomes `BTC-USD`. |
| A product is on the Coinbase app but fails here | The retail app lists assets that Coinbase Exchange does not trade. This Actor reads the Exchange venue. |
| Prices differ from the Coinbase app | The app shows retail pricing with its own spread. Exchange prices are the order book. |
| `value` looks behind another exchange | Read `validFrom`. It is the exchange's own timestamp for that tick, so two venues legitimately differ. Prices are spot, not aggregated. |

### FAQ

#### Does the Coinbase API need an API key?

The retail and Advanced Trade APIs do, and some flows need OAuth. The public Coinbase Exchange product ticker does not, which is what this Actor reads.

#### Which Coinbase does this read, the app or the exchange?

Coinbase Exchange, the institutional venue. Its prices come off the order book rather than carrying the retail spread, so they differ from the consumer app.

#### Is this the real-time Coinbase price?

It is the last trade Coinbase published at `validFrom`, read live on each run. It is not a stream, so for tick-by-tick data use a websocket. For a price every minute or every hour, schedule the Actor.

#### Does it return Coinbase candles or historical prices?

No. Each record is the current ticker. To build a series, schedule the Actor and let the dataset accumulate one row per pair per run, each stamped with `validFrom`.

#### Can I price in EUR or GBP?

Yes, for the products Coinbase lists in that fiat.

#### Do I need a Coinbase API key?

No. You need an Apify token to call the Actor over the API. No Coinbase credential is involved anywhere.

#### Can I get this data in Python?

Yes, with the `apify-client` package as shown above. It returns parsed JSON, so there is no HTML or response handling on your side.

#### Can I get the data into Excel or Google Sheets?

Yes. Export the dataset as XLSX or CSV, or connect the Google Sheets integration so each run appends to a sheet.

#### Can an AI agent call this Actor?

Yes. Add it to an MCP client with the config above and the model can request what it needs on its own. Every record is flat JSON with named fields, so no post-processing is needed.

#### Is it legal to scrape Coinbase?

This Actor reads public Coinbase data that needs no login and collects no personal data. Scraping public data is generally lawful, and how you store, redistribute or act on market data is governed by your own agreements and local rules. Take your own legal advice for your use case.

### Changelog

- **0.0.2** Added the 24h high and low next to volume.
- **0.0.1** First release. Product ticker for any listed product.

### Feedback

Found a field Coinbase publishes that this Actor misses, or an input it rejects? Open an issue on the Issues tab with the input and what you expected. A daily test runs every Actor in the fleet against live sources, so parser fixes ship fast.

# Actor input Schema

## `pairs` (type: `array`):

Coinbase Exchange products to read, one per line, written BASE/QUOTE. Coinbase writes them with a hyphen and the Actor converts. This reads Coinbase Exchange, the institutional venue, so its prices come off the order book rather than carrying the retail app's spread. Examples: 'BTC/USD', 'ETH/USD', 'SOL/USD', 'ETH/EUR'. Default is 'BTC/USD', 'ETH/USD'.

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

Maximum number of products to read, counted from the top of the list. Use it to cap spend on a long list without editing the list itself. Examples: 10, 50, 200. Default is 0, which reads every product given.

## Actor input object example

```json
{
  "pairs": [
    "BTC/USD",
    "ETH/USD"
  ],
  "maxItems": 0
}
```

# Actor output Schema

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

One item per requested input, in the default dataset.

# 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 = {
    "pairs": [
        "BTC/USD",
        "ETH/USD"
    ],
    "maxItems": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("publicmoney/coinbase-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 = {
    "pairs": [
        "BTC/USD",
        "ETH/USD",
    ],
    "maxItems": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("publicmoney/coinbase-scraper").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 '{
  "pairs": [
    "BTC/USD",
    "ETH/USD"
  ],
  "maxItems": 0
}' |
apify call publicmoney/coinbase-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,publicmoney/coinbase-scraper"
        }
    }
}

```

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/z1zLemcvkkDeHuOE9/builds/X1rmer13JuRbBOhCJ/openapi.json
