Oil Price API Indicators API
The Indicators API from Oil Price API — 10 operation(s) for indicators.
The Indicators API from Oil Price API — 10 operation(s) for indicators.
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-indicators-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 Indicators 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: Indicators
paths:
/v1/indicators/fuel-switching:
get:
summary: Get the fuel-switching indicator
operationId: getV1IndicatorsFuelSwitching
tags:
- Indicators
description: Gas-to-oil switching economics on an energy-equivalent basis.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get the fuel-switching indicator
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
energy_equivalent:
type: object
properties: {}
oil_parity:
type: object
properties: {}
components:
type: object
properties: {}
historical_context:
type: object
properties: {}
timestamp:
type: string
format: date-time
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/indicators/fuel-switching/historical:
get:
summary: Get fuel-switching history
operationId: getV1IndicatorsFuelSwitchingHistorical
tags:
- Indicators
description: Historical fuel-switching series.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get fuel-switching history
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
period:
type: string
example: 30d
count:
type: integer
data:
type: array
items:
type: object
properties:
date:
type: string
value:
type: number
crude_benchmark:
type: string
gas_benchmark:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: period
in: query
required: false
schema:
type: string
example: 30d
description: Lookback window for the series.
/v1/indicators/price-context:
get:
summary: Get price context for a code
operationId: getV1IndicatorsPriceContext
tags:
- Indicators
description: Statistical context for a commodity's current price.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get price context for a code
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
code:
type: string
price:
type: number
context_as_of:
type: string
format: date-time
description: Historical inputs are cached for up to 15 minutes. Changes, ranks and anomaly calculations use the current response price.
context:
type: object
properties: {}
timestamp:
type: string
format: date-time
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: code
in: query
required: true
schema:
type: string
example: BRENT_CRUDE_USD
description: Commodity code. See /v1/commodities for the catalogue.
/v1/indicators/storage-analytics:
get:
summary: Get storage analytics
operationId: getV1IndicatorsStorageAnalytics
tags:
- Indicators
description: Storage level analytics with seasonal range and draw rate.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get storage analytics
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
location:
type: string
name:
type: string
current:
type: object
properties: {}
range_52w:
type: object
properties: {}
seasonal:
type: object
properties: {}
draw_rate:
type: object
properties: {}
anomalies:
type: array
items:
type: object
properties: {}
signal:
type: string
trading_implication:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: location
in: query
required: false
schema:
type: string
example: CUSHING
description: Storage location. Omit for the default location.
/v1/indicators/storage-analytics/all:
get:
summary: Get storage analytics for all locations
operationId: getV1IndicatorsStorageAnalyticsAll
tags:
- Indicators
description: Storage analytics across every location.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get storage analytics for all locations
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
locations:
type: array
items:
type: object
properties:
location:
type: string
signal:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/indicators/cftc-positioning:
get:
summary: Get CFTC positioning
operationId: getV1IndicatorsCftcPositioning
tags:
- Indicators
description: CFTC Legacy Futures Only non-commercial positioning, in contracts. BRENT identifies NYMEX Brent Last Day (06765T), not ICE Brent. This is not disaggregated managed money or combined futures-and-options data. report_date is the source observation date; collected_at/timestamp are collection times and published_at is null when unknown. Metrics join only the same observation date; unavailable fields remain null and coverage reports partial fields. Undated legacy rows are excluded.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get CFTC positioning
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
commodity:
type: string
name:
type: string
positioning:
type: object
properties: {}
signal:
type: string
percentile_1y:
type:
- number
- 'null'
week_change:
type:
- integer
- 'null'
report_date:
type: string
format: date
report:
type: object
description: Dataset, contract_market_code, population, instrument_scope and unit.
coverage:
type: object
description: Complete/partial status and missing_fields (long, short, commercial_net, open_interest).
collected_at:
type: string
format: date-time
published_at:
type:
- string
- 'null'
format: date-time
timestamp:
type: string
format: date-time
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: commodity
in: query
required: false
schema:
type: string
enum:
- WTI
- BRENT
- NATURAL_GAS
- HEATING_OIL
- GASOLINE
example: WTI
description: Commodity. Omit for the default commodity.
/v1/indicators/cftc-positioning/historical:
get:
summary: Get CFTC positioning history
operationId: getV1IndicatorsCftcPositioningHistorical
tags:
- Indicators
description: CFTC Legacy Futures Only history grouped by source observation date, excluding rows without observed_at. Each row has date, spec_net, open_interest and spec_net_pct_oi. Requested period is retained and coverage exposes the effective 730-day range and range_limited flag. This endpoint does not provide managed-money futures-and-options history.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get CFTC positioning history
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
period:
type: object
properties:
start:
type: string
format: date
end:
type: string
format: date
coverage:
type: object
description: Effective start/end, source_observation date basis, and range_limited.
count:
type: integer
data:
type: array
items:
type: object
properties:
date:
type: string
spec_net:
type: integer
open_interest:
type:
- integer
- 'null'
spec_net_pct_oi:
type:
- number
- 'null'
commodity:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: commodity
in: query
schema:
type: string
enum:
- WTI
- BRENT
- NATURAL_GAS
- HEATING_OIL
- GASOLINE
default: WTI
example: WTI
description: Energy contract family; defaults to WTI. BRENT is NYMEX Brent Last Day.
- name: start_date
in: query
schema:
type: string
format: date
example: '2026-09-01'
description: Source observation date; defaults to 90 days ago, capped at 730 days.
- name: end_date
in: query
schema:
type: string
format: date
example: '2026-10-02'
description: Last source observation date; defaults to today.
/v1/indicators/cftc-positioning/all:
get:
summary: Get CFTC positioning for all commodities
operationId: getV1IndicatorsCftcPositioningAll
tags:
- Indicators
description: CFTC positioning across every commodity.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get CFTC positioning for all commodities
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
commodities:
type: array
items:
type: object
properties:
commodity:
type: string
signal:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/indicators/annotations:
get:
summary: Get price annotations for a code
operationId: getV1IndicatorsAnnotations
tags:
- Indicators
description: Narrative annotations explaining notable moves in a series.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get price annotations for a code
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
code:
type: string
price:
type: number
annotation_count:
type: integer
annotations:
type: array
items:
type: object
properties: {}
timestamp:
type: string
format: date-time
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: code
in: query
required: true
schema:
type: string
example: BRENT_CRUDE_USD
description: Commodity code. See /v1/commodities for the catalogue.
/v1/indicators/annotations/batch:
get:
summary: Get annotation coverage for several codes
operationId: getV1IndicatorsAnnotationsBatch
tags:
- Indicators
description: Which of the supplied codes carry annotations.
security:
- ApiKeyAuth: []
responses:
'200':
description: Get annotation coverage for several codes
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
properties:
total_codes:
type: integer
codes_with_annotations:
type: integer
annotated:
type: array
items:
type: string
required:
- status
- data
'400':
description: A required parameter is missing or invalid. The message enumerates valid values.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalServerError'
parameters:
- name: codes
in: query
required: true
schema:
type: string
example: BRENT_CRUDE_USD,WTI_USD
description: Comma-separated commodity codes.
components:
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'
schemas:
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
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