Forex Factory Economic Calendar Scraper avatar

Forex Factory Economic Calendar Scraper

Pricing

from $0.02 / 1,000 item extracteds

Go to Apify Store
Forex Factory Economic Calendar Scraper

Forex Factory Economic Calendar Scraper

πŸ“… Export current-week Forex Factory macro events with stable IDs, currency, impact, forecast, previous value, local schedule, and canonical URLs. Filter records for trading-risk dashboards, alerts, and market-data pipelines.

Pricing

from $0.02 / 1,000 item extracteds

Rating

5.0

(1)

Developer

Automation Lab

Automation Lab

Maintained by Community

Actor stats

0

Bookmarked

53

Total users

12

Monthly active users

13 days ago

Last modified

Categories

Share

Export the current-week Forex Factory economic calendar as clean JSON, CSV, Excel, XML, or RSS-ready dataset records.

Get event titles, currencies, local dates and times, impact levels, forecasts, previous values, stable IDs, and canonical Forex Factory URLs without a login or API key.

This Actor is designed for repeat schedules: trading-risk dashboards, market alerts, quantitative pipelines, newsletters, and research notebooks can refresh the same structured contract throughout the week.

CSV/XML does not declare a timezone. Legacy local fields and timezone: null stay unchanged. Opt in to source-backed UTC timestamps from uniquely matched offset-bearing JSON records; missing or conflicting evidence remains null.

This is an unofficial tool, not affiliated with or endorsed by Forex Factory or Fair Economy.

What does Forex Factory Economic Calendar Scraper do?

The Actor fetches Forex Factory's public current-week structured feed and turns every valid macroeconomic event into a normalized dataset row.

It can:

  • πŸ“… extract this week's economic calendar events;
  • πŸ’± select currencies such as USD, EUR, GBP, JPY, CAD, AUD, NZD, or CHF;
  • 🚨 select High, Medium, Low, or Holiday impact levels;
  • πŸ”Ž restrict results to an inclusive local-date window and literal title keyword;
  • πŸ• optionally enrich events with source-backed UTC timestamps;
  • πŸ“‹ inspect full-feed coverage, truncation and enrichment in the run summary;
  • 🧩 create a deterministic event ID for deduplication;
  • πŸ”— preserve the canonical Forex Factory event URL;
  • πŸ“€ export results through Apify datasets and integrations.

The minimum product intentionally stays on the proven public current-week feed. It does not claim arbitrary historical coverage.

Who is it for?

Traders and risk managers

Build a weekly risk calendar before entering positions. Filter to High-impact USD or EUR releases and send the records to an alerting tool.

Quantitative and market-data teams

Load normalized event schedules into a warehouse, join them to price series, and use stable IDs to avoid duplicate processing.

Newsletters and research desks

Create a repeatable list of upcoming macro events, forecasts, and previous values for briefing documents.

Automation builders

Run the Actor on a schedule and connect the dataset to Slack, Google Sheets, webhooks, Make, Zapier, or custom code.

Why use this economic calendar extractor?

Forex Factory presents useful macroeconomic information, but automation needs a stable machine-readable contract.

This Actor adds:

  • normalized dates in YYYY-MM-DD format;
  • normalized clock times in 24-hour format when available;
  • safe timezone handling with timezone: null when the feed is silent;
  • null preservation for blank forecasts and previous values;
  • stable IDs derived from event identity fields;
  • bounded retries and validation instead of silent empty output;
  • pay-per-event billing aligned with produced data.

What data can I extract?

FieldTypeDescription
eventIdstringStable 24-character event identifier
titlestringEconomic event title
currencystringThree-letter affected currency code
localDatestringSource-local date in YYYY-MM-DD
localTimestring24-hour time, All Day, Tentative, or Unscheduled
localDateTimestring or nullTimezone-free local datetime when a clock time exists
timezonenullAlways null; CSV/XML declares no timezone or IANA zone
sourceDateTimestring or nullExact offset-bearing JSON date for a unique compatible match; null otherwise
eventDateTimeUtcstring or nullUTC ISO instant converted from sourceDateTime; null otherwise
impactstringHigh, Medium, Low, or Holiday
forecaststring or nullForecast value exactly as supplied
previousstring or nullPrevious value exactly as supplied
urlstringCanonical Forex Factory calendar URL
sourcestringForex Factory
scrapedAtstringUTC extraction timestamp

How to scrape the Forex Factory calendar

  1. Open the Actor input page.
  2. Set Maximum events to the number you need.
  3. Optionally add currency codes such as USD and EUR.
  4. Optionally select impact levels such as High.
  5. Optionally enter dateFrom and dateTo using YYYY-MM-DD.
  6. Click Start.
  7. Open the dataset to preview or export the economic events.
  8. Add a schedule if you need recurring refreshes.

