Browse all documentation

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

NameRequiredTypeMeaning
series_idYespath · stable Narwhal IDUse an ID returned by discovery.
price_monthNoquery · YYYY-MMMPOB 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"
    }
  ]
}
FieldTypeRequiredMeaning
series_idstringYesStable physical-series identity.
currency / unitstringsYesCurrency and native unit: kilogram for Indonesian FFB schedules, metric_ton for CPO, or one_percent_oer for Malaysian FFB references.
period_start / period_enddatesYesEffective prices use inclusive dates. MPOB uses the report date through the next day, with an exclusive end.
revisionintegerYesRevision of the price or complete schedule.
price or pricesdecimal string or complete arrayYesA 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_monthYYYY-MMNoRequired 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_exceeded or quota_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.