# Currency Exchange Rates Scraper (`automation-lab/currency-exchange-rate-snapshot-tracker`) Actor

Export dated currency exchange rate snapshots with inverse rates and source provenance for treasury and commerce reporting.

- **URL**: https://apify.com/automation-lab/currency-exchange-rate-snapshot-tracker.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.44 / 1,000 rate snapshots

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

## Currency Exchange Rates Scraper

Export latest or dated **currency exchange rates** as clean currency-pair snapshots for treasury, ecommerce, reconciliation, and scheduled reporting.

Supply ISO base/quote pairs and optional amounts. Each result includes the rate, inverse rate, converted amount, provider date, retrieval timestamp, and exact source URL. The Actor uses the anonymous Frankfurter API and ECB-derived reference rates—no browser, proxy, login, or external API key is required.

### What does this Actor do?

The Actor turns a list of currency pairs into one dataset row per unique pair.

It supports:

- latest available reference-rate snapshots;
- historical snapshots for a specified `YYYY-MM-DD` date;
- multiple base currencies in one run;
- amount conversion alongside the unit rate;
- deterministic provenance fields for audits and reports;
- scheduling through Apify for recurring snapshots.

This is a reference-rate data product, not a physical currency exchange locator, retail cash quote, trading feed, or intraday price service.

### Who is it for?

- **Treasury teams** recording a daily or weekly currency basket.
- **Commerce operators** converting catalogue or settlement amounts.
- **Finance analysts** reconciling reports against a dated reference rate.
- **Data engineers** feeding normalized FX rows into warehouses or spreadsheets.
- **Developers** who want a schedulable currency exchange API workflow without managing another API credential.

### Why use it?

The output is designed for repeatable reporting rather than a one-off calculator page.

Every row records both when the provider says the rate applies and when the Actor retrieved it. This distinction matters on weekends, holidays, and scheduled runs. Inverse rates and converted amounts are calculated consistently, while `sourceUrl` preserves reproducible provenance.

Requests are grouped by base currency to reduce upstream traffic. Temporary failures receive bounded retries; invalid currencies and malformed input fail clearly instead of producing misleading rows.

### What currency exchange rate data is extracted?

| Field | Meaning |
| --- | --- |
| `pair` | Normalized `BASE/QUOTE` pair |
| `baseCurrency` | Three-letter base code |
| `quoteCurrency` | Three-letter quote code |
| `baseAmount` | Amount supplied, or `1` |
| `quoteAmount` | Base amount multiplied by the rate |
| `rate` | Quote units per one base unit |
| `inverseRate` | Base units per one quote unit |
| `requestedDate` | `latest` or requested calendar date |
| `providerDate` | Actual provider reference date |
| `retrievedAt` | UTC retrieval timestamp |
| `sourceName` | Human-readable provenance |
| `sourceUrl` | Exact Frankfurter API request |

All fields are represented in the dataset schema and can be exported as JSON, CSV, Excel, XML, or RSS through Apify.

### Getting started

1. Open the Actor input page.
2. Add one or more objects to **Currency pairs**.
3. Enter `base`, `quote`, and optionally `amount`.
4. Leave **Reference date** as `latest`, or enter a historical date.
5. Choose the maximum number of unique snapshots.
6. Click **Start**.
7. Open the default dataset or download it in your preferred format.

The prefilled input runs immediately and produces USD/EUR, USD/GBP, and EUR/JPY snapshots.

### Input parameters

#### `pairs`

Required array of objects:

- `base`: a supported three-letter currency code;
- `quote`: a different supported three-letter currency code;
- `amount`: optional positive number, default `1`.

Codes are normalized to uppercase. Duplicate normalized pairs are emitted once. Unsupported codes fail the run before data is saved.

#### `date`

Optional string. Use `latest` for the newest available rate or a date such as `2024-01-15`.

The provider can return an applicable prior business-day date for weekends and holidays. Always use `providerDate` as the effective reference date.

#### `maxItems`

Optional integer from 1 to 1,000. It limits unique input pairs after normalization and deduplication.

### Example input

```json
{
  "pairs": [
    { "base": "USD", "quote": "EUR", "amount": 100000 },
    { "base": "GBP", "quote": "USD", "amount": 75000 },
    { "base": "EUR", "quote": "JPY", "amount": 50000 }
  ],
  "date": "latest",
  "maxItems": 100
}
```