The Console prefill/example saves 10 events; omitted maxItems defaults to 100. Use 500 for a broad weekly export, and inspect SUMMARY.truncated rather than assuming a capped dataset covers the whole week.

Input parameters

ParameterTypeDefaultDescription
maxItemsinteger100Maximum matching events to save, from 1 to 500
currenciesstring[][]Optional three-letter currency filters
impactsstring[][]Optional High, Medium, Low, or Holiday filters
dateFromstringunsetInclusive source-local start date
dateTostringunsetInclusive source-local end date
keywordstring""Trimmed, case-insensitive literal substring of title
includeUtcTimestampbooleanfalseRequest optional source-backed UTC fields; inspect summary status

Empty filter arrays include all source values. Currency matching is case-insensitive; impact labels are case-sensitive. Keyword filtering is a literal title substring, not regex, whole-word matching, synonyms or sentiment. Empty/whitespace keyword includes all titles. Filters are AND-combined; array entries match ANY selected value. The global limit applies after filtering and deduplication.

Invalid property/array element types, noninteger limits, impossible Gregorian dates (such as 2026-02-30), reversed ranges and unsupported impact values fail clearly before requests or charging. Valid leap days are accepted. Unknown optional properties are ignored.

Example input: high-impact USD events

{
"currencies": ["USD"],
"impacts": ["High"],
"maxItems": 50
}

For a broad weekly export:

{
"maxItems": 500
}

For a focused USD inflation risk calendar:

{
"currencies": ["USD"],
"impacts": ["High"],
"keyword": "CPI",
"includeUtcTimestamp": true,
"maxItems": 50
}

A legitimate zero-match week is possible. Do not substitute guessed timestamps when UTC enrichment is unavailable.

For a major-currency risk monitor:

{
"currencies": ["USD", "EUR", "GBP", "JPY"],
"impacts": ["High", "Medium"],
"maxItems": 200
}

Example output

{
"eventId": "37d74dd9479b359e70134b18",
"title": "BusinessNZ Services Index",
"currency": "NZD",
"localDate": "2026-07-12",
"localTime": "22:30",
"localDateTime": "2026-07-12T22:30:00",
"timezone": null,
"sourceDateTime": null,
"eventDateTimeUtc": null,
"impact": "Low",
"forecast": null,
"previous": "47.5",
"url": "https://www.forexfactory.com/calendar/852-nz-businessnz-services-index",
"source": "Forex Factory",
"scrapedAt": "2026-07-16T02:30:00.000Z"
}

Values such as percentages or abbreviations remain strings because the source may include units and revisions.

Local time and timezone semantics

The public current-week export provides a date and time but does not declare an IANA timezone or UTC offset in the complete CSV/XML record.

Accordingly:

  • localDate preserves the calendar date;
  • localTime normalizes ordinary clock times to 24-hour form;
  • localDateTime combines those values without a timezone suffix;
  • timezone is always null;
  • all-day or tentative events have localDateTime: null.

When includeUtcTimestamp: true, the Actor separately reads the current-week JSON feed. It joins only unique records by exact trimmed title, currency, and JSON date converted to a UTC clock equal to the full CSV/XML localDateTime, with compatible impact. This is a conservative cross-feed matching rule, not a claim that CSV/XML declares a timezone.

For example, a base schedule 2026-09-27T23:50:00 can match the JSON date 2026-09-27T19:50:00-04:00 and produce eventDateTimeUtc: "2026-09-27T23:50:00.000Z". The offset is applied once; it is not converted into an IANA zone. Positive offsets and day rollover follow the JSON instant, never a global offset assumption.

Disabled enrichment, ambiguous keys, missing/invalid offsets, incompatible impact or time, all-day/tentative/unscheduled labels, and cross-feed disagreement leave the two additive fields null. If JSON fails, useful base rows still succeed; the summary says unavailable. At most two JSON requests, each with a 10-second timeout, are made, direct first then fresh proxy. No browser or per-event request is used. Date filters still use localDate; enabling UTC does not change them.

Coverage and extraction summary

Open Coverage and UTC enrichment summary in the Output tab or read SUMMARY in this run's default key-value store. It costs no item event. SOURCE_SAMPLE remains the first unnormalized base event.

The summary records source URL/format/route, scrape time and observed valid source-local date bounds. Counts cover the entire acquired feed, not just the saved prefix:

  • sourceCount: all acquired records.
  • malformedCount: records rejected by base validation; partial malformed feeds warn explicitly.
  • validCount: valid records including duplicates (sourceCount - malformedCount).
  • duplicateCount: valid repeated event IDs, removed before filtering.
  • filteredCount: unique valid records rejected by one or more filters, counted once.
  • matchingCount: unique valid records passing every filter, before the cap.
  • savedCount: rows actually saved; maxItems is the cap.
  • truncated: matching count exceeds the cap; 143 matches at a cap of 100 means 100 saved and true.

