# Market Quotes: FX, coins, stocks and ETFs in one row (`s-r/market-quotes`) Actor

One row per symbol with the quote (price, change, timestamp) plus optional daily OHLCV. FX pairs read the unmetered reference set, coins the unmetered price endpoint, stocks and ETFs a keyed quote API or a rendered quote page. Coins, stocks and ETFs in one actor.

- **URL**: https://apify.com/s-r/market-quotes.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 symbol quoteds

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

## Exchange Rate API Actor: FX, coins, stocks and ETFs in one quote row

Coins to stocks to ETFs in one actor, no keys. This exchange rate API actor
returns one row per symbol with the quote (price or rate, change, change
percent, previous close, open, high, low, volume, timestamp, fifty-two week
range, where the feed publishes it) plus optional daily OHLCV history. FX
pairs, coin ids and stock or ETF tickers all work in the same run, so a
pricing dashboard that needs a euro rate, a bitcoin price and a share quote
fills all three fields from one call. FX reads the published reference set,
which is unmetered. Nothing in the chain needs an account, a token or a
signup: every feed is public.

### What you get

- One dataset row per symbol, so a dashboard refresh is billable only for the
  symbols you actually received.
- A `quote` block carrying the figures a `last_price` field needs: price or
  rate, change, change percent, previous close, open, high, low, volume and a
  timestamp.
- FX pairs as a plain rate with its reference date, with `base` and
  `quote_currency` on the row. Write `EURUSD`, `EUR/USD` or `EURUSD=X` and the
  pair is read either way.
- Coins with price, market capitalisation, 24-hour volume and 24-hour change.
  Write the coin id (`bitcoin`) or the trading form (`BTC-USD`).
- Stocks and ETFs with the full quote summary: price, change, change percent,
  previous close, open, day's high and low, volume, the fifty-two week range,
  the currency and a quote date. Write the ticker (`AAPL`), or the ticker with
  its exchange (`AAPL:NASDAQ`, `ASML:AMS`).
- Optional daily OHLCV under `ohlcv` when you ask for a history window. One
  month, three months or one year.
- An `asset_class` on every row (`fx`, `crypto`, `equity`) so a consumer never
  has to infer from the symbol shape why one number is a reference rate and
  another is a share quote.
- A `data_coverage` count block saying whether the quote came back and how many
  daily history rows arrived, and a `missing_blocks` list naming what did not.

### Why you need an FX rates API

Fintech apps, pricing dashboards and ERP connectors all have one boring,
load-bearing field: the last price. A product ships a `last_price` in a
checkout flow, a finance dashboard refreshes a table every morning, a
procurement system revalues a foreign-currency invoice. None of those teams
wants to run a meter.

The problem with building it yourself is that the data lives in three different
shapes. FX is a reference rate with a date. A coin is a price with a market
capitalisation and a 24-hour change. A share is a quote summary with a day's
range and a fifty-two week range. Three page shapes, three timestamp
conventions, three ideas of what "change" means. Reconciling them is not hard
once. Doing it again every time one of them moves a class name is a job nobody
wanted.

There is also the metering question. The FX reference set is published for
unattended use and costs nothing. Managed FX vendors then sell the same rates
by the request and gate history behind a plan. A buyer who only needs a daily
euro rate should not be paying a metered door for it, and a buyer who needs a
thousand equity quotes should know exactly what each row cost.

### Input

| Field | Required | What it does |
|---|---|---|
| `symbols` | Yes | Symbols to quote. FX as `EURUSD`, coins as `bitcoin`, stocks as `AAPL` or `AAPL:NASDAQ`. Up to 100 per run. |
| `asset` | No | Force the asset class instead of reading it from the symbol's shape. `auto` is the default. |
| `range` | No | History window: `none`, `1mo`, `3mo`, `1y`. Default `none`. |
| `include_history` | No | Fill `ohlcv` with the daily window. Off by default. |
| `max_symbols` | No | Upper bound on symbols returned per run, 1 to 100. Default 30. |

### Output

```json
{
  "symbol": "AAPL",
  "asset_class": "equity",
  "as_of": "2026-09-25",
  "quote": {
    "grain": "market",
    "asset_class": "equity",
    "price": 335.92,
    "change": -1.10,
    "change_pct": -0.33,
    "previous_close": 337.02,
    "open": 336.72,
    "high": 338.91,
    "low": 334.30,
    "volume": 24733063,
    "fifty_two_week": { "low": 243.42, "high": 345.34 },
    "name": "Apple Inc.",
    "currency": "USD",
    "exchange": "NASDAQ",
    "quote_date": "2026-09-24",
    "status": "ok"
  },
  "ohlcv": [
    { "date": "2026-09-24", "open": 336.72, "high": 338.91, "low": 334.30, "close": 335.92, "volume": 24733063 }
  ],
  "ticker": "AAPL",
  "data_coverage": { "quote": 1, "history": 22 },
  "missing_blocks": []
}
```