For a dated reconciliation, change `date` to `2024-01-15` or another supported historical date.

### Example output

A current run returns rows shaped like this:

```json
{
  "pair": "USD/EUR",
  "baseCurrency": "USD",
  "quoteCurrency": "EUR",
  "baseAmount": 1000,
  "quoteAmount": 862.66,
  "rate": 0.86266,
  "inverseRate": 1.159205,
  "requestedDate": "latest",
  "providerDate": "2026-09-11",
  "retrievedAt": "2026-09-12T06:15:00.000Z",
  "sourceName": "Frankfurter API (European Central Bank reference rates)",
  "sourceUrl": "https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR"
}
```

Rates change over time, so numerical values and provider dates in later runs will differ.

### How much does it cost to export currency exchange rate snapshots?

The Actor uses pay-per-event pricing:

- a **$0.005 start fee** per run;
- one **rate-snapshot** event per saved row;
- BRONZE rate-snapshot price: **$0.0024 per row**;
- lower per-row rates are available on higher plans, down to **$0.00144** on GOLD, PLATINUM, and DIAMOND.

At BRONZE, examples are approximately:

| Saved snapshots | Estimated total |
| ---: | ---: |
| 1 | $0.0074 |
| 10 | $0.029 |
| 100 | $0.245 |

Failed validation does not create rate-snapshot events. Apify plan tier, platform rounding, and billing presentation can affect the displayed total; Console pricing is authoritative.

### Scheduling recurring FX snapshots

Create an Apify schedule for daily, weekly, or month-end runs. Keep the same input and append each run's dataset to your downstream store.

Use `pair` and `providerDate` as a natural comparison key. Use `retrievedAt` to audit run timing. For weekends, compare `providerDate` before treating a repeated reference rate as a change or duplicate.

Common workflows include:

1. daily treasury balance conversion;
2. month-end finance reconciliation;
3. scheduled ecommerce reference-price refreshes;
4. exchange-rate snapshots sent to Google Sheets or a data warehouse.

The Actor records snapshots; it does not retain or calculate changes across prior Apify runs automatically.

### Export and integrations

The default dataset connects to:

- Google Sheets and Microsoft Excel;
- Make, Zapier, and webhooks;
- cloud storage and database integrations;
- custom applications through the Apify API.

For a reporting pipeline, schedule the Actor and trigger a webhook after successful runs. Read rows from the run's default dataset rather than relying on log output.

### Run with the Apify API

Replace `YOUR_TOKEN` with your Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~currency-exchange-rate-snapshot-tracker/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pairs":[{"base":"EUR","quote":"USD","amount":2500}],"date":"2024-01-15"}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/currency-exchange-rate-snapshot-tracker').call({
  pairs: [{ base: 'USD', quote: 'EUR', amount: 1000 }],
  date: 'latest',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/currency-exchange-rate-snapshot-tracker").call(
    run_input={
        "pairs": [{"base": "GBP", "quote": "USD", "amount": 75000}],
        "date": "latest",
    }
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use through MCP

#### Claude Code setup

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/currency-exchange-rate-snapshot-tracker"
```

#### Claude Desktop setup

Claude Desktop can use this JSON configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/currency-exchange-rate-snapshot-tracker"
    }
  }
}
```

#### Cursor setup

In Cursor, add the same server URL under **Settings → Tools & MCP → New MCP Server**.

#### VS Code setup

In VS Code, add the same HTTP server URL to your workspace MCP configuration.

Example prompts:

- “Get the latest USD/EUR, USD/GBP, and EUR/JPY reference rates.”
- “Convert EUR 25,000 to USD using the 2024-01-15 reference rate.”
- “Prepare a current treasury basket snapshot for USD, EUR, GBP, JPY, and CHF.”

### Reliability and failure behavior

The Actor uses a 15-second request timeout and up to three attempts for transient provider errors such as HTTP 429 or 5xx responses. Deterministic 4xx errors are not retried.

Input is validated before rate requests. A run fails when:

- `pairs` is absent or empty;
- a code is malformed or unsupported;
- base and quote are identical;
- an amount is zero, negative, or non-finite;
- a date is malformed;
- the provider cannot return a valid positive rate.

The Actor does not silently emit partial or fabricated rates after a failed provider request.

### Limits and data interpretation

