Oil Price API Commodities API
Discover commodity codes, availability, provenance, cadence, and coverage.
Discover commodity codes, availability, provenance, cadence, and coverage.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/oilpriceapi:oilpriceapi-commodities-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Oil Price API V1 Commodities API
version: v1
description: 'Source-aware oil and energy data API. Check each endpoint''s source timestamp,
coverage, and freshness fields before using a response in a time-sensitive workflow. ## Authentication
API-key endpoints use `Authorization: Token YOUR_API_KEY`. Operations that do
not require an API key explicitly declare an empty security requirement. `/v1/demo/prices` is keyless. ## Rate Limiting
- Free tier: 50 requests per day
- Paid tiers have plan-specific monthly quotas. - `402` means the allowance is exhausted: a Free or post-trial caller
must upgrade, and a paid plan has used its monthly allowance (the body
carries `MONTHLY_QUOTA_EXCEEDED` and reset metadata, so do not retry before
the reset). `429` means an active-trial allowance or a rolling rate limit
(for example the hourly safety limit) is exceeded; retry `429` and transient
`5xx` responses with bounded backoff. - Website login and signup (`POST /sessions` and `POST /users`) also enforce
authentication-attempt limits independently of API plan quotas: 3 attempts
per normalized email address in 5 minutes, and 3 attempts per minute per
verified visitor IP. Requests without a verified proxy identity retain
the existing 20 requests/minute IP ceiling. A `429` on these routes means
wait for `Retry-After` before retrying; upgrading a plan does not remove
authentication-attempt limits. Futures curves are never refused because a market is closed or a session has
just reopened. The last available data is served with `metadata.freshness_status`,
`metadata.stale`, `metadata.latest_data_at` and `metadata.stale_by_minutes`:
`outside_market_hours` while the venue is closed (weekend, daily break,
holiday); `awaiting_first_print` for the first 30 minutes of a new session
while only a valid prior close exists; `degraded` when the market is open and
the source is behind. None of these is a fresh trade; source timestamps remain
unchanged. Data older than the 96-hour serving bound is refused with 503. Gasoil reports `metadata.freshness_status: no_recent_trades` when the
benchmark contract has not traded within 30 minutes but our collector confirmed
the quote within that window and the curve printed within 90 minutes. The last
trade is served with its true `latest_data_at` and `stale_by_minutes`, plus
`source_checked_at` and `curve_latest_trade_at`. Paid monthly-cap responses include `retry_guidance`: immediate retries cannot
restore quota. When a representative sample supports it, `batching_opportunity`
describes an estimated lower request rate; batching does not restore an already
exhausted allowance. It may replace an unnecessary upgrade recommendation. ## Continuous futures coverage
On `/v1/futures/continuous/brent`, `/v1/futures/continuous/wti` and their
`/historical` routes, `metadata.history_available_from` is the earliest
stored public continuous futures source date, falling back to collection
date for older imports without a source timestamp. It is a date string or
null when no public observations exist. Coverage metadata is cached for up
to one hour and does not promise observations or volume on every later date. It describes the archive independently of the request''s date range; account
depth limits remain in `metadata.history_window` on historical responses. Latest-response `metadata.total_historical_records` counts stored public
snapshots, including revisions, rather than distinct source dates. Latest
quotes and their prior-day comparisons exclude private organization rows
and other price types. Repeated source timestamps select the later collected
revision; the oldest metadata/response cache formats are no longer used. ## Spread and indicator query parameters
Spread and indicator endpoints reject unrecognized query parameter names with
HTTP 400 and `error.code: UNKNOWN_PARAMETERS`, after authentication and access
checks. The error includes `unrecognized_parameters`, `allowed_parameters`,
and a `suggestions` map for recognized date-name mistakes; values are not
echoed.'
contact:
name: Oil Price API Support
email: support@oilpriceapi.com
url: https://oilpriceapi.com
license:
name: Commercial License
url: https://oilpriceapi.com/terms
servers:
- url: https://api.oilpriceapi.com
description: Production server
tags:
- name: Commodities
description: Discover commodity codes, availability, provenance, cadence, and coverage.
paths:
/v1/commodities:
get:
summary: Get the callable commodity catalog
operationId: getV1Commodities
tags:
- Commodities
description: 'Retrieve metadata for callable commodity codes. Every item declares
`status` and `has_data`. Pass `include_unavailable=true` to inspect
discontinued, source-limited, and not-yet-served catalog entries.'
parameters:
- name: include_unavailable
in: query
required: false
description: Include configured commodities that currently have no served data.
schema:
type: boolean
default: false
example: true
- name: include_discontinued
in: query
required: false
description: Include discontinued commodity definitions.
schema:
type: boolean
default: false
example: false
security:
- ApiKeyAuth: []
responses:
'200':
description: List of all commodities
content:
application/json:
schema:
$ref: '#/components/schemas/CommoditiesResponse'
'401':
description: Unauthorized - Invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/commodities/{code}:
get:
summary: Get commodity details by code
operationId: getV1CommoditiesByCode
tags:
- Commodities
description: Retrieve detailed information about a specific commodity including current pricing if available
parameters:
- name: code
in: path
required: true
description: Commodity code
schema:
type: string
example: BRENT_CRUDE_USD
security:
- ApiKeyAuth: []
responses:
'200':
description: Commodity details
content:
application/json:
schema:
$ref: '#/components/schemas/CommodityDetailResponse'
'404':
description: Commodity not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/commodities/{code}/coverage:
get:
summary: Get dataset coverage and account access
operationId: getV1CommodityCoverage
tags:
- Commodities
description: 'Returns the versioned, customer-safe coverage contract for one catalog
code. History bounds come from an asynchronously refreshed materialized
snapshot; this request does not scan the raw price table. Availability
and account entitlement are separate so callers can distinguish missing
data from plan access.'
parameters:
- name: code
in: path
required: true
description: Commodity code, including supported dynamic contract codes
schema:
type: string
example: BRENT_CRUDE_USD
security:
- ApiKeyAuth: []
responses:
'200':
description: Versioned dataset coverage contract
content:
application/json:
schema:
$ref: '#/components/schemas/DatasetCoverageResponse'
'401':
description: Unauthorized - Invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Commodity code is unknown
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/commodities/categories:
get:
summary: Get commodities grouped by category
operationId: getV1CommoditiesCategories
tags:
- Commodities
description: Retrieve commodities organized by their categories (oil, gas, metal, forex, coal)
security:
- ApiKeyAuth: []
responses:
'200':
description: Commodities grouped by category
content:
application/json:
schema:
$ref: '#/components/schemas/CommodityCategoriesResponse'
'401':
description: Unauthorized
'500':
$ref: '#/components/responses/InternalServerError'
/v1/meta/methodology:
get:
summary: Get the data sources and methodology table
operationId: getV1MetaMethodology
tags:
- Commodities
description: 'One row per catalogue code with its source label, instrument type,
update frequency, publication cadence, nominal stale threshold, source
timezone, front-month roll rule and revision policy (spec T3).
Generated from the same catalogue, source-cadence registry, freshness
and futures-contract code the API serves from, so it cannot drift from
API behaviour. A fact the metadata does not hold reads "not recorded";
it is never estimated. Source labels name government publishers and
render `market_reporting` for every other source. OilPriceAPI grants no
rights in any data.
Takes the same listing parameters as GET /v1/commodities. Keyless and
cached for an hour.'
security: []
parameters:
- name: include_unavailable
in: query
required: false
description: Also list codes that are not backed by data.
schema:
type: boolean
example: false
- name: include_discontinued
in: query
required: false
description: Also list discontinued codes.
schema:
type: boolean
example: false
responses:
'200':
description: Methodology rows and their coverage
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
codes:
type: array
items:
type: object
properties:
code:
type: string
example: WTI_USD
source:
description: Object with labels, roles and data_source, or "not recorded".
example:
labels:
- market_reporting
roles:
- market_data
instrument_type:
type: string
example: front_month_futures
update_frequency:
type: string
example: realtime
publication_cadence:
description: Array of publication cadences, or "not recorded".
example:
- intraday
stale_threshold:
description: Object with expected_max_age_seconds, stale_after_seconds and basis, or "not recorded".
example:
expected_max_age_seconds: 86400
stale_after_seconds: 172800
timezone:
type: string
example: not recorded
roll_rule:
description: Object for front-month benchmarks, "not applicable" for non-futures, otherwise "not recorded".
example: not applicable
revision_policy:
type: string
example: not recorded
coverage:
type: object
properties:
codes:
type: integer
example: 900
source_type_cadence_complete:
type: integer
example: 6
recorded:
type: object
additionalProperties:
type: integer
meta:
type: object
properties:
timestamps_timezone:
type: string
example: UTC
not_recorded_value:
type: string
example: not recorded
'429':
description: Rate limited by IP. Honour Retry-After.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
components:
schemas:
CommodityWithPrice:
allOf:
- $ref: '#/components/schemas/Commodity'
- type: object
properties:
sources:
type: array
description: Per-source publication & collection metadata (#5155). What the publisher does (observation frequency, release cadence, lag, revisions) and what OilPriceAPI does (sampling frequency, backfill, ingestion latency).
items:
$ref: '#/components/schemas/SourceInfo'
links:
$ref: '#/components/schemas/Links'
your_access:
$ref: '#/components/schemas/YourAccess'
current_price:
type:
- object
- 'null'
properties:
value:
type: number
format: float
example: 75.42
formatted:
type: string
example: $75.42
currency:
type: string
example: USD
last_updated:
type: string
format: date-time
example: '2025-01-20T10:30:00.000Z'
Links:
type: object
description: Canonical OilPriceAPI links for this commodity. Absolute URLs on OilPriceAPI hosts only.
properties:
docs:
type: string
format: uri
example: https://docs.oilpriceapi.com/api-reference/commodities/details
publication_schedule:
type: string
format: uri
example: https://docs.oilpriceapi.com/data/publication-schedules#jet_fuel_usd
openapi:
type: string
format: uri
example: https://api.oilpriceapi.com/.well-known/openapi.json
latest:
type: string
format: uri
example: https://api.oilpriceapi.com/v1/prices/latest?by_code=JET_FUEL_USD
historical:
type: string
format: uri
example: https://api.oilpriceapi.com/v1/prices/historical?by_code=JET_FUEL_USD
CommodityCategoriesResponse:
type: object
properties:
categories:
type: object
additionalProperties:
type: object
properties:
name:
type: string
example: Oil
commodities:
type: array
items:
type: object
properties:
code:
type: string
example: BRENT_CRUDE_USD
name:
type: string
example: Brent Crude Oil
currency:
type: string
example: USD
description:
type: string
example: North Sea Brent Crude Oil
unit:
type: string
example: barrel
unit_description:
type: string
example: Price per barrel
CommodityDetailResponse:
type: object
required:
- status
- data
properties:
status:
type: string
enum:
- success
data:
$ref: '#/components/schemas/CommodityWithPrice'
YourAccess:
type: object
description: The requesting account's historical-depth entitlement for this commodity, derived from the same limit the historical price endpoints enforce — advertisement and entitlement cannot disagree.
properties:
history_available_from:
type:
- string
- 'null'
format: date
description: Earliest date this account can query; null means the full archive
example: '2025-07-21'
note:
type: string
example: Your plan includes 1 year of price history (from 2025-07-21). Upgrade for the full archive.
SourceInfo:
type: object
required:
- label
- role
- publication
- collection
properties:
label:
type: string
description: Customer-safe source label. Government/official sources are named (e.g. "EIA"); market sources render 'market_reporting'.
example: EIA
role:
type: string
description: Role this source plays for the commodity
example: official_spot
publication:
type: object
description: What the publisher does — independent of OilPriceAPI
required:
- observation_frequency
- cadence
- schedule
properties:
observation_frequency:
type: string
description: How often the underlying series has observations
example: weekday
cadence:
type: string
description: How the publisher releases those observations
example: weekly_batch
schedule:
type: string
description: Plain-English publication schedule
example: Published by EIA in weekly batches, typically Wednesdays, covering trading days through the prior Monday.
typical_lag_days:
type:
- object
- 'null'
properties:
min:
type: integer
example: 2
max:
type: integer
example: 8
revisions:
type:
- string
- 'null'
description: Whether the publisher revises previously published periods
collection:
type: object
description: What OilPriceAPI does — sampling, backfill, ingestion
required:
- frequency
properties:
frequency:
type: string
example: daily at 21:00 UTC
backfills_missed_data:
type: boolean
captures_revisions:
type: boolean
ingestion_latency:
type: string
example: typically within 24 hours of source publication
Commodity:
type: object
required:
- code
- name
- currency
- category
- unit
- status
- has_data
properties:
code:
type: string
description: Unique commodity identifier
example: BRENT_CRUDE_USD
name:
type: string
description: Human-readable commodity name
example: Brent Crude Oil
currency:
type: string
description: Base currency for pricing
example: USD
category:
type: string
description: Commodity category
example: oil
description:
type: string
description: Detailed description
example: North Sea Brent Crude Oil
unit:
type: string
description: Unit of measurement
example: barrel
unit_description:
type: string
description: Detailed unit description
example: Price per barrel
multiplier:
type: integer
description: Deprecated — internal storage configuration detail retained for backward compatibility only. Do not build on it.
example: 100
validation:
type: object
description: Deprecated — internal validation configuration retained for backward compatibility only. Do not build on it.
properties:
min:
type: number
description: Minimum valid price
example: 0
max:
type: number
description: Maximum valid price
example: 200
price_change_threshold:
type: number
description: Deprecated — internal alerting configuration retained for backward compatibility only. Do not build on it.
example: 10
data_source:
type:
- string
- 'null'
description: Customer-safe source label; internal venue and scraper names are masked
update_frequency:
type:
- string
- 'null'
description: Expected source-specific refresh cadence
status:
type: string
enum:
- available
- unavailable
has_data:
type: boolean
unavailable_reason:
type:
- string
- 'null'
enum:
- never_had_data
- not_served
- withheld
- discontinued
- null
unavailable_detail:
type:
- string
- 'null'
sources:
type: array
description: Compact per-source cadence summary (#5155). The detail endpoint /v1/commodities/{code} returns the full publication/collection blocks per source.
items:
type: object
properties:
label:
type: string
description: Customer-safe source label; masked sources render 'market_reporting'
example: EIA
role:
type: string
example: official_spot
publication:
type: object
properties:
cadence:
type: string
example: weekly_batch
collection:
type: object
properties:
frequency:
type: string
example: daily at 21:00 UTC
DatasetCoverage:
type: object
required:
- schema_version
- generated_at
- code
- name
- category
- currency
- unit
- availability
- source_class
- expected_cadence
- latest
- history
- delivery
- access
- usage_review
properties:
schema_version:
type: string
enum:
- '1.0'
generated_at:
type: string
format: date-time
code:
type: string
example: BRENT_CRUDE_USD
name:
type: string
category:
type: string
geography:
type:
- string
- 'null'
currency:
type: string
unit:
type: string
availability:
type: string
enum:
- active
- stale
- discontinued
- source_limited
- unavailable
- empty
availability_reason:
type:
- string
- 'null'
source_class:
type: string
enum:
- official_or_public_source
- published_market_reference
expected_cadence:
type: string
latest:
type: object
required:
- as_of
- stale
- age_days
properties:
as_of:
type:
- string
- 'null'
format: date-time
stale:
type:
- boolean
- 'null'
age_days:
type:
- integer
- 'null'
history:
type: object
required:
- available_from
- available_to
- granularities
- coverage_type
- measured_at
- sample_count
properties:
available_from:
type:
- string
- 'null'
format: date
available_to:
type:
- string
- 'null'
format: date
granularities:
type: array
items:
type: string
coverage_type:
type: string
enum:
- observed_series
- unknown
measured_at:
type:
- string
- 'null'
format: date-time
sample_count:
type:
- integer
- 'null'
delivery:
type: array
items:
type: string
enum:
- rest
- websocket
- webhook
access:
type: object
description: Account-aware access states derived from canonical entitlement policies
additionalProperties: true
usage_review:
type: object
required:
- public_display
- redistribution
properties:
public_display:
type: string
redistribution:
type: string
CommoditiesResponse:
type: object
required:
- status
- data
properties:
status:
type: string
enum:
- success
data:
type: object
required:
- commodities
- metadata
properties:
commodities:
type: array
items:
$ref: '#/components/schemas/Commodity'
metadata:
type: object
properties:
availability:
type: object
properties:
returned:
type: integer
unavailable_excluded:
type: integer
note:
type:
- string
- 'null'
DatasetCoverageResponse:
type: object
required:
- status
- data
properties:
status:
type: string
enum:
- success
data:
$ref: '#/components/schemas/DatasetCoverage'
ErrorResponse:
type: object
properties:
error:
type: object
properties:
code:
type: string
description: Machine-readable error code (e.g. UNAUTHORIZED, NOT_FOUND, INVALID_PARAMETER).
example: UNAUTHORIZED
message:
type: string
example: 'Missing or invalid API key. Include header: Authorization: Token YOUR_API_KEY'
status:
type: integer
example: 401
request_id:
type: string
example: fa0e389f-ca86-47b2-b167-2b4645a2fb8b
docs:
type: string
example: https://docs.oilpriceapi.com#UNAUTHORIZED
signup_url:
type:
- string
- 'null'
example: https://www.oilpriceapi.com/auth/signup
demo_endpoint:
type:
- string
- 'null'
example: /v1/demo/prices
responses:
InternalServerError:
description: Unexpected server error. Retry transient failures with bounded backoff and retain the request ID when contacting support.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: Authorization
description: 'API key as: Authorization: Token YOUR_API_KEY'
externalDocs:
description: OilPriceAPI developer documentation
url: https://docs.oilpriceapi.com