```json
{
  "symbol": "EURUSD",
  "asset_class": "fx",
  "as_of": "2026-09-25",
  "quote": {
    "grain": "market",
    "asset_class": "fx",
    "rate": 1.1367,
    "date": "2026-09-24",
    "status": "ok"
  },
  "ohlcv": [ { "date": "2026-09-01", "close": 1.1694 } ],
  "base": "EUR",
  "quote_currency": "USD",
  "data_coverage": { "quote": 1, "history": 22 },
  "missing_blocks": []
}
```

Figures shown are from a September 2026 run and move as the markets move.

### Use cases

**Pricing dashboard with a `last_price` field.** A dashboard holds a table of
instruments across asset classes: a euro rate for the currency widget, a
bitcoin price for the crypto widget, a watchlist of tickers for the equities
widget. One call with all three kinds of symbol fills every cell, and the
`as_of` stamp tells the dashboard how fresh the row is.

**ERP connector revaluing a foreign-currency invoice.** An invoice in Swiss
francs has to be revalued into euros at the reference rate for a given date.
The FX row carries `rate` and `date` together, which is exactly what the
revaluation needs, and the reference set is unmetered so a nightly job costs
nothing per row.

**Fintech app deciding whether to gate history.** The app wants to draw a
sparkline behind every price. Ask for `range=1mo` and `include_history=true`
and `ohlcv` comes back with the daily closes. Decide whether to gate it on your
side from the actual row rather than from a plan document.

**Coin, stock and ETF coverage in one integration.** A research tool that
starts with coins and later adds ETFs should not need a second integration.
The symbol list takes both, `asset_class` tells the consumer which one it got,
and the quote block carries the fields each asset actually publishes.

### How it compares

| | This actor | benthepythondev/yahoo-finance-scraper | sian.agency/coingecko-crypto-scraper | openexchangerates.org |
|---|---|---|---|---|
| Asset classes in one call | FX, coins, stocks, ETFs | One portal's quotes | Coins | FX only |
| Per 1k rows | $3.00 | Free (compute only) | Free (compute only) | $1.20 per 1k API requests |
| Asset class on the row | Yes | No | No | No |
| Daily history in the same call | Yes | No | No | Behind higher plans |
| Fifty-two week range | Where published | No | No | No |
| Coverage counts | Yes | No | No | No |
| Unmetered FX rows | Yes | No | No | Metered |

The closest competitor by audience is `benthepythondev/yahoo-finance-scraper`
at 333 users and 15,682 runs, free, covering one portal. The priced comparison
a buyer will actually make is `openexchangerates.org` at $12 a month for 10,000
API requests, FX only, with history gated. This actor sits above their
per-request rate and returns what their request does not: a classified row with
change, a fifty-two week range where the door publishes one, and optional
daily history, across four asset classes from one schema. What they have that
we do not: a guaranteed hourly refresh for FX, and a free tier of 1,000
requests a month for a very small app.

### Pricing

All pricing is pay-per-event at $0.003 per `quote`, one event per returned
symbol row that carries a figure. $3.00 per 1,000 rows. Rows with no figure at
all are delivered but never charged. All pricing is pay-per-event, you only pay
for results you receive. No actor-start fee, no per-compute-unit charges.

### Coverage

Everything below runs on public feeds. No account, no token, no signup on your
side or ours.

| Asset class | Quote | Daily history |
|---|---|---|
| FX pairs | Rate plus its reference date | Yes, over the window you ask for |
| Coins | Price, market cap, 24h volume, 24h change | Yes, over the window you ask for |
| Stocks and ETFs | Full quote summary, US and major European, Asian and other listings | Daily bars for US listings and for the mapped non-US listings (Amsterdam, Paris, Xetra and Frankfurt, London, Toronto, Tokyo, Hong Kong, Sydney, Zurich, Milan). Anywhere else the row reports `no keyless history source` and `ohlcv` stays empty |

### Limits and gotchas

- FX pairs are read from the published reference set, which updates on its own
  schedule and carries a reference date rather than a live tick. That is the
  right feed for an invoice revaluation and the wrong one for a trading bot.
- Coin prices come from a public price endpoint with a fair-use ceiling. A long
  coin list is paced so a run stays inside it, and a ceiling response is waited
  out rather than treated as a failure.
- Equity quotes are read live, one batched request for the whole symbol list,
  with public fallbacks for tickers the batch does not carry. A row only ever
  shows what its door publishes: most rows carry the full summary, a fallback
  row may carry price, change and volume alone.