Frankfurter exposes ECB-derived reference data for its supported currencies and dates. Coverage is narrower than providers advertising 160+ currencies.

Important limitations:

- no cryptocurrencies;
- no retail cash buy/sell spreads;
- no airport or “currency exchange near me” locations;
- no intraday ticks or trading signals;
- no future dates;
- no guarantee that a requested weekend date equals `providerDate`.

Reference rates are informational. Confirm the appropriate accounting or contractual rate for your use case.

### Responsible use and legality

The Actor reads a public, anonymous rate API and includes source provenance. Follow Frankfurter and upstream data terms, Apify's terms, and the laws and accounting rules applicable to your organization.

Do not present reference rates as guaranteed executable prices. Do not use the Actor as the sole basis for regulated trading, customer promises, tax filings, or financial advice without independent verification.

### FAQ

#### Does it need an API key or proxy?

No. The source is an anonymous public JSON API. Only your Apify token is needed when starting the Actor through Apify's API.

#### Are these live trading prices?

No. They are dated reference rates, not intraday market quotes or guaranteed bank conversion prices.

#### Why is `providerDate` earlier than my requested date?

The requested date may be a weekend or holiday. Use the provider's returned date as the effective date.

#### Why did an ISO-style code fail?

The code may be syntactically valid but absent from Frankfurter's current supported-currency catalogue. The Actor fails closed rather than substituting another currency.

#### How do I monitor rate changes?

Schedule repeated runs and compare rows downstream by `pair` and `providerDate`. The Actor exports snapshots and does not persist cross-run alerts itself.

#### Can I request many pairs?

Yes, up to 1,000 input entries. Requests are grouped by base currency, duplicates are removed, and `maxItems` limits saved unique pairs.

### Related automation-lab Actors

This Actor is intentionally standalone in the automation-lab portfolio: it provides normalized financial reference-rate snapshots, while no existing automation-lab Actor offers the same currency-pair contract. Combine it with Apify schedules, webhooks, and integrations rather than an unrelated scraper.

### Support

When reporting a problem, include the run URL, sanitized input, expected pair/date, and the observed error. Do not include API tokens or private financial data.

# Actor input Schema

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

Base and quote currency pairs. Set amount to calculate the converted quote amount; duplicate pairs are emitted once.

## `date` (type: `string`):

Use latest for the newest available reference rate, or enter YYYY-MM-DD for a historical snapshot. Non-business days resolve to the provider's applicable reference date.

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

Maximum number of unique currency-pair rows to save.

## Actor input object example

```json
{
  "pairs": [
    {
      "base": "USD",
      "quote": "EUR",
      "amount": 1000
    },
    {
      "base": "USD",
      "quote": "GBP",
      "amount": 1000
    },
    {
      "base": "EUR",
      "quote": "JPY",
      "amount": 500
    }
  ],
  "date": "latest",
  "maxItems": 10
}
```

# Actor output Schema

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

Open normalized currency-pair rates, converted amounts, timestamps, and provenance.

# 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": [
        {
            "base": "USD",
            "quote": "EUR",
            "amount": 1000
        },
        {
            "base": "USD",
            "quote": "GBP",
            "amount": 1000
        },
        {
            "base": "EUR",
            "quote": "JPY",
            "amount": 500
        }
    ],
    "date": "latest",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/currency-exchange-rate-snapshot-tracker").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": [
        {
            "base": "USD",
            "quote": "EUR",
            "amount": 1000,
        },
        {
            "base": "USD",
            "quote": "GBP",
            "amount": 1000,
        },
        {
            "base": "EUR",
            "quote": "JPY",
            "amount": 500,
        },
    ],
    "date": "latest",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/currency-exchange-rate-snapshot-tracker").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": [
    {
      "base": "USD",
      "quote": "EUR",
      "amount": 1000
    },
    {
      "base": "USD",
      "quote": "GBP",
      "amount": 1000
    },
    {
      "base": "EUR",
      "quote": "JPY",
      "amount": 500
    }
  ],
  "date": "latest",
  "maxItems": 10
}' |
apify call automation-lab/currency-exchange-rate-snapshot-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/currency-exchange-rate-snapshot-tracker"
        }
    }
}

```

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/AaZC9Cv55WsGC7BGm/builds/9lXX5vNQYkl4gTeAT/openapi.json
