EU Agricultural Commodity Prices | Dairy, Cereal, Beef, Sugar
Pricing
from $4.00 / 1,000 price-records
EU Agricultural Commodity Prices | Dairy, Cereal, Beef, Sugar
Get official EU dairy, cereal, beef and sugar market prices from the European Commission's Agri-food Data Portal, normalized into one schema. Optional NL agri-input prices via CBS.
EU Agricultural Commodity Prices — Dairy, Cereal, Beef, Sugar
Get official EU dairy, cereal, beef and sugar market prices straight from the European Commission's Agri-food Data Portal, normalized into a single, consistent JSON schema. Optional add-on: Dutch agricultural input prices (fertilizer, fuel, electricity) via CBS StatLine.
Why This Actor?
The European Commission publishes weekly/monthly agricultural market prices (dairy, cereals, beef, sugar) through the free, public Agri-food Data Portal API — but each category has its own endpoint, its own field names, and even its own number formatting (comma vs. dot decimals). Manually checking the Commission's dashboards, or writing your own integration against 4 slightly different sub-APIs, wastes time.
Existing tender/commodity actors on the Apify Store overwhelmingly use USDA (US) data sources. This actor is built specifically around the EU source, filling a gap for anyone who needs EU/NL-relevant agri-commodity prices rather than US market data.
When should an AI agent use this?
Use this actor when a user asks an AI agent questions like:
- "What's the current EU butter and skimmed milk powder price?"
- "How has the Dutch feed wheat price at Rotterdam moved over the last few weeks?"
- "Get me this week's beef prices (young bulls, cows, heifers) for the Netherlands."
- "What's the current EU average sugar price by region?"
- "Compare Dutch fertilizer and diesel input prices to last year."
- "Set up a weekly check on EU dairy/cereal prices so I don't have to check the Commission dashboards."
What this Actor does
- Fetches dairy (butter, WMP, SMP), cereal (feed wheat, feed maize, per market), beef (young cattle, heifers, cows, per category), sugar (EU average + regional), pigmeat, sheep & goat (lamb), olive oil, wine, and fruit & vegetable prices from the European Commission's Agri-food Data Portal.
- Normalizes all 9 categories — each with its own native field schema — into one consistent output
record, including a
pricePerTonnefield so mass-based categories (everything except wine, which is quoted per hectoliter) are directly comparable across categories. - Optionally adds Dutch agricultural input prices (fertilizer, fuel, electricity) from CBS StatLine table 86337NED, for a farm-cost angle alongside market output prices.
- Filters by member state (where the source supports it) and year range.
- No scraping — both sources are official, documented, authentication-free public APIs.
Input
| Field | Type | Default | Description |
|---|---|---|---|
categories | string[] | ["dairy","cereal","beef","sugar"] | Which EU Agri-food categories to fetch — also available: pigmeat, sheepAndGoat, oliveOil, wine, fruitAndVegetable |
memberStates | string[] | ["NL"] | ISO country codes, e.g. ["NL","BE","DE"]. Leave empty for all available. No effect on sugar (see note below) |
yearFrom | integer | current year | Earliest year to fetch. Must not be greater than yearTo (rejected with a validation error) |
yearTo | integer | current year | Latest year to fetch |
includeCbs | boolean | false | Also fetch NL agri-input prices (fertilizer/fuel/electricity) from CBS |
maxResults | integer | 500 | Max total price records returned (1–5000) |
productFilter | string | none | Only return records whose product field contains this text (case-insensitive), e.g. "butter". Leave empty for no filter |
berekenTrends | boolean | false | Add a period-over-period change field, calculated from the already-fetched period range |
alertOpDrempel | boolean | false | Compare each product's price with the previous run and flag a significant change |
alertDrempelPercentage | integer | 5 | Minimum absolute % change vs. the previous run to count as a price-alert |
Note on sugar: the EU Agri-food Data Portal's sugar endpoint has no per-member-state
breakdown — it only reports an EU average plus numbered regions (confirmed via live API testing).
memberStates therefore has no effect on sugar results; use the market field to see the
region/average instead.
Output
Each price is pushed to the dataset as a normalized JSON object:
{"source": "eu_agrifood","category": "dairy","product": "BUTTER","memberState": "NL","market": null,"price": 375,"priceRaw": "€375.00","unit": "100KG","pricePerTonne": 3750,"period": "2026-06-29/2026-07-05","sourceUrl": "https://agridata.ec.europa.eu/extensions/DashboardMilk/MilkProductPrices.html","vorigePeriodePrice": null,"periodeVeranderingPercentage": null,"trendBeschikbaar": false,"vorigeRunPrice": null,"vorigeRunVeranderingPercentage": null,"priceAlertDrempelOverschreden": false}
Fetch robustness
A failed fetch for one year/category (e.g. a temporary 5xx from the source) no longer fails the whole run —
it's logged as a warning and the run continues with the remaining years/categories, so data already fetched in
the same run isn't lost. If any warnings occurred, they're written to the actor's key-value store under
FETCH_WARNINGS (visible in the Apify Console run's storage tab) and printed to the run log.
Trend fields (berekenTrends, optional, separately charged)
With berekenTrends: true (typically combined with a yearFrom/yearTo range spanning multiple periods),
each record is compared with the previous period for the same source/category/product/member-state/market:
vorigePeriodePrice and periodeVeranderingPercentage. trendBeschikbaar is true only when a previous
period was actually found in the fetched range — the first period has nothing to compare against, so it stays
false rather than a guessed 0%. Only records with trendBeschikbaar: true are charged the extra
trend-record event.
Price alerts (alertOpDrempel, optional, separately charged)
With alertOpDrempel: true, each product's price is compared with the previous run (via the actor's
key-value store): vorigeRunPrice, vorigeRunVeranderingPercentage, and priceAlertDrempelOverschreden (true
when the absolute % change reaches alertDrempelPercentage, default 5). Meant for scheduled runs — you get
a direct signal for products whose price moved significantly since last time, without re-checking every
price yourself. Only alerted records are charged the extra price-alert event.
Alert streaks (trackAlertStreak, optional, separately charged)
With alertOpDrempel: true and trackAlertStreak: true, each group also gets alertStreak (the number of
consecutive runs, including this one, that crossed the threshold in the same direction) and
alertStreakRichting ("omhoog"/"omlaag"/null). A single one-off price spike looks the same as before
(alertStreak: 1), but a sustained trend across multiple scheduled runs is now visible directly instead of
requiring you to compare runs yourself. The extra alert-streak-signaal event is only charged once a streak
of 2 or more is actually detected.
Farm-margin indicator (berekenMargeIndicator, optional, separately charged)
With berekenMargeIndicator: true (requires both a dairy category and includeCbs: true), one extra
dataset item is added at the end of the run — the ratio of the average EU dairy price to the CBS fertilizer
price ("Kunstmest"), a rough farm-margin proxy:
{"type": "marge-indicator","jaar": "2026","gemiddeldeMelkprijs": 350,"melkprijsEenheid": "100KG","kunstmestPrijs": 50,"kunstmestEenheid": "","ratio": 7}
Only added (and charged as the new margin-record event) when both a dairy price and a CBS fertilizer price
are actually available in the same run — otherwise there's nothing to compare and no record is produced.
A cereal example (with a market field, which dairy/beef don't have):
{"source": "eu_agrifood","category": "cereal","product": "Feed wheat","memberState": "NL","market": "National Average","price": 216.5,"priceRaw": "€216,50","unit": "TONNES","period": "2026-06-29/2026-07-05","sourceUrl": "https://agridata.ec.europa.eu/extensions/DashboardCereals/CerealsPrices.html"}
Field Reference
| Field | Type | Description |
|---|---|---|
source | string | "eu_agrifood" or "cbs" |
category | string | "dairy", "cereal", "beef", "sugar", "pigmeat", "sheepAndGoat", "oliveOil", "wine", "fruitAndVegetable" or "input" (CBS only) |
product | string | Product/category name, e.g. "BUTTER", "Feed wheat", "Young cattle", "Elektriciteit" |
memberState | string | null | ISO country code. Always null for sugar and non-NL CBS rows aren't fetched |
market | string | null | Market/region name where the source has one (cereal markets, sugar regions, olive oil/fruit-veg markets). null otherwise |
price | number | null | Parsed numeric price. null if the source value couldn't be parsed |
priceRaw | string | The original price string as returned by the source, e.g. "€216,50" |
unit | string | Price unit, e.g. "100KG", "TONNES", "€/100Kg" |
pricePerTonne | number | null | Price converted to a fixed per-tonne basis, so mass-based categories are directly comparable. null when the unit isn't mass-based (e.g. wine per hectoliter) or unrecognized — never a guess |
period | string | ISO date range ("YYYY-MM-DD/YYYY-MM-DD"), ISO month ("YYYY-MM", sugar) or year ("YYYY", CBS) |
sourceUrl | string | Link to the relevant European Commission dashboard or CBS StatLine table |
alertStreak | number | null | Only with trackAlertStreak: consecutive same-direction threshold crossings, including this run. null when the feature is off |
alertStreakRichting | string | null | "omhoog"/"omlaag"/null — direction of the active streak |
Use cases
- Agricultural procurement / trading: track weekly EU dairy, cereal and beef prices without manually checking Commission dashboards.
- Farm cost monitoring (NL): combine market output prices with CBS input cost data
(
includeCbs: true) to track margin pressure. - Market research / journalism: quote official EU price benchmarks in reports.
- AI agents / MCP tooling: structured price data as context for market-analysis or procurement-advisory agents.
Pricing
This Actor uses Apify's Pay-Per-Event (PPE) pricing model.
- Actor Start: $0.00005 (Apify default)
price-record: $0.004 per price record returnedtrend-record: $0.008 extra, only withberekenTrendsenabled and only when a previous-period comparison was actually foundprice-alert: $0.015 extra, only withalertOpDrempelenabled and only when the price change vs. the previous run reaches the thresholdalert-streak-signaal: $0.01 extra, only withalertOpDrempel+trackAlertStreakenabled and only when a same-direction streak of 2 or more runs is actually detectedmargin-record: $0.006, only withberekenMargeIndicatorenabled and only when both a dairy price and a CBS fertilizer price are available in the same run
Legal
- EU Agri-food Data Portal: official European Commission (DG AGRI) service, explicitly built and documented as a public API for reuse of market data. No authentication or scraping involved.
- CBS StatLine: official Dutch government open data (OData), same reuse policy as other Dutch government sources.
- No personal data is processed — all data is aggregate market/region-level pricing, not individual businesses or people.
FAQ
How fresh is the data? The EU Agri-food Data Portal publishes dairy/beef weekly and cereal/sugar monthly-to-weekly depending on category. Every run fetches live from the source — there is no caching layer.
Why is memberState sometimes null?
The sugar endpoint reports an EU average plus numbered regions, not a per-country breakdown — this
is a limitation of the source API itself, confirmed via live testing, not a bug in this actor.
What does includeCbs add?
Dutch agricultural input prices (fertilizer, fuel, electricity) from CBS StatLine table 86337NED,
useful for a farm-cost angle alongside the EU market output prices. Only the most recent annual
figures are returned (this CBS table publishes yearly, not real-time).
Are there rate limits? Neither source publishes explicit rate-limit headers. This actor adds a small delay between requests to the EU Agri-food API as a conservative precaution.
Related Actors
Also by this developer:
- Shopify Product & Price Monitor — same profile: a change-detection price-monitoring feed with alert thresholding, for Shopify store products instead of EU agricultural commodities.
Keywords
agriculture, agri, commodity-prices, dairy, cereal, beef, sugar, pigmeat, sheep, goat, olive oil, wine, fruit, vegetable, eu-open-data, cbs, netherlands, farming, market-data
Changelog
0.5.0
- Added
trackAlertStreak: signals when a group crosses the price-alert threshold in the same direction across multiple consecutive runs (alertStreak/alertStreakRichting), instead of only a single-run alert. New charged eventalert-streak-signaal($0.01), only when a streak of 2 or more is detected. Confirmed by the user (2026-07-16). - Added
berekenMargeIndicator: a farm-margin-indicator dataset item (ratio of average EU dairy price to CBS fertilizer price). New charged eventmargin-record($0.006), only when both source prices are available in the same run. Confirmed by the user (2026-07-16).
0.4.0
- Added 5 new EU Agri-food categories:
pigmeat,sheepAndGoat,oliveOil,wine,fruitAndVegetable— same normalization pattern as the existing 4 categories. No pricing change. - Added a
pricePerTonneoutput field: a fixed conversion table normalizes mass-based units (100KG,KG,TONNES) to a per-tonne basis so categories with different native units are directly comparable.nullfor non-mass-based units (e.g. wine per hectoliter) — never a guessed value. Applied to EU Agri-food and CBS records alike. No pricing change. - Added a Zod validation rejecting
yearFrom > yearTo, which previously silently returned 0 EU Agri-food records with no explanation. - A failed fetch for one year/category no longer fails the whole run: the error is logged as a warning
(written to the key-value store under
FETCH_WARNINGS) and the run continues with the remaining years/categories, so already-fetched data in the same run isn't lost.
0.3.1 - Bugfix
- Fixed
price-alertnever firing across scheduled runs: the actor was reading/writing its snapshot to Apify's per-Run default key-value store, which is not shared between separate runs — so the "previous run" comparison always came back empty. Now uses a named, persistent key-value store. If you usealertOpDrempel, a new baseline will be captured on the next run.
0.3.0
- Added
berekenTrends: period-over-period % change, calculated from the fetched period range. New charged eventtrend-record($0.008). - Added
alertOpDrempel/alertDrempelPercentage: compares each product's price with the previous run and flags a significant change. New charged eventprice-alert($0.015). - Both confirmed by the user (2026-07-14, see docs/actor-verbeteringen/PRIJSBESLISSINGEN.md).
0.2.0
- Added
productFilter(case-insensitive substring match on theproductfield) so users can request e.g. only butter prices instead of the full dairy category. No pricing change.
0.1.0
- Initial release: dairy, cereal, beef, sugar from the EU Agri-food Data Portal, optional CBS Landbouwprijzen (input costs) add-on.