Thus validCount = duplicateCount + filteredCount + matchingCount. A valid zero-match run says resultReason: "no_filter_matches"; an empty or entirely malformed base feed fails non-zero rather than claiming zero matches.

utcEnrichment records requested status (not_requested, complete, degraded or unavailable), source URL and join provenance. Its matchedCount/unmatchedCount partition all matching unique rows before the cap when requested; both are zero when disabled. savedMatchedCount counts enriched saved rows. complete means all matching rows were enriched, not an assertion of complete source history. Always inspect null fields and summary status before timing-sensitive automation.

Stable IDs and scheduled monitoring

The eventId is derived from title, currency, date, time, and canonical URL.

For scheduled workflows:

  1. store the latest dataset in your database;
  2. use eventId as a natural deduplication key;
  3. compare forecasts or previous values when the same ID reappears;
  4. alert only when a record is new or changed.

IDs are stable for unchanged source records, but a corrected source schedule can intentionally produce a new ID.

How much does it cost to scrape Forex Factory events?

The Actor uses pay-per-event pricing. A run costs $0.005 to start, then one item event per saved economic event.

Apify tierPrice per saved event100 events plus start
Free$0.000042972about $0.00930
Bronze$0.000037367about $0.00874
Silver$0.000029146about $0.00791
Gold$0.000022420about $0.00724
Platinum$0.000014947about $0.00649
Diamond$0.000010463about $0.00605

Input filters and maxItems let you cap output and spending. A valid run that saves 20 events charges one start event and 20 item events. Filtered-out records, duplicate records and the summary are not item-charged. A valid zero-match run charges only start. Enrichment adds no new charge event. Invalid input is rejected before the start charge.

Tips for reliable calendar workflows

  • πŸ—“οΈ Run on a schedule appropriate for your dashboard, not every minute by default.
  • 🚨 Use impact filters when only market-moving releases matter.
  • πŸ’± Use uppercase ISO-style codes in documentation, although input matching is case-insensitive.
  • πŸ”‘ Deduplicate on eventId, not title alone.
  • πŸ• Treat local schedule fields as timezone-free unless you verify the source convention.
  • πŸ“¦ Export the dataset after each run or consume it through the API.
  • πŸ” Preserve null forecasts; a blank value is different from zero.

Integrations and automation patterns

Google Sheets briefing

Schedule the Actor before a weekly trading meeting and export the dataset to a Sheet sorted by local date and impact.

Slack or email risk alerts

Filter to High-impact currencies, compare IDs against the prior run, and post new events to a risk channel.

Data warehouse ingestion

Use a webhook to copy completed dataset rows into BigQuery, Snowflake, PostgreSQL, or another warehouse.

Market-research notebook

Fetch dataset JSON in Python and join local event schedules to independently timezone-normalized market data.

Make and Zapier

Trigger a run on a schedule, iterate dataset rows, and route events by currency or impact.

API usage with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/forex-factory-economic-calendar-scraper').call({
currencies: ['USD', 'EUR'],
impacts: ['High'],
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python API example

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/forex-factory-economic-calendar-scraper').call(
run_input={
'currencies': ['USD', 'EUR'],
'impacts': ['High'],
'maxItems': 50,
}
)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

cURL API example

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~forex-factory-economic-calendar-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"currencies":["USD"],"impacts":["High"],"maxItems":50}'

After the run succeeds, read its defaultDatasetId and request /v2/datasets/{DATASET_ID}/items.

Use with Apify MCP

Connect Claude Code with:

$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/forex-factory-economic-calendar-scraper"

For Claude Desktop, Cursor, or VS Code, add an HTTP MCP server configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/forex-factory-economic-calendar-scraper"
}
}
}

Follow one run and read bounded results

The Actor-specific endpoint selects a stable subset, not exactly one tool: it also includes get-actor-run, get-dataset-items, get-key-value-store-record, and abort-actor-run. Use scoped tools/list to discover the actual names and argument schemas, then load only the Actor/run/data helpers you need. Read-only discovery does not authorize execution or aborting a run.

  1. Start once when authorized. Retain the returned run ID, status and storage IDs; these are metadata, not event rows. call-actor waits at most waitSecs (0–45 seconds, default 30), so it may return before completion. Set the client request timeout above the selected wait plus transport margin, within a total 120-second consumer deadline.
  2. Follow the same run. If nonterminal, use get-actor-run for that ID with 2, 4, 8-second backoff capped at 10 seconds, stopping at the deadline. After a client timeout, recover/check the known run instead of starting another. If the ID is unknown, report uncertainty rather than blindly rerunning. At the deadline, report pending with the run ID and stop polling. Report terminal failures honestly; any available rows are partial, not a successful full extraction.
  3. Read actual rows in pages. After success, use get-dataset-items with defaultDatasetId, explicit offset: 0, limit: 20, and needed fields such as eventId,title,currency,impact,localDateTime,eventDateTimeUtc,url, using the discovered argument schema. Prefer untransformed JSON. Track source offsets and pagination metadata, not transformed row counts, since filtering/unwinding can change counts. Read SUMMARY through get-key-value-store-record when coverage/enrichment status is needed.
  4. Bound model context, not extraction. For example, admit at most 100 source rows and 64 KiB of serialized UTF-8 result content across all pages and summary, whichever comes first. Process responses host-side before injecting them into model context; omit or summarize an oversized row/page with disclosure. If your client cannot intercept oversized responses, this is not a hard byte guarantee: do not request unbounded results. Stop at exhaustion or budget, disclose returned rows, continuation offset, and any partial/truncated result. Keep full dataset exports in storage/downstream processing outside model context. This consumer budget does not change Actor defaults, collection scope or output fields.

