Palm oil physical price API
Get the latest accepted Palm oil observation
Endpoint and request
REST endpoint
GET /v1/commodities/palmoil/physical/{series_id}Contract request
curl --request GET \
--url "https://api.narwhalapi.com/v1/commodities/palmoil/physical/id-ri-oil-palm-ffb-smallholder-purchase-agreement" \
--header "Authorization: Bearer $NARWHAL_API_KEY"MCP uses commodities_get_palmoil_physical_price. REST and MCP share the same schema, account quota, rights check, and problem shape.
Parameters
| Name | Required | Type | Meaning |
|---|---|---|---|
series_id | Yes | path · stable Narwhal ID | Use an ID returned by discovery. |
price_month | No | query · YYYY-MM | MPOB CPO only. Selects one quoted month; defaults to each report's own month. |
Response
Contract example
{
"series_id": "id-ri-oil-palm-ffb-smallholder-purchase-agreement",
"currency": "IDR",
"unit": "kilogram",
"period_start": "2026-08-26",
"period_end": "2026-09-01",
"revision": 1,
"prices": [
{
"tree_age_min_years": 3,
"tree_age_max_years": 3,
"price": "2998.31"
},
{
"tree_age_min_years": 4,
"tree_age_max_years": 4,
"price": "3347.20"
},
{
"tree_age_min_years": 5,
"tree_age_max_years": 5,
"price": "3595.38"
},
{
"tree_age_min_years": 6,
"tree_age_max_years": 6,
"price": "3734.94"
},
{
"tree_age_min_years": 7,
"tree_age_max_years": 7,
"price": "3818.86"
},
{
"tree_age_min_years": 8,
"tree_age_max_years": 8,
"price": "3865.46"
},
{
"tree_age_min_years": 9,
"tree_age_max_years": 9,
"price": "3878.72"
},
{
"tree_age_min_years": 10,
"tree_age_max_years": 20,
"price": "3836.93"
},
{
"tree_age_min_years": 21,
"tree_age_max_years": 21,
"price": "3770.94"
},
{
"tree_age_min_years": 22,
"tree_age_max_years": 22,
"price": "3695.31"
},
{
"tree_age_min_years": 23,
"tree_age_max_years": 23,
"price": "3609.33"
},
{
"tree_age_min_years": 24,
"tree_age_max_years": 24,
"price": "3544.29"
},
{
"tree_age_min_years": 25,
"tree_age_max_years": 25,
"price": "3490.84"
},
{
"tree_age_min_years": 26,
"tree_age_max_years": 26,
"price": "3471.62"
},
{
"tree_age_min_years": 27,
"tree_age_max_years": 27,
"price": "3441.82"
},
{
"tree_age_min_years": 28,
"tree_age_max_years": 28,
"price": "3385.41"
},
{
"tree_age_min_years": 29,
"tree_age_max_years": 29,
"price": "3344.02"
},
{
"tree_age_min_years": 30,
"tree_age_max_years": 30,
"price": "3249.41"
}
]
}| Field | Type | Required | Meaning |
|---|---|---|---|
series_id | string | Yes | Stable physical-series identity. |
currency / unit | strings | Yes | Currency and native unit: kilogram for Indonesian FFB schedules, metric_ton for CPO, or one_percent_oer for Malaysian FFB references. |
period_start / period_end | dates | Yes | Effective prices use inclusive dates. MPOB uses the report date through the next day, with an exclusive end. |
revision | integer | Yes | Revision of the price or complete schedule. |
price or prices | decimal string or complete array | Yes | A positive decimal-string price, or a complete prices array with tree_age_min_years, tree_age_max_years and price. Both age bounds are inclusive. Malaysian FFB stays in one_percent_oer. |
price_month | YYYY-MM | No | Required for MPOB CPO quotes; identifies the quoted month; period_start and period_end identify the report-day observation interval. |
Errors and quota
400 invalid_query— a code, area, date range, limit, or selector is invalid.401 invalid_api_key— the Bearer key is missing or rejected.403 plan_upgrade_required— the requested period or start is before your plan's history window (Free 12 months, Basic 5 years, Pro full).404 palmoil_series_not_found— no complete approved data matches the request.429 rate_limit_exceededorquota_exhausted— the shared allowance is exhausted.503 palmoil_unavailable— a complete publication cannot safely satisfy the Interface.
Rejected requests and server errors do not consume monthly quota.
Coverage
CPO and Malaysian FFB return scalar prices. Indonesian FFB preserves complete age schedules. The newest no-trade report never becomes an older price presented as current.
Available with a Narwhal API key.
Docs