# Currency Exchange Rates Frankfurter (`real-estate-api/currency-exchange-rates-frankfurter-202610120341`) Actor

Frankfurter Currency Exchange Rates Scraper is a Python tool designed to extract current and historical reference exchange rates, currency conversions, and time-series data from the open-source Frankfurter API. It exports clean foreign exchange datasets into structured CSV or JSON formats.

- **URL**: https://apify.com/real-estate-api/currency-exchange-rates-frankfurter-202610120341.md
- **Developed by:** [real-estate-api](https://apify.com/real-estate-api) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 results

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?

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

### Currency Exchange Rates (Frankfurter) — Historical and Latest FX Rates

### Overview

Currency Exchange Rates (Frankfurter) collects exchange rates based on European Central Bank (ECB) reference data through Frankfurter. Choose a base currency, select target currencies, and retrieve the latest rates, a historical date, a date range, or the available currency catalog.

The results can be exported as JSON, CSV, or Excel through the Apify dataset.

### Features

- Retrieve the latest available exchange rates.
- Look up rates for a specific historical date.
- Collect exchange-rate time series across a date range.
- Retrieve a catalog of supported currency codes and names.
- Filter results by base and target currencies.
- Preserve observation dates and exchange-rate values.
- Remove duplicate base-currency and date combinations within a run.
- Export collected data in common structured formats.

### Use Cases

- **Latest FX snapshots:** Collect current available cross rates for USD, EUR, or another base currency.
- **Historical research:** Compare exchange rates on a previous working day.
- **Time-series analysis:** Build historical datasets for financial research and reporting.
- **Currency catalogs:** Retrieve currency codes and names for applications and data-cleaning workflows.
- **Spreadsheet comparisons:** Schedule recurring collections and compare exported datasets.
- **Application data:** Use exchange-rate datasets in pricing displays and currency-conversion workflows.

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | String | `latest` | Collection mode: `latest`, `historical`, `series`, or `currencies`. |
| `base` | String | `USD` | Base currency used to calculate the returned rates. |
| `symbols` | Array | `[]` | Target currency codes. An empty array keeps all returned rates. |
| `startDate` | String | Empty | Historical observation date or beginning of a date range, formatted as `YYYY-MM-DD`. |
| `endDate` | String | Empty | End of the date range, formatted as `YYYY-MM-DD`. |
| `maxItems` | Integer | `100` | Maximum number of successful records to save per run. Hard maximum: 1,000. |

### Example Input

#### Latest exchange rates

Retrieve the latest available rates for USD against all returned currencies.

```json id="frk101"
{
  "mode": "latest",
  "base": "USD",
  "symbols": [],
  "startDate": "",
  "endDate": "",
  "maxItems": 100
}
```

#### Historical exchange rates

Retrieve USD and GBP rates relative to EUR for 2 January 2024.

```json id="frk102"
{
  "mode": "historical",
  "base": "EUR",
  "symbols": ["USD", "GBP"],
  "startDate": "2024-01-02",
  "endDate": "",
  "maxItems": 100
}
```

#### Exchange-rate time series

Retrieve USD rates relative to EUR across a date range.

```json id="frk103"
{
  "mode": "series",
  "base": "EUR",
  "symbols": ["USD"],
  "startDate": "2024-01-01",
  "endDate": "2024-01-05",
  "maxItems": 100
}
```

#### Currency catalog

Retrieve the available currency codes and their names.

```json id="frk104"
{
  "mode": "currencies",
  "maxItems": 100
}
```

### What Data Does This Actor Extract?

The output structure depends on the selected mode. Exchange-rate records contain a base currency, an observation date, and a mapping of target currency codes to rate values. Currency-catalog records contain currency codes and their corresponding names.

#### Example Output

```json id="frk105"
{
  "amount": 1.0,
  "base": "USD",
  "date": "2026-10-09",
  "rates": {
    "EUR": 0.89238,
    "GBP": 0.75641,
    "JPY": 158.25
  },
  "mode": "latest",
  "scraped_at": "2026-10-12T00:00:00+00:00"
}
```

#### Extracted Data Fields

| Field | Type | Description |
|---|---|---|
| `amount` | Number | Amount against which the exchange rates are quoted, usually `1.0`. |
| `base` | String | Base currency code. |
| `date` | String | Exchange-rate observation date. |
| `rates` | Object | Mapping of target currency codes to exchange-rate values. |
| `currencyCode` | String | Currency code in a catalog record. |
| `currencyName` | String | Currency name in a catalog record, including names with non-ASCII characters. |
| `startDate` | String | Start date of a time series when supplied in the output. |
| `endDate` | String | End date of a time series when supplied in the output. |
| `mode` | String | Collection mode: `latest`, `historical`, `series`, or `currencies`. |
| `scraped_at` | String | UTC timestamp indicating when the record was created. |

### Working with Your Dataset

Once the actor finishes, open the Apify dataset to inspect or export the collected records.

- **JSON:** Use structured exchange-rate records in Python applications and data pipelines.
- **CSV:** Import results into spreadsheets, databases, and analytics tools.
- **Excel:** Review historical observations, compare currencies, and prepare financial reports.

For time-series analysis, use the observation date to align records across currencies and account for dates on which no rate was published.

### Important Notes

- The rates are based on ECB reference data distributed through Frankfurter.
- The latest available observation may not correspond to the current calendar date.
- Exchange rates are generally available on working days; weekends and holidays may be absent from historical series.
- Historical and time-series results depend on the selected dates and the available observations.
- The `maxItems` setting defaults to 100 and cannot exceed 1,000 records per run.
- Currency codes must be supported by the underlying data source.
- Reference exchange rates may differ from rates offered by banks, payment providers, or currency exchanges.

### FAQ

**What is the difference between latest, historical, series, and currencies modes?**

- `latest` retrieves the newest available exchange rates.
- `historical` retrieves rates for a specified date.
- `series` retrieves observations across a date range.
- `currencies` retrieves the available currency codes and names.

**Why is the latest rate not from today?**

The newest available observation may lag behind the current calendar date because rates are published on working days and depend on source-data availability.

**Can I collect exchange rates for a specific period?**

Yes. Select `series` mode and specify both `startDate` and `endDate`.

**Why are weekends missing from the time series?**

The underlying ECB reference rates are generally published on working days. Dates without observations may therefore be absent.

**Can I export the results to CSV or Excel?**

Yes. The Apify dataset supports JSON, CSV, and Excel exports.

### Disclaimer

This actor is an independent tool and is not affiliated with or endorsed by Frankfurter or the European Central Bank. Exchange-rate data is provided for informational and analytical purposes. Verify important values against the relevant official source before using them for financial decisions or reporting.

### Is Web Scraping Legal?

Collecting information that is already public is generally legal. Scraping is not the same thing as hacking, and there is no single law that bans it. The limits are the usual ones: do not break into accounts, do not take private or confidential data, and be careful with personal data and copyrighted works. A site's terms can also restrict how you access it. Facts such as a public name, price, or rating are not the same thing as republishing someone's article or photo.

This actor collects information from public pages. It does not log in and it does not bypass access controls.

For a longer explanation, see Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

# Actor input Schema

## `mode` (type: `string`):

latest loads one ECB reference snapshot. historical loads a single YYYY-MM-DD. series loads each working day from startDate through endDate. currencies loads the currency code list.

## `base` (type: `string`):

Base currency code sent as from, such as USD or EUR. Used by latest, historical, and series. Ignored by currencies.

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

Target currency codes, one per line, sent as to. Leave empty to keep every rate the endpoint returns. On currencies mode, an empty list returns the full catalog.

## `startDate` (type: `string`):

YYYY-MM-DD. Required for historical (the quote date) and for series (range start). Ignored by latest and currencies.

## `endDate` (type: `string`):

YYYY-MM-DD range end for series. Ignored by latest, historical, and currencies.

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

Maximum successful rows to save this run. Hard cap is 1000. Error rows do not count toward this limit.

## `requestDelaySecs` (type: `number`):

Seconds to wait between HTTP calls. Minimum is 0.2 so requests stay sequential.

## `timeoutSecs` (type: `integer`):

Stop the run after this many seconds and keep rows already collected. Default 300. Maximum 3600.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for one response before treating that call as failed. Default 30 seconds.

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

Optional proxy for api.frankfurter.app requests. Leave useApifyProxy off. The public API does not need a proxy.

## Actor input object example

```json
{
  "mode": "latest",
  "base": "EUR",
  "symbols": [],
  "startDate": "2024-01-02",
  "endDate": "2024-01-05",
  "maxItems": 100,
  "requestDelaySecs": 0.2,
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Amount, base, date, mode, and source URL for each saved row.

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

Failed lookups with the input, HTTP status, and message.

## `dataset` (type: `string`):

Every row from the run, without a table view applied.

# 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 = {
    "base": "USD",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("real-estate-api/currency-exchange-rates-frankfurter-202610120341").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 = {
    "base": "USD",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("real-estate-api/currency-exchange-rates-frankfurter-202610120341").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 '{
  "base": "USD",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call real-estate-api/currency-exchange-rates-frankfurter-202610120341 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,real-estate-api/currency-exchange-rates-frankfurter-202610120341"
        }
    }
}
```

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/Wkgij2ZdeBuev17Q4/builds/svTjpQ5s7csF03sur/openapi.json