These backoff/deadline/context values are example consumer choices, not Apify defaults. Discovery transport bytes are not model-visible context; host-side caching, progressive loading and prompt caching depend on client capabilities. No universal token savings are promised. A numeric savings claim would need the measured client/version, negotiated capabilities and cache mode, model/tokenizer, visible tool/result subset and baseline method.

Example prompts:

  • β€œExtract this week's high-impact USD Forex Factory events.”
  • β€œBuild a JSON list of medium- and high-impact EUR and GBP releases.”
  • β€œCompare these event IDs with yesterday's dataset and summarize changes.”

Source coverage and limitations

The Actor covers the current public weekly feed available at run time.

It does not:

  • crawl arbitrary historical date ranges;
  • predict future values;
  • provide trading advice;
  • invent missing forecast or previous values;
  • guess UTC instants from timezone-free local schedules;
  • guarantee actual/revised values, arbitrary history, or next/last-week feeds;
  • scrape private account data.

The upstream feed can revise event dates, times, values, or URLs. Scheduled users should treat each run as a fresh source snapshot.

Data quality and error handling

The extractor validates required titles, dates, currency codes, impact levels, and canonical event URLs.

Individual malformed records are skipped with warning logs. A missing feed root or a feed with no parseable events fails rather than returning a misleading empty success.

Requests use a finite timeout and bounded retries. The Actor spreads direct requests across the equivalent CSV and XML feeds. If both direct routes are throttled, it retries through fresh Apify Proxy identities; this can add a small amount of platform proxy transfer. The Actor explicitly decodes the feed's declared Windows-1252 encoding.

Data handling and AI

The Actor uses deterministic HTTP extraction and parsing. It does not call AI models or accept credentials/private account data. Run datasets, key-value stores and logs follow your Apify account retention settings and can be deleted with Apify storage controls.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed; diagnostic reports are retained for 30 days. Successful optional-feed recovery warnings are not terminal failure reports.

This Actor reads an anonymously accessible public structured feed and does not bypass login controls.

You are responsible for your use of the data, including compliance with applicable laws, contracts, Forex Factory terms, intellectual-property rights, and privacy obligations.

Use reasonable schedules, avoid unnecessary load, and do not present the output as investment advice.

FAQ

Does the Actor need a Forex Factory account?

No. The current-week feed used by this Actor is publicly accessible without a login or API key.

Can I scrape last month or any custom historical range?

Not in v1. The reliable product scope is the public current-week feed. Date filters narrow that feed; they do not request historical pages.

Why is timezone null?

The complete CSV/XML record does not declare a timezone. Returning null is safer than inventing an offset that could move an event to the wrong instant.

Why are some forecasts or previous values null?

Forex Factory leaves some values blank, especially before estimates are available. The Actor preserves blanks as null rather than treating them as zero.

Why did my filtered run return no events?

The selected currencies, impacts, keyword or local date range may not occur in the current weekly feed. Inspect SUMMARY for source/matching/saved counts, remove filters or inspect the broad weekly export.

Why did the run reject my date?

Use a real Gregorian YYYY-MM-DD date, for example 2026-07-16. Impossible dates are rejected. Ensure dateFrom is not later than dateTo.

Can I stop after a fixed number of records?

Yes. Set maxItems from 1 to 500. It applies after filtering.

Can I use the output for automated trading?

You can integrate it into your own systems, but verify timing and data independently. The Actor is a data extraction tool, not financial advice.

Combine this Actor with other automation-lab data tools:

Choose this Actor when your workflow specifically needs the Forex Factory current-week event feed.

Support

If a run fails unexpectedly, share the run URL and a minimal input that reproduces the issue through the Actor page.

Useful details include:

  • the currency and impact filters used;
  • the local date range;
  • whether an unfiltered run worked;
  • the expected event title or URL.

These details make source-feed changes and parser regressions faster to diagnose.