- Equity daily history covers US listings and the non-US listings on the
  mapped boards (Euronext, Xetra and Frankfurt, London, Toronto, Tokyo, Hong
  Kong, Sydney, Zurich, Milan). The row is only ever matched to the listing
  that was asked for, so `SAP:XETR` never returns another market's series for
  the same letters. Where no door publishes a window, the quote still comes
  back and the history block reports `no keyless history source` in
  `history_note` with `ohlcv` left empty.
- `asset=auto` reads the shape of the symbol. A six-letter ticker that happens
  to look like a currency pair will be read as FX; force `asset=equity` for
  those.
- `include_history` only fills `ohlcv` when `range` names a window. Leaving
  `range` at `none` returns the quote alone.
- `max_symbols` bounds what comes back. A run of 30 symbols with history takes
  under a minute; 100 with a year of history takes several.

### FAQ

**Can I use this as a currency exchange rates API for a checkout flow?**
Yes. Write the pair as `EURUSD` and read `quote.rate` and `quote.date`. The
reference set is unmetered, so a high-volume checkout can refresh as often as
the feed moves without a meter running.

**Do I get crypto prices alongside FX rates?**
Yes. Put `bitcoin` and `EURUSD` in the same list. The coin row carries price,
market capitalisation and 24-hour change; the FX row carries the rate and its
reference date. Both land in one dataset with the asset class on each row.

**Is there a free tier for a small app?**
The FX rows are sourced from an unmetered reference set, which is why the rate
sits at the low end of the band. Free-plan Apify runs return up to 10 rows per
run. Above that, you pay per symbol row you receive and nothing else.

**How do I get stock history rather than just the last price?**
Set `range` to `1mo`, `3mo` or `1y` and turn `include_history` on. Daily OHLCV
comes back under `ohlcv`, with one row per trading day: date, open, high, low,
close and volume where the listing publishes it. It covers US listings and the
mapped non-US boards, including Amsterdam and Xetra. Name the exchange
(`ASML:AMS`, `SAP:XETR`) so the row is matched to that listing; anywhere the
quote still comes back and the history block reports what is missing.

**Which symbols work for ETFs?**
The same shape as stocks: `SPY`, `VWCE:AMS`, `QQQ:NASDAQ`. The row comes back
as `asset_class: "equity"` with the same quote fields.

**What happens when a symbol has no figure?**
One row with the symbol, its asset class, `data_coverage.quote` set to 0 and a
generic reason. Nothing is invented, and the row is not charged.

### Related Actors

- [Cost of Living Actor](https://apify.com/s-r/cost-of-living) for the price
  side of a market next to its FX rate.
- [Google Finance Scraper](https://apify.com/s-r/google-finance-scraper) for
  quote pages with news and chart context.
- [SEC EDGAR Scraper](https://apify.com/s-r/sec-edgar-scraper) for filings
  behind an equity ticker.

# Actor input Schema

## `symbols` (type: `array`):

Symbols to quote. FX pairs as `EURUSD`, `EUR/USD` or `EURUSD=X`. Coins as `bitcoin` or `BTC-USD`. Stocks and ETFs as `AAPL`, `AAPL:NASDAQ` or `ASML:AMS`. Up to 100 per run.

## `asset` (type: `string`):

Force the asset class instead of reading it from the symbol's shape. Auto works it out.

## `range` (type: `string`):

Daily history window to fetch alongside the quote. `none` returns the quote alone. History is only available where the door for that asset publishes a window.

## `include_history` (type: `boolean`):

Fill `ohlcv` with the daily window named in `range`. Off by default.

## `max_symbols` (type: `number`):

Upper bound on symbols returned per run, 1 to 100. Default 30.

## Actor input object example

```json
{
  "symbols": [
    "EURUSD",
    "bitcoin",
    "AAPL"
  ],
  "asset": "auto",
  "range": "none",
  "include_history": false,
  "max_symbols": 30
}
```

# Actor output Schema

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

One row per symbol, with the quote, optional daily history, coverage counts and the asset class.

## `output` (type: `string`):

OUTPUT record with the run's counts, coverage totals and status flags.

## `errors` (type: `string`):

Failures with a code and a redacted message. Absent when the run had none.

# 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 = {
    "symbols": [
        "EURUSD"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/market-quotes").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 = { "symbols": ["EURUSD"] }

# Run the Actor and wait for it to finish
run = client.actor("s-r/market-quotes").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 '{
  "symbols": [
    "EURUSD"
  ]
}' |
apify call s-r/market-quotes --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/market-quotes"
        }
    }
}
```

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/JjdDVkGNZplf0FMfS/builds/czH2coUyPNmF1Xb8Z/openapi.json
