---
openapi: 3.0.4
info:
  title: Oil Price API V1
  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 a Free or post-trial caller must upgrade for the exhausted
      allowance or requested dataset. `429` means an active-trial or paid-plan
      quota or rolling rate limit is exhausted. Use the response's reset metadata
      before retrying quota errors; retry transient `5xx` responses with bounded
      backoff.

    ## Available Data Categories

    ## Discovery

    Use `GET /v1/commodities` for the current catalog. Endpoint-level metadata
    is authoritative for authentication, plan access, source, and freshness.
  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
externalDocs:
  description: OilPriceAPI developer documentation
  url: https://docs.oilpriceapi.com
tags:
- name: Discovery
  description: No-key representative sample endpoints for API discovery.
- name: API Key Management
  description: Create, list, rotate, and revoke API keys.
- name: Account
  description: Account profile, usage, and entitlement metadata.
- name: Commodities
  description: Discover commodity codes, availability, provenance, cadence, and coverage.
- name: Demo (No Auth)
  description: Keyless representative responses for evaluation.
- name: Diesel Prices
  description: Diesel price datasets and regional views.
- name: Drilling Intelligence
  description: Rig, permit, frac-spread, and drilling activity datasets.
- name: Electricity Prices
  description: Electricity price datasets.
- name: Fuel Surcharge
  description: Published carrier fuel-surcharge schedules and history.
- name: Futures
  description: Futures curves, contracts, and historical settlements.
- name: Gasoline Prices
  description: Gasoline price datasets and regional views.
- name: Marine Fuels
  description: Marine and bunker fuel prices.
- name: Market Brief
  description: Source-aware market summaries.
- name: Premium
  description: Endpoints requiring a paid dataset entitlement.
- name: Prices
  description: Latest, windowed, and historical commodity prices.
- name: Storage
  description: Petroleum and natural-gas storage datasets.
- name: Subscriptions
  description: Subscription lifecycle and billing state.
- name: Webhooks
  description: Webhook endpoint configuration and delivery history.
- name: Well Lifecycle
  description: Well lifecycle availability, cohorts, and state coverage.
- name: Well Production
  description: Well production data and operational analytics.
paths:
  "/v1/api-keys":
    get:
      summary: List API Keys
      operationId: getV1ApiKeys
      tags:
      - API Key Management
      description: List all API keys for the authenticated user. Never returns full
        tokens, only hints.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: List of API keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      api_keys:
                        type: array
                        items:
                          "$ref": "#/components/schemas/ApiKey"
                      total_count:
                        type: integer
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
    post:
      summary: Create API Key
      operationId: postV1ApiKeys
      tags:
      - API Key Management
      description: |
        Create a new API key. Maximum 5 active keys per user.
        The full token (`plain_token`) is only returned in this response — store it securely.
      security:
      - ApiKeyAuth: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  nullable: true
                  description: Optional label (e.g. "Production", "Staging")
                  example: Production
      responses:
        '200':
          description: API key created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      api_key:
                        allOf:
                        - "$ref": "#/components/schemas/ApiKey"
                        - type: object
                          properties:
                            plain_token:
                              type: string
                              description: Full token (64 hex chars) — only returned
                                on create/roll
                              example: a1b2c3d4e5f6...
        '401':
          description: Unauthorized
        '422':
          description: Maximum active keys reached
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/api-keys/{id}":
    delete:
      summary: Revoke API Key
      operationId: deleteV1ApiKeysById
      tags:
      - API Key Management
      description: Soft-revoke an API key. Cannot revoke your last active key.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Resource identifier.
        schema:
          type: string
          format: uuid
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Key revoked
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - data
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  data:
                    type: object
                    additionalProperties: true
        '404':
          description: Key not found (or belongs to another user)
        '422':
          description: Cannot revoke last active key or already revoked
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/api-keys/{id}/roll":
    post:
      summary: Roll (Regenerate) API Key
      operationId: postV1ApiKeysByIdRoll
      tags:
      - API Key Management
      description: |
        Regenerate the token for an API key. The key ID stays the same but gets a new token.
        The old token is immediately invalidated.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Resource identifier.
        schema:
          type: string
          format: uuid
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Token regenerated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      api_key:
                        allOf:
                        - "$ref": "#/components/schemas/ApiKey"
                        - type: object
                          properties:
                            plain_token:
                              type: string
                              description: New full token (64 hex chars)
        '404':
          description: Key not found
        '422':
          description: Cannot roll a revoked key
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/demo/prices":
    get:
      summary: Get demo prices (No authentication required)
      operationId: getV1DemoPrices
      tags:
      - Demo (No Auth)
      description: |
        **Start here - no API key needed!**

        Returns the latest prices for free-tier commodities. Perfect for testing the API
        before signing up or for embedding in documentation examples.

        **Available commodities:**
        - Brent Crude Oil (BRENT_CRUDE_USD)
        - WTI Crude Oil (WTI_USD)
        - Natural Gas Henry Hub (NATURAL_GAS_USD)
        - Gold (GOLD_USD)
        - Gold AM/PM Fix (GOLD_AM_USD, GOLD_AM_GBP, GOLD_AM_EUR, GOLD_PM_USD, GOLD_PM_GBP, GOLD_PM_EUR)
        - Silver (SILVER_USD)
        - Silver Fix (SILVER_FIX_USD, SILVER_FIX_GBP, SILVER_FIX_EUR)
        - EUR/USD (EUR_USD)
        - USD/NOK (USD_NOK)
        - EUR/NOK (EUR_NOK)
        - GBP/USD (GBP_USD)
        - Heating Oil (HEATING_OIL_USD)
        - Gasoline RBOB (GASOLINE_USD)
        - Diesel (DIESEL_USD)

        **Rate limit:** 20 requests per hour per IP

        **Need more?** [Get a free API key](https://www.oilpriceapi.com/signup) for full access.
      security: []
      responses:
        '200':
          description: Demo price data with code examples
          headers:
            X-RateLimit-Limit:
              description: Maximum requests per hour
              schema:
                type: integer
                example: 20
            X-RateLimit-Remaining:
              description: Remaining requests this hour
              schema:
                type: integer
            X-Demo-Mode:
              description: Indicates demo mode is active
              schema:
                type: string
                example: 'true'
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DemoPricesResponse"
              example:
                status: success
                data:
                  prices:
                  - code: BRENT_CRUDE_USD
                    name: Brent Crude Oil
                    price: 75.42
                    currency: USD
                    updated_at: '2026-01-10T15:30:00Z'
                  - code: WTI_USD
                    name: WTI Crude Oil
                    price: 71.28
                    currency: USD
                    updated_at: '2026-01-10T15:30:00Z'
                  meta:
                    demo_mode: true
                    rate_limit: 20 requests per hour
                    signup_url: https://www.oilpriceapi.com/signup
                  examples:
                    curl: curl -X GET "https://api.oilpriceapi.com/v1/demo/prices"
                    python: |
                      import requests
                      response = requests.get("https://api.oilpriceapi.com/v1/demo/prices")
                      print(response.json())
                    javascript: |
                      fetch("https://api.oilpriceapi.com/v1/demo/prices")
                        .then(r => r.json())
                        .then(console.log)
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Rate limit exceeded
                  message:
                    type: string
                    example: Demo API is limited to 20 requests per hour. Sign up
                      for a free API key for higher limits.
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/demo/prices/{code}":
    get:
      summary: Get single demo commodity price
      operationId: getV1DemoPricesByCode
      tags:
      - Demo (No Auth)
      description: |
        Get the latest price for a specific free-tier commodity.

        **No authentication required.**

        Only free-tier commodities are available. For premium commodities,
        [sign up for a free API key](https://www.oilpriceapi.com/signup).
      security: []
      parameters:
      - name: code
        in: path
        required: true
        description: Commodity code (must be a free-tier commodity)
        schema:
          type: string
          enum:
          - BRENT_CRUDE_USD
          - WTI_USD
          - NATURAL_GAS_USD
          - GOLD_USD
          - SILVER_USD
          - PLATINUM_USD
          - PALLADIUM_USD
          - COPPER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - GBP_USD
          - HEATING_OIL_USD
          - GASOLINE_USD
          - DIESEL_USD
          example: BRENT_CRUDE_USD
      responses:
        '200':
          description: Single commodity price
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      code:
                        type: string
                        example: BRENT_CRUDE_USD
                      name:
                        type: string
                        example: Brent Crude Oil
                      price:
                        type: number
                        format: float
                        example: 75.42
                      currency:
                        type: string
                        example: USD
                      updated_at:
                        type: string
                        format: date-time
        '403':
          description: Premium commodity requested
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: fail
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: PREMIUM_COMMODITY
                      message:
                        type: string
                        example: PERMIAN_DUC_WELLS is a premium commodity. Sign up
                          for a free API key to access all commodities.
                      signup_url:
                        type: string
                        example: https://www.oilpriceapi.com/signup
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/latest":
    get:
      summary: Get latest price for a commodity
      operationId: getV1PricesLatest
      tags:
      - Prices
      description: Retrieve the most recent price for a specific commodity
      parameters:
      - name: by_code
        in: query
        required: false
        description: |
          Commodity code or comma-separated commodity codes (defaults to
          `BRENT_CRUDE_USD`). Physical crude coverage includes
          `MURBAN_CRUDE_USD`, `BONNY_LIGHT_USD`, `MARS_USD`,
          `LOUISIANA_LIGHT_USD`, `ESPO_CRUDE_USD`, and
          `JOHAN_SVERDRUP_USD`.

          These series have different publication cadences. Use `as_of`,
          `data_status`, `stale`, and `freshness` in the response rather than
          assuming the API collection time is the market date. Mars and LLS
          are monthly EIA first-purchase statistics and not live traded
          assessments; Johan Sverdrup is a quarterly-finalized tax-reference
          norm price; ESPO is an intermittent public snapshot.
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BONNY_LIGHT_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ESPO_CRUDE_USD
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - JOHAN_SVERDRUP_USD
          - LEAD_USD
          - LOUISIANA_LIGHT_USD
          - MARS_USD
          - MGO_05S_USD
          - METHANOL_USD
          - MURBAN_CRUDE_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: MURBAN_CRUDE_USD
      - name: by_type
        in: query
        required: false
        description: Price type
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: |
            Latest price data. A single `by_code` returns a flat `data` object
            (LatestPriceResponse); multiple comma-separated codes return `data.prices[]`
            (LatestPricesResponse).
          content:
            application/json:
              schema:
                oneOf:
                - "$ref": "#/components/schemas/LatestPriceResponse"
                - "$ref": "#/components/schemas/LatestPricesResponse"
        '400':
          description: 'Invalid commodity code. Body is `{"status":"fail","data":{"error":"invalid_code",...,"invalid_codes":[...]}}`.

            '
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '401':
          description: |
            Unauthorized — missing or invalid API key. Body is
            `{"error":{"code":"UNAUTHORIZED","message":...,"request_id":...}}` (no top-level `status`).
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/RateLimitErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/batch":
    post:
      summary: Batch price lookup
      tags:
      - Prices
      description: |
        Get latest prices for multiple commodities in a single request.
        Accepts up to 50 commodity codes. Counts as 1 request against your monthly quota.
        Supports shorthand aliases (e.g., 'BRENT' → 'BRENT_CRUDE_USD') and case-insensitive codes.
      operationId: batchPrices
      security:
      - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - codes
              properties:
                codes:
                  type: array
                  items:
                    type: string
                  minItems: 1
                  maxItems: 50
                  example:
                  - BRENT_CRUDE_USD
                  - WTI_USD
                  - NATURAL_GAS_USD
                  - GOLD_USD
      responses:
        '200':
          description: Batch price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      prices:
                        type: array
                        items:
                          type: object
                          properties:
                            code:
                              type: string
                              example: BRENT_CRUDE_USD
                            price:
                              type: number
                              example: 78.41
                              description: Actual price in commodity's currency (not
                                cents)
                            formatted:
                              type: string
                              example: "$78.41"
                            currency:
                              type: string
                              example: USD
                            unit:
                              type: string
                              example: barrel
                            updated_at:
                              type: string
                              format: date-time
                            source:
                              type: string
                      meta:
                        type: object
                        properties:
                          requested:
                            type: integer
                            example: 4
                          returned:
                            type: integer
                            example: 4
                          missing:
                            type: array
                            items:
                              type: string
                            nullable: true
                          timestamp:
                            type: string
                            format: date-time
                          request_id:
                            type: string
        '400':
          description: Invalid request (bad JSON, invalid codes, too many codes)
        '401':
          description: Unauthorized — missing or invalid API key
        '429':
          description: Rate limit exceeded
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices":
    get:
      summary: Get historical prices with pagination
      operationId: getV1Prices
      tags:
      - Prices
      description: Retrieve historical price data with filtering and pagination
      parameters:
      - name: by_code
        in: query
        required: false
        description: Commodity code
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - LEAD_USD
          - MGO_05S_USD
          - METHANOL_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Price type
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      - name: page
        in: query
        required: false
        description: Page number for pagination
        schema:
          type: integer
          minimum: 1
          default: 1
          example: 1
      - name: per_page
        in: query
        required: false
        description: Number of items per page
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
          example: 100
      - name: interval
        in: query
        required: false
        description: Aggregation interval. When set, returns one price per interval
          period instead of raw tick data.
        schema:
          type: string
          enum:
          - raw
          - hourly
          - 1h
          - daily
          - 1d
          - weekly
          - 1w
          - monthly
          - 1m
          example: daily
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical price data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PricesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/past_day":
    get:
      summary: Get prices from the past 24 hours
      operationId: getV1PricesPastDay
      tags:
      - Prices
      description: |
        Intraday endpoint: every raw point recorded in the last 24 hours (or, with `at=YYYY-MM-DD`,
        for one exact observation day).

        **Endpoint selection rule**

        | You want | Use |
        |---|---|
        | Intraday detail for a single day | `/v1/prices/past_day` |
        | A multi-day series, one point per day | `/v1/prices/historical` (`start_date`, `end_date`, `per_page`) |
        | The most recent page of raw points in a window | `/v1/prices/past_week`, `/v1/prices/past_month` |

        `past_week` / `past_month` are capped at 100 raw points per page. For any series stored
        more often than it is assessed (all marine/bunker codes are hourly snapshots of a
        once-daily assessment), those 100 points cover only ~4-5 calendar days — use
        `/v1/prices/historical` for a full daily series.
      parameters:
      - name: by_code
        in: query
        required: false
        description: Commodity code or comma-separated commodity codes. Discover current
          codes with GET /v1/commodities.
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - LEAD_USD
          - MGO_05S_USD
          - METHANOL_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Optional price-type filter.
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Past day price data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PricesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/past_week":
    get:
      summary: Get prices from the past 7 days (most recent 100 raw points)
      operationId: getV1PricesPastWeek
      tags:
      - Prices
      description: |
        Returns the most recent page of raw price points inside a 7-day window
        (default `interval=raw`).

        **Page cap.** This endpoint returns at most **100 raw points per page**. `per_page`
        above 100 is reduced to 100; the applied value is returned in `X-Per-Page` and in
        `data.metadata.truncation.pagination`.

        **Read this if you want a daily series.** Series stored as hourly snapshots of a
        once-daily assessment (all marine/bunker codes, e.g. `VLSFO_SGSIN_USD`) spend the
        entire 100-point budget on ~4-5 calendar days, so this endpoint cannot cover a week
        for them. Use `/v1/prices/historical?by_code=…&start_date=…&end_date=…&per_page=500`,
        which returns one point per day for the full window. Use `/v1/prices/past_day` for
        intraday detail.

        **Truncation is signalled.** When the response does not cover the requested window,
        `data.metadata.truncation` is present — `truncated`, `points_returned`,
        `points_available_in_window`, `window_requested` vs `window_covered` (including the
        number of distinct days actually covered), and the `/v1/prices/historical` request
        that returns the complete daily series. The response also carries `X-Truncated: true`.
        When `data.metadata.truncation` is absent, the page covers the full requested window.
      parameters:
      - name: by_code
        in: query
        required: false
        description: Commodity code or comma-separated commodity codes. Discover current
          codes with GET /v1/commodities.
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - LEAD_USD
          - MGO_05S_USD
          - METHANOL_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Optional price-type filter.
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      - name: start_date
        in: query
        required: false
        description: 'Override default start date (YYYY-MM-DD). Also accepts camelCase:
          startDate'
        schema:
          type: string
          format: date
          example: '2025-06-01'
      - name: end_date
        in: query
        required: false
        description: 'Override default end date (YYYY-MM-DD). Also accepts camelCase:
          endDate'
        schema:
          type: string
          format: date
          example: '2025-12-31'
      - name: interval
        in: query
        required: false
        description: Data aggregation interval
        schema:
          type: string
          enum:
          - raw
          - hourly
          - daily
          - weekly
          - monthly
          default: raw
          example: daily
      - name: per_page
        in: query
        required: false
        description: Points per page. Capped at 100 on raw responses (500 when an
          interval is supplied); requests above the cap are reduced and the applied
          value is reported in X-Per-Page and data.metadata.truncation.
        schema:
          type: integer
          maximum: 100
          default: 100
          example: 100
      - name: page
        in: query
        required: false
        description: One-based page number.
        schema:
          type: integer
          default: 1
          example: 1
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Past week price data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PricesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/past_month":
    get:
      summary: Get prices from the past month (most recent 100 raw points)
      operationId: getV1PricesPastMonth
      tags:
      - Prices
      description: |
        Returns the most recent page of raw price points inside a 1-month window
        (default `interval=raw`).

        **Page cap.** This endpoint returns at most **100 raw points per page**. `per_page`
        above 100 is reduced to 100; the applied value is returned in `X-Per-Page` and in
        `data.metadata.truncation.pagination`.

        **Read this if you want a daily series.** Series stored as hourly snapshots of a
        once-daily assessment (all marine/bunker codes, e.g. `VLSFO_SGSIN_USD`) spend the
        entire 100-point budget on ~4-5 calendar days, so this endpoint cannot cover a month
        for them. Use `/v1/prices/historical?by_code=…&start_date=…&end_date=…&per_page=500`,
        which returns one point per day for the full window. Use `/v1/prices/past_day` for
        intraday detail.

        **Truncation is signalled.** When the response does not cover the requested window,
        `data.metadata.truncation` is present — `truncated`, `points_returned`,
        `points_available_in_window`, `window_requested` vs `window_covered` (including the
        number of distinct days actually covered), and the `/v1/prices/historical` request
        that returns the complete daily series. The response also carries `X-Truncated: true`.
        When `data.metadata.truncation` is absent, the page covers the full requested window.
      parameters:
      - name: by_code
        in: query
        required: false
        description: Commodity code or comma-separated commodity codes. Discover current
          codes with GET /v1/commodities.
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - LEAD_USD
          - MGO_05S_USD
          - METHANOL_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Optional price-type filter.
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      - name: start_date
        in: query
        required: false
        description: 'Override default start date (YYYY-MM-DD). Also accepts camelCase:
          startDate'
        schema:
          type: string
          format: date
          example: '2025-06-01'
      - name: end_date
        in: query
        required: false
        description: 'Override default end date (YYYY-MM-DD). Also accepts camelCase:
          endDate'
        schema:
          type: string
          format: date
          example: '2025-12-31'
      - name: interval
        in: query
        required: false
        description: Data aggregation interval
        schema:
          type: string
          enum:
          - raw
          - hourly
          - daily
          - weekly
          - monthly
          default: raw
          example: daily
      - name: per_page
        in: query
        required: false
        description: Points per page. Capped at 100 on raw responses (500 when an
          interval is supplied); requests above the cap are reduced and the applied
          value is reported in X-Per-Page and data.metadata.truncation.
        schema:
          type: integer
          maximum: 100
          default: 100
          example: 100
      - name: page
        in: query
        required: false
        description: One-based page number.
        schema:
          type: integer
          default: 1
          example: 1
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Past month price data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PricesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/past_year":
    get:
      summary: Get prices from the past year
      operationId: getV1PricesPastYear
      description: Retrieve the available price series for the prior year, with optional
        commodity and pagination filters.
      tags:
      - Prices
      parameters:
      - name: by_code
        in: query
        required: false
        description: Commodity code or comma-separated commodity codes. Discover current
          codes with GET /v1/commodities.
        schema:
          type: string
          enum:
          - ALUMINUM_USD
          - AMMONIA_USD
          - ASPHALT_USD
          - AZERI_LIGHT_USD
          - BAKKEN_DUC_WELLS
          - BAKKEN_FRAC_SPREADS
          - BIODIESEL_USD
          - BRENT_CRUDE_USD
          - CANADA_RIG_COUNT
          - CAPP_COAL_USD
          - CME_COAL_USD
          - COAL_USD
          - COKING_COAL_USD
          - COPPER_USD
          - CUSHING_STORAGE
          - DIESEL_USD
          - DUBAI_CRUDE_USD
          - DUTCH_TTF_EUR
          - DUTCH_TTF_NATURAL_GAS_USD
          - EAGLEFORD_DUC_WELLS
          - EAGLEFORD_FRAC_SPREADS
          - ETHANOL_USD
          - ETHYLENE_USD
          - EUR_USD
          - USD_NOK
          - EUR_NOK
          - EU_CARBON_EUR
          - UK_CARBON_GBP
          - GASOLINE_RBOB_USD
          - GASOLINE_USD
          - GBP_USD
          - GOLD_USD
          - SILVER_USD
          - GOLD_AM_USD
          - GOLD_AM_GBP
          - GOLD_AM_EUR
          - GOLD_PM_USD
          - GOLD_PM_GBP
          - GOLD_PM_EUR
          - SILVER_FIX_USD
          - SILVER_FIX_GBP
          - SILVER_FIX_EUR
          - HEATING_OIL_USD
          - HFO_180_USD
          - HFO_380_USD
          - ILLINOIS_COAL_USD
          - INTERNATIONAL_RIG_COUNT
          - IRON_ORE_USD
          - JET_A1_NWE_USD
          - JET_FUEL_USD
          - JKM_LNG_USD
          - LEAD_USD
          - MGO_05S_USD
          - METHANOL_USD
          - NAPHTHA_USD
          - NICKEL_USD
          - NATURAL_GAS_GBP
          - NATURAL_GAS_STORAGE
          - NATURAL_GAS_USD
          - NEWCASTLE_COAL_USD
          - NORTH_DAKOTA_WELL_PERMITS
          - NYMEX_APPALACHIAN_USD
          - NYMEX_WESTERN_RAIL_USD
          - OKLAHOMA_WELL_PERMITS
          - PALLADIUM_USD
          - PERMIAN_DUC_WELLS
          - PERMIAN_FRAC_SPREADS
          - POLYETHYLENE_USD
          - POLYPROPYLENE_USD
          - PLATINUM_USD
          - PRB_COAL_USD
          - TAPIS_CRUDE_USD
          - TIN_USD
          - TEXAS_WELL_PERMITS
          - ULSD_DIESEL_USD
          - URALS_CRUDE_USD
          - URANIUM_USD
          - UREA_USD
          - US_RIG_COUNT
          - VLSFO_USD
          - WCS_CRUDE_USD
          - WTI_USD
          - ZINC_USD
          default: BRENT_CRUDE_USD
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Optional price-type filter.
        schema:
          type: string
          enum:
          - spot_price
          - daily_average_price
          default: spot_price
          example: spot_price
      - name: start_date
        in: query
        required: false
        description: 'Override default start date (YYYY-MM-DD). Also accepts camelCase:
          startDate'
        schema:
          type: string
          format: date
          example: '2025-01-01'
      - name: end_date
        in: query
        required: false
        description: 'Override default end date (YYYY-MM-DD). Also accepts camelCase:
          endDate'
        schema:
          type: string
          format: date
          example: '2025-12-31'
      - name: interval
        in: query
        required: false
        description: Data aggregation interval. Defaults to 'daily' for performance.
        schema:
          type: string
          enum:
          - raw
          - hourly
          - daily
          - weekly
          - monthly
          default: daily
          example: daily
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Past year price data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PricesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/historical":
    get:
      summary: Get paginated historical price data
      operationId: getV1PricesHistorical
      tags:
      - Prices
      - Premium
      description: |
        Retrieve the authenticated account's available history for one or more
        commodity codes. `by_code` is required. The account's historical-depth
        entitlement is enforced even when no dates are supplied.

        The default interval is `daily`, and the default page size for aggregated
        history is 500. Responses are paginated; follow `X-Page`, `X-Per-Page`,
        `X-Total`, and `X-Total-Pages` rather than assuming one response contains
        the entire archive. Use `interval=raw` only when individual collected rows
        are required.

        Use `GET /v1/commodities/{code}` to discover links, source publication
        cadence, and the requesting account's history entitlement.

        Example:
        ```bash
        curl "https://api.oilpriceapi.com/v1/prices/historical?by_code=JET_FUEL_USD&start_date=2025-01-01&interval=daily&per_page=500" \
          -H "Authorization: Token YOUR_API_KEY"
        ```
      externalDocs:
        description: Historical prices guide
        url: https://docs.oilpriceapi.com/api-reference/prices/historical
      parameters:
      - name: by_code
        in: query
        required: true
        description: One commodity code or a comma-separated list. Discover current
          codes with `GET /v1/commodities`.
        schema:
          type: string
          example: JET_FUEL_USD
      - name: by_type
        in: query
        required: false
        description: Optional stored price type. When omitted, all price types are
          eligible.
        schema:
          type: string
          example: spot_price
      - name: by_source
        in: query
        required: false
        description: Optional internal source token filter. Prefer omitting this unless
          reproducing a source-specific workflow.
        schema:
          type: string
          example: energy_institute
      - name: start_date
        in: query
        required: false
        description: Inclusive UTC start date. Aliases `start`, `start_at`, and `startDate`
          are accepted.
        schema:
          type: string
          format: date
          example: '2025-01-01'
      - name: end_date
        in: query
        required: false
        description: Inclusive UTC end date. Aliases `end`, `end_at`, and `endDate`
          are accepted.
        schema:
          type: string
          format: date
          example: '2025-12-31'
      - name: past
        in: query
        required: false
        description: Relative window such as `30d`, `6m`, or `1y`. Ignored when explicit
          dates are supplied.
        schema:
          type: string
          pattern: "^[1-9][0-9]*[hdwmy]$"
          example: 1y
      - name: interval
        in: query
        required: false
        description: Aggregation interval. Common names and their short aliases are
          accepted.
        schema:
          type: string
          enum:
          - raw
          - 1h
          - hourly
          - h
          - 1d
          - daily
          - d
          - day
          - 1w
          - weekly
          - w
          - week
          - 1m
          - monthly
          - m
          - month
          default: daily
          example: daily
      - name: page
        in: query
        required: false
        description: Page number for pagination
        schema:
          type: integer
          minimum: 1
          default: 1
          example: 1
      - name: per_page
        in: query
        required: false
        description: Items per page. Values above 500 are clamped to 500.
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 500
          example: 500
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Paginated historical price data available to the authenticated
            account.
          headers:
            X-Page:
              "$ref": "#/components/headers/XPage"
            X-Per-Page:
              "$ref": "#/components/headers/XPerPage"
            X-Total:
              "$ref": "#/components/headers/XTotal"
            X-Total-Pages:
              "$ref": "#/components/headers/XTotalPages"
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/HistoricalPricesResponse"
              examples:
                jetFuelDaily:
                  summary: One page of daily Jet Fuel history
                  value:
                    status: success
                    data:
                      prices:
                      - price: 3.38
                        formatted: "$3.38"
                        currency: USD
                        code: JET_FUEL_USD
                        created_at: '2026-07-13T00:00:00.000Z'
                        type: daily_average
                        price_type: spot_price
                        unit: gallon
                        source: aggregated
                        as_of: '2026-07-13T00:00:00.000Z'
                        collected_at: '2026-07-15T21:00:00.000Z'
                        stale: false
                        age_days: 0
                        synthetic: false
                      metadata:
                        window: historical
                        interval: daily
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '402':
          description: Payment required - Paid subscription needed for historical
            data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PaymentRequiredResponse"
        '400':
          description: Missing or invalid code, date, interval, or relative window.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '429':
          "$ref": "#/components/responses/RateLimited"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/all":
    get:
      summary: Get all commodity prices in one call
      operationId: getV1PricesAll
      tags:
      - Prices
      - Premium
      description: |
        Retrieve the commodity values available to the account in a single API call.
        Responses include timestamps and metadata for evaluating freshness. Catalog access varies by dataset, plan, and entitlement.
      parameters:
      - name: categories
        in: query
        required: false
        description: Comma-separated list of categories to filter (oil,gas,metals,forex,marine_fuels)
        schema:
          type: string
          example: oil,gas
      - name: codes
        in: query
        required: false
        description: Comma-separated list of specific commodity codes
        schema:
          type: string
          example: WTI_USD,BRENT_CRUDE_USD,GOLD_USD
      - name: currency
        in: query
        required: false
        description: Convert prices to specific currency (Premium only)
        schema:
          type: string
          enum:
          - USD
          - EUR
          - GBP
          default: USD
          example: USD
      - name: include_metadata
        in: query
        required: false
        description: Include additional metadata
        schema:
          type: boolean
          default: false
          example: true
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: All commodity prices
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/AllPricesResponse"
        '401':
          description: Unauthorized - Invalid API key
        '429':
          description: Too many requests
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/all/health":
    get:
      summary: Check data freshness for all commodities
      operationId: getV1PricesAllHealth
      tags:
      - Prices
      - Premium
      description: Monitor which commodities have fresh data and which are stale
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Data freshness status
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DataHealthResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/storage/cushing":
    get:
      summary: Get Cushing oil storage data
      operationId: getV1StorageCushing
      tags:
      - Storage
      - Premium
      description: |
        Latest-available Cushing, Oklahoma oil storage intelligence with market signals.
        Cushing is the delivery point for WTI crude and North America's largest oil storage hub.
        **Premium Feature** - Scale tier required.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Cushing storage data with analytics
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/CushingStorageResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/brent":
    get:
      summary: Get Brent futures curve
      operationId: getV1FuturesBrent
      tags:
      - Futures
      - Premium
      description: |
        Complete Brent futures curve with contract prices and spreads.
        **Premium Feature** - Scale tier required.

        Canonical instrument-generic path (#4170). The legacy venue-named
        alias `/v1/futures/ice-brent` continues to work and returns an
        identical response.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Brent futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/BrentFuturesResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/brent/historical":
    get:
      summary: Get historical Brent futures data
      operationId: getV1FuturesBrentHistorical
      description: |
        Canonical instrument-generic path (#4170). Legacy alias:
        `/v1/futures/ice-brent/historical` (identical response).
      tags:
      - Futures
      - Premium
      parameters:
      - name: contract_month
        in: query
        required: false
        description: Specific contract month (e.g., "M1", "M2")
        schema:
          type: string
          example: 2026-09
      - name: period
        in: query
        required: false
        description: Time period
        schema:
          type: string
          enum:
          - 1d
          - 1w
          - 1m
          - 3m
          - 1y
          default: 1w
          example: 1y
      - name: interval
        in: query
        required: false
        description: Data interval for historical data
        schema:
          type: string
          enum:
          - hourly
          - daily
          - weekly
          - monthly
          default: daily
          example: daily
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/HistoricalFuturesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/brent/spreads":
    get:
      summary: Get Brent calendar spreads
      operationId: getV1FuturesBrentSpreads
      tags:
      - Futures
      - Premium
      description: |
        Calendar spread analysis between contract months.
        Canonical instrument-generic path (#4170). Legacy alias:
        `/v1/futures/ice-brent/spreads` (identical response).
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Futures spreads data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuturesSpreadsResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/wti":
    get:
      summary: Get WTI futures curve
      operationId: getV1FuturesWti
      tags:
      - Futures
      - Premium
      description: |
        Complete WTI (West Texas Intermediate) futures curve with contract prices,
        front month identification, and rollover indicators.

        Canonical instrument-generic path (#4170). The legacy venue-named
        alias `/v1/futures/ice-wti` continues to work and returns an
        identical response.

        **Key Features:**
        - `is_front_month`: Boolean flag identifying CL1 (front month contract)
        - `days_to_expiry`: Days until contract settlement
        - `contract_status`: "front_month", "near_expiry", or "active" on the live curve (expired contracts are filtered out; historical/OHLC endpoints still return "expired" for point-in-time queries)
        - Automatic rollover: When ≤7 days to expiry, next contract becomes front month

        **Premium Feature** - Futures data access required.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: WTI futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WtiFuturesResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/wti/historical":
    get:
      summary: Get historical WTI futures data
      operationId: getV1FuturesWtiHistorical
      description: |
        Canonical instrument-generic path (#4170). Legacy alias:
        `/v1/futures/ice-wti/historical` (identical response).
      tags:
      - Futures
      - Premium
      parameters:
      - name: contract_month
        in: query
        required: false
        description: Specific contract month (e.g., "2026-03")
        schema:
          type: string
          example: 2026-09
      - name: period
        in: query
        required: false
        description: Time period
        schema:
          type: string
          enum:
          - 1d
          - 1w
          - 1m
          - 3m
          - 1y
          default: 1w
          example: 1y
      - name: interval
        in: query
        required: false
        description: Data interval for historical data
        schema:
          type: string
          enum:
          - hourly
          - daily
          - weekly
          - monthly
          default: daily
          example: daily
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical WTI futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/HistoricalFuturesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/wti/spreads":
    get:
      summary: Get WTI calendar spreads
      operationId: getV1FuturesWtiSpreads
      tags:
      - Futures
      - Premium
      description: |
        Calendar spread analysis between WTI contract months.
        Canonical instrument-generic path (#4170). Legacy alias:
        `/v1/futures/ice-wti/spreads` (identical response).
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: WTI futures spreads data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuturesSpreadsResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/ice-brent":
    get:
      summary: "[Alias] Brent futures curve — use /v1/futures/brent"
      operationId: getV1FuturesIceBrent
      tags:
      - Futures
      - Premium
      description: |
        Legacy venue-named alias of `/v1/futures/brent` (#4170). Identical
        response. Retained for backward compatibility; prefer the canonical
        instrument-generic path.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Brent futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/BrentFuturesResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/ice-wti":
    get:
      summary: "[Alias] WTI futures curve — use /v1/futures/wti"
      operationId: getV1FuturesIceWti
      tags:
      - Futures
      - Premium
      description: |
        Legacy venue-named alias of `/v1/futures/wti` (#4170). Identical
        response. Retained for backward compatibility; prefer the canonical
        instrument-generic path.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: WTI futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WtiFuturesResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/natural-gas":
    get:
      summary: Get NYMEX Natural Gas futures curve
      operationId: getV1FuturesNaturalGas
      tags:
      - Futures
      - Premium
      description: |
        Complete NYMEX Henry Hub Natural Gas futures curve with contract prices,
        front month identification, and rollover indicators.

        **Key Features:**
        - `is_front_month`: Boolean flag identifying front month contract
        - `days_to_expiry`: Days until contract settlement
        - `contract_status`: "front_month", "near_expiry", or "active" on the live curve (expired contracts are filtered out; historical/OHLC endpoints still return "expired" for point-in-time queries)

        **Premium Feature** - Futures data access required.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Natural Gas futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/NatGasFuturesResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/natural-gas/historical":
    get:
      summary: Get historical Natural Gas futures data
      operationId: getV1FuturesNaturalGasHistorical
      description: Retrieve historical NYMEX Natural Gas futures data for the selected
        contract and date range.
      tags:
      - Futures
      - Premium
      parameters:
      - name: contract_month
        in: query
        required: false
        description: Specific contract month (e.g., "2026-03")
        schema:
          type: string
          example: 2026-09
      - name: period
        in: query
        required: false
        description: Time period
        schema:
          type: string
          enum:
          - 1d
          - 1w
          - 1m
          - 3m
          - 1y
          default: 1w
          example: 1y
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical Natural Gas futures data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/HistoricalFuturesResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/futures/natural-gas/spreads":
    get:
      summary: Get Natural Gas calendar spreads
      operationId: getV1FuturesNaturalGasSpreads
      tags:
      - Futures
      - Premium
      description: Calendar spread analysis between Natural Gas contract months
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Natural Gas futures spreads data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuturesSpreadsResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/marine-fuels":
    get:
      summary: Get marine fuel prices for all ports
      operationId: getV1PricesMarineFuels
      tags:
      - Marine Fuels
      - Premium
      description: |
        Global marine bunker fuel prices including VLSFO, HFO 380, and MGO.
        Covers major bunkering ports worldwide.
        **Premium Feature** - Professional tier and above.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Marine fuel prices
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MarineFuelsResponse"
        '401':
          description: Unauthorized
        '403':
          description: Premium access required
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/marine-fuels/latest":
    get:
      summary: Get latest marine fuel prices by port
      operationId: getV1PricesMarineFuelsLatest
      description: Retrieve the latest available marine fuel prices for one or more
        supported ports.
      tags:
      - Marine Fuels
      - Premium
      parameters:
      - name: port_code
        in: query
        required: false
        description: Port code (e.g., SINGAPORE, ROTTERDAM)
        schema:
          type: string
          enum:
          - SINGAPORE
          - ROTTERDAM
          - HOUSTON
          - FUJAIRAH
          - HONG_KONG
          - LOS_ANGELES
          - NEW_YORK
          - SANTOS
          - DUBAI
          - GIBRALTAR
          - ALGECIRAS
          - PIRAEUS
          - ISTANBUL
          - BUSAN
          - SHANGHAI
          example: SINGAPORE
      - name: fuel_type
        in: query
        required: false
        description: Fuel type
        schema:
          type: string
          enum:
          - VLSFO
          - HFO_380
          - HFO_180
          - MGO
          example: VLSFO
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest marine fuel prices
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MarineFuelLatestResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/prices/marine-fuels/historical":
    get:
      summary: Get historical marine fuel prices
      operationId: getV1PricesMarineFuelsHistorical
      description: Retrieve marine fuel price history for supported ports, fuel grades,
        and date ranges.
      tags:
      - Marine Fuels
      - Premium
      parameters:
      - name: port_code
        in: query
        required: true
        description: Port code
        schema:
          type: string
          example: SGSIN
      - name: fuel_type
        in: query
        required: true
        description: Fuel type
        schema:
          type: string
          example: VLSFO
      - name: period
        in: query
        required: false
        description: Time period
        schema:
          type: string
          enum:
          - 1d
          - 1w
          - 1m
          - 3m
          - 1y
          default: 1w
          example: 1y
      - name: interval
        in: query
        required: false
        description: Data interval for historical data
        schema:
          type: string
          enum:
          - hourly
          - daily
          - weekly
          - monthly
          default: daily
          example: daily
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical marine fuel data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MarineFuelHistoricalResponse"
        '401':
          description: Unauthorized
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge":
    get:
      summary: List current LTL carrier fuel surcharges
      operationId: getV1FuelSurcharge
      tags:
      - Fuel Surcharge
      description: |
        Returns the latest stored published fuel-surcharge percentage for every
        covered LTL carrier that currently has data. Each row preserves the
        carrier's effective date, retrieval timestamp, and published source URL.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Current LTL carrier fuel surcharges
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuelSurchargeListResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge/{carrier}/latest":
    get:
      summary: Get the current LTL fuel surcharge for one carrier
      operationId: getV1FuelSurchargeCarrierLatest
      tags:
      - Fuel Surcharge
      description: |
        Returns the latest stored published fuel-surcharge percentage for one
        LTL carrier. An unknown carrier or a carrier with no ingested data
        returns 404; the API never fabricates a current value.
      parameters:
      - "$ref": "#/components/parameters/FuelSurchargeCarrier"
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Current LTL carrier fuel surcharge
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuelSurchargeRateResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Carrier is unknown or has no retrieved data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge/{carrier}/history":
    get:
      summary: Get LTL fuel-surcharge history for one carrier
      operationId: getV1FuelSurchargeCarrierHistory
      tags:
      - Fuel Surcharge
      description: |
        Returns stored weekly published fuel-surcharge rows newest first. Each
        row retains its original effective date and retrieval timestamp.
      parameters:
      - "$ref": "#/components/parameters/FuelSurchargeCarrier"
      - "$ref": "#/components/parameters/Page"
      - "$ref": "#/components/parameters/FuelSurchargePerPage"
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Paginated LTL carrier fuel-surcharge history
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuelSurchargeHistoryResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Carrier is unknown or has no retrieved data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge/parcel":
    get:
      summary: List current parcel carrier fuel surcharges
      operationId: getV1FuelSurchargeParcel
      tags:
      - Fuel Surcharge
      description: |
        Returns current published parcel fuel surcharges grouped by carrier and
        service level, with effective dates and retrieval timestamps.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Current parcel fuel surcharges by carrier and service level
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ParcelFuelSurchargeListResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge/parcel/{carrier}/latest":
    get:
      summary: Get current parcel fuel surcharges for one carrier
      operationId: getV1FuelSurchargeParcelCarrierLatest
      tags:
      - Fuel Surcharge
      description: |
        Returns all current service-level surcharges for a parcel carrier, or a
        single rate when `service_level` is provided.
      parameters:
      - "$ref": "#/components/parameters/ParcelFuelSurchargeCarrier"
      - "$ref": "#/components/parameters/FuelSurchargeServiceLevel"
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Current parcel carrier surcharge data
          content:
            application/json:
              schema:
                oneOf:
                - "$ref": "#/components/schemas/FuelSurchargeRateResponse"
                - "$ref": "#/components/schemas/ParcelFuelSurchargeCarrierResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Carrier, service level, or retrieved data is unavailable
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/fuel-surcharge/parcel/{carrier}/history":
    get:
      summary: Get parcel fuel-surcharge history for one service level
      operationId: getV1FuelSurchargeParcelCarrierHistory
      tags:
      - Fuel Surcharge
      description: |
        Returns stored published parcel fuel-surcharge rows newest first for one
        carrier and required service level.
      parameters:
      - "$ref": "#/components/parameters/ParcelFuelSurchargeCarrier"
      - name: service_level
        in: query
        required: true
        description: Carrier service-level identifier returned by the parcel list
          endpoint
        schema:
          type: string
          example: ground
      - "$ref": "#/components/parameters/Page"
      - "$ref": "#/components/parameters/FuelSurchargePerPage"
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Paginated parcel fuel-surcharge history
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FuelSurchargeHistoryResponse"
        '400':
          description: service_level is missing
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Carrier, service level, or retrieved data is unavailable
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/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/marine-ports":
    get:
      summary: Get all marine fuel ports
      operationId: getV1MarinePorts
      tags:
      - Marine Fuels
      description: |
        Retrieve all available marine fuel ports with their details and capabilities.
        Returns port information including coordinates, fuel services, and trading hours.
      parameters:
      - name: region
        in: query
        required: false
        description: Filter ports by geographic region
        schema:
          type: string
          enum:
          - Asia
          - Europe
          - Americas
          - Middle East
          example: Asia
      - name: country
        in: query
        required: false
        description: Filter ports by country name
        schema:
          type: string
          example: Singapore
      - name: major_ports
        in: query
        required: false
        description: Return only major bunkering hubs
        schema:
          type: boolean
          default: false
          example: true
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: List of marine fuel ports
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MarinePortsResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/RateLimitErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/marine-ports/{port_code}":
    get:
      summary: Get specific marine fuel port with prices
      operationId: getV1MarinePortsByPortCode
      tags:
      - Marine Fuels
      description: |
        Retrieve detailed information about a specific marine fuel port including
        current bunker prices for all available fuel grades.
      parameters:
      - name: port_code
        in: path
        required: true
        description: Port identifier code
        schema:
          type: string
          enum:
          - SGSIN
          - NLRTM
          - USHOU
          - AEFUJ
          - HKHKG
          - USLAX
          - USNYC
          - BRSSZ
          example: SGSIN
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Port details with current prices
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/MarinePortDetailResponse"
        '404':
          description: Port not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/rig-counts/latest":
    get:
      summary: Get latest rig count data (simplified)
      operationId: getV1RigCountsLatest
      tags:
      - Drilling Intelligence
      description: |
        Retrieve the latest rig count data in a simplified format.
        This endpoint returns the most recent US rig count with week-over-week and year-over-year changes.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest rig count data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/RigCountLatestResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/rig-counts":
    get:
      summary: Get historical rig count data
      operationId: getV1RigCounts
      tags:
      - Drilling Intelligence
      description: |
        Retrieve historical rig count data with filtering options.
        **Requires the Scale plan.**
      parameters:
      - name: region
        in: query
        required: false
        description: Filter by region
        schema:
          type: string
          enum:
          - us
          - canada
          - international
          default: us
          example: us
      - name: start_date
        in: query
        required: false
        description: Start date (YYYY-MM-DD)
        schema:
          type: string
          format: date
          example: '2025-01-01'
      - name: end_date
        in: query
        required: false
        description: End date (YYYY-MM-DD)
        schema:
          type: string
          format: date
          example: '2025-08-10'
      - name: page
        in: query
        required: false
        description: Page number for pagination
        schema:
          type: integer
          minimum: 1
          default: 1
          example: 1
      - name: per_page
        in: query
        required: false
        description: Results per page (max 100)
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 100
          example: 100
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Historical rig count data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/RigCountHistoricalResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence":
    get:
      summary: Get the drilling intelligence summary
      operationId: getV1DrillingIntelligence
      tags:
      - Drilling Intelligence
      description: |
        Compatibility alias for the cache-backed drilling intelligence summary.
        Prefer `/v1/drilling-intelligence/summary` for new integrations.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Drilling intelligence summary
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingIntelligenceSummaryResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/latest":
    get:
      summary: Get the latest drilling intelligence summary
      operationId: getV1DrillingIntelligenceLatest
      tags:
      - Drilling Intelligence
      description: |
        Compatibility alias for `/v1/drilling-intelligence/summary`.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest drilling intelligence summary
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingIntelligenceSummaryResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/summary":
    get:
      summary: Get drilling intelligence summary
      operationId: getV1DrillingIntelligenceSummary
      tags:
      - Drilling Intelligence
      description: |
        Get latest data points for each category in a consolidated summary view.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Drilling intelligence summary
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingIntelligenceSummaryResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling/latest":
    get:
      summary: Get latest drilling intelligence summary (compatibility alias)
      operationId: getV1DrillingLatest
      tags:
      - Drilling Intelligence
      description: |
        Backward-compatible SDK alias for the cached drilling intelligence summary payload.
        Prefer `/v1/drilling-intelligence/summary` for new integrations.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest drilling intelligence summary
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingIntelligenceSummaryResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/frac-spreads":
    get:
      summary: Get frac spreads data
      operationId: getV1DrillingIntelligenceFracSpreads
      tags:
      - Drilling Intelligence
      description: |
        Get the latest national frac-spread count and any available legacy
        basin series.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Frac spreads data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FracSpreadsResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/well-permits":
    get:
      summary: Get well permits data
      operationId: getV1DrillingIntelligenceWellPermits
      tags:
      - Drilling Intelligence
      description: |
        Get recent drilling permits with bounded pagination and an optional
        state filter.
        **Requires the Scale plan.**
      parameters:
      - name: state_code
        in: query
        required: false
        description: Two-letter US state code
        schema:
          type: string
          minLength: 2
          maxLength: 2
          example: TX
      - name: days
        in: query
        required: false
        description: Lookback window in days (clamped to 1-365)
        schema:
          type: integer
          minimum: 1
          maximum: 365
          default: 30
          example: 30
      - name: page
        in: query
        required: false
        description: Page number for pagination
        schema:
          type: integer
          minimum: 1
          default: 1
          example: 1
      - name: per_page
        in: query
        required: false
        description: Results per page (max 200)
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
          example: 50
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Well permits data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WellPermitsResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/duc-wells":
    get:
      summary: Get DUC wells data
      operationId: getV1DrillingIntelligenceDucWells
      tags:
      - Drilling Intelligence
      description: |
        Get the latest EIA drilled-but-uncompleted well inventory by basin.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: DUC wells data
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingBasinSeriesResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/completions":
    get:
      summary: Get wells completed by basin
      operationId: getV1DrillingIntelligenceCompletions
      tags:
      - Drilling Intelligence
      description: |
        Get the latest EIA wells-completed series by basin.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest wells completed by basin
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingBasinSeriesResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/drilling-intelligence/wells-drilled":
    get:
      summary: Get wells drilled by basin
      operationId: getV1DrillingIntelligenceWellsDrilled
      tags:
      - Drilling Intelligence
      description: |
        Get the latest EIA wells-drilled series by basin.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Latest wells drilled by basin
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/DrillingBasinSeriesResponse"
        '401':
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/webhooks":
    get:
      summary: List webhook endpoints
      operationId: getV1Webhooks
      tags:
      - Webhooks
      description: |
        Get all configured webhook endpoints for the authenticated user.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: List of webhook endpoints
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WebhookListResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    post:
      summary: Create webhook endpoint
      operationId: postV1Webhooks
      tags:
      - Webhooks
      description: |
        Create a new webhook endpoint to receive event-driven updates.
        **Requires the Scale plan.**
      security:
      - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateWebhookRequest"
      responses:
        '201':
          description: Webhook endpoint created successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WebhookResponse"
        '400':
          description: Bad request - Invalid webhook configuration
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/webhooks/{webhook_id}":
    get:
      summary: Get webhook endpoint details
      operationId: getV1WebhooksByWebhookId
      tags:
      - Webhooks
      description: |
        Get details of a specific webhook endpoint.
        **Requires the Scale plan.**
      parameters:
      - name: webhook_id
        in: path
        required: true
        description: Webhook endpoint ID
        schema:
          type: string
          example: wh_1a2b3c4d5e6f
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Webhook endpoint details
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WebhookResponse"
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    put:
      summary: Update webhook endpoint
      operationId: putV1WebhooksByWebhookId
      tags:
      - Webhooks
      description: |
        Update an existing webhook endpoint configuration.
        **Requires the Scale plan.**
      parameters:
      - name: webhook_id
        in: path
        required: true
        description: Webhook endpoint ID
        schema:
          type: string
          example: wh_1a2b3c4d5e6f
      security:
      - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdateWebhookRequest"
      responses:
        '200':
          description: Webhook endpoint updated successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/WebhookResponse"
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    delete:
      summary: Delete webhook endpoint
      operationId: deleteV1WebhooksByWebhookId
      tags:
      - Webhooks
      description: |
        Delete a webhook endpoint.
        **Requires the Scale plan.**
      parameters:
      - name: webhook_id
        in: path
        required: true
        description: Webhook endpoint ID
        schema:
          type: string
          example: wh_1a2b3c4d5e6f
      security:
      - ApiKeyAuth: []
      responses:
        '204':
          description: Webhook endpoint deleted successfully
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/InsufficientPlanError"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/diesel-prices":
    get:
      summary: Get regional diesel prices
      operationId: getV1DieselPrices
      tags:
      - Diesel Prices
      description: |
        Retrieve diesel prices for US regions including national average, PAD districts, and major states.
        Data sourced from EIA (Energy Information Administration) with weekly updates.

        **FREE TIER** - No additional cost
      parameters:
      - name: state
        in: query
        required: false
        description: Two-letter US state code (e.g., CA, TX, NY)
        schema:
          type: string
          example: CA
      - name: zip
        in: query
        required: false
        description: US ZIP code
        schema:
          type: string
          example: '94102'
      - name: lat
        in: query
        required: false
        description: Latitude coordinate
        schema:
          type: number
          format: float
          example: 37.7749
      - name: lng
        in: query
        required: false
        description: Longitude coordinate
        schema:
          type: number
          format: float
          example: -122.4194
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Regional diesel price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      regional_average:
                        type: object
                        properties:
                          price:
                            type: number
                            format: float
                            example: 4.862
                            description: Diesel price per gallon
                          currency:
                            type: string
                            example: USD
                          unit:
                            type: string
                            example: gallon
                          region:
                            type: string
                            example: california
                            description: EIA region name
                          granularity:
                            type: string
                            enum:
                            - national
                            - pad_district
                            - state
                            example: state
                          source:
                            type: string
                            example: EIA
                          updated_at:
                            type: string
                            format: date-time
                          cached:
                            type: boolean
                            example: true
                      location:
                        type: object
                        properties:
                          type:
                            type: string
                            enum:
                            - state
                            - zip_code
                            - coordinates
                            - national
                          state_code:
                            type: string
                            example: CA
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/gasoline-prices":
    get:
      summary: Get regional regular gasoline prices
      operationId: getV1GasolinePrices
      tags:
      - Gasoline Prices
      description: |
        Retrieve regular gasoline prices for US national average, PAD districts, and selected
        state-level EIA series. ZIP and coordinate inputs are accepted for client consistency
        and currently fall back to national/regional EIA coverage.

        **FREE TIER** - No additional cost
      parameters:
      - name: state
        in: query
        required: false
        description: Two-letter US state code (e.g., CA, TX, NY)
        schema:
          type: string
          example: CA
      - name: zip
        in: query
        required: false
        description: US ZIP code
        schema:
          type: string
          example: '94102'
      - name: lat
        in: query
        required: false
        description: Latitude coordinate
        schema:
          type: number
          format: float
          example: 37.7749
      - name: lng
        in: query
        required: false
        description: Longitude coordinate
        schema:
          type: number
          format: float
          example: -122.4194
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Regional gasoline price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      regional_average:
                        type: object
                        properties:
                          price:
                            type: number
                            format: float
                            nullable: true
                            example: 3.452
                            description: Regular gasoline price per gallon
                          currency:
                            type: string
                            example: USD
                          unit:
                            type: string
                            example: gallon
                          region:
                            type: string
                            example: california
                            description: EIA region name
                          granularity:
                            type: string
                            enum:
                            - national
                            - pad_district
                            - state
                            example: state
                          source:
                            type: string
                            example: EIA
                          updated_at:
                            type: string
                            format: date-time
                          cached:
                            type: boolean
                            example: true
                          error:
                            type: string
                            nullable: true
                      location:
                        type: object
                        properties:
                          type:
                            type: string
                            enum:
                            - state
                            - zip_code
                            - coordinates
                            - national
                          state_code:
                            type: string
                            example: CA
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/electricity":
    get:
      summary: Get retail electricity prices by state and sector
      operationId: getV1Electricity
      tags:
      - Electricity Prices
      description: |
        Retrieve US retail electricity prices in cents per kilowatt-hour by state and customer sector.
        Data sourced from EIA (Energy Information Administration, Forms EIA-826/861/861M) with monthly updates.
        Covers all 50 states plus DC and the US national average.

        **FREE TIER** - No additional cost
      parameters:
      - name: state
        in: query
        required: true
        description: Two-letter US state code (e.g., CA, TX, NY), DC, or US for the
          national average
        schema:
          type: string
          example: CA
      - name: sector
        in: query
        required: false
        description: Customer sector (default residential)
        schema:
          type: string
          enum:
          - residential
          - commercial
          - industrial
          - all
          example: residential
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Retail electricity price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      price:
                        type: number
                        format: float
                        nullable: true
                        example: 35.25
                        description: Retail electricity price in cents per kilowatt-hour
                      currency:
                        type: string
                        example: USD
                      unit:
                        type: string
                        example: cents_per_kwh
                      period:
                        type: string
                        nullable: true
                        example: 2026-04
                        description: EIA data month (YYYY-MM)
                      state:
                        type: string
                        example: CA
                      sector:
                        type: string
                        enum:
                        - residential
                        - commercial
                        - industrial
                        - all
                        example: residential
                      source:
                        type: string
                        example: EIA
                      updated_at:
                        type: string
                        format: date-time
                        nullable: true
                      cached:
                        type: boolean
                        example: true
                      error:
                        type: string
                        nullable: true
        '400':
          description: Missing or invalid state/sector parameter
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  message:
                    type: string
                    example: 'Missing required parameter: state (two-letter US state
                      code, DC, or US)'
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/account":
    get:
      summary: Get account details
      operationId: getV1Account
      tags:
      - Account
      description: |
        Self-service account summary plus API key inventory for the authenticated user.
        Returns tier, monthly request limit and usage, trial status, and every API key (token hints only).
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Account and API key inventory
          content:
            application/json:
              schema:
                type: object
                properties:
                  account:
                    type: object
                    properties:
                      email:
                        type: string
                        example: you@example.com
                      tier:
                        type: string
                        example: developer
                      request_limit:
                        type: integer
                        example: 10000
                      usage_this_month:
                        type: integer
                        example: 67
                      trial_active:
                        type: boolean
                        example: false
                      trial_ends_at:
                        type: string
                        format: date-time
                        nullable: true
                  api_keys:
                    type: array
                    items:
                      "$ref": "#/components/schemas/ApiKey"
                  docs:
                    type: string
                    example: https://docs.oilpriceapi.com
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/market-brief":
    get:
      summary: Multi-commodity market brief
      operationId: getV1MarketBrief
      tags:
      - Market Brief
      description: |
        Compact multi-commodity snapshot for agents and MCP clients: latest price, 24h change,
        and a 1-month forecast per commodity, plus optional spreads and macro context.
        The `codes` parameter is REQUIRED (comma-separated commodity codes).
      security:
      - ApiKeyAuth: []
      parameters:
      - name: codes
        in: query
        required: true
        description: Comma-separated commodity codes (e.g. `WTI_USD,BRENT_CRUDE_USD`).
        schema:
          type: string
        example: WTI_USD,BRENT_CRUDE_USD
      - name: narrative
        in: query
        required: false
        description: When `true`, adds a `data.context` block (disruptions, macro
          indicators).
        schema:
          type: boolean
          default: false
          example: true
      responses:
        '200':
          description: Market brief
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      as_of:
                        type: string
                        format: date-time
                      codes:
                        type: array
                        items:
                          type: string
                      commodities:
                        type: array
                        items:
                          type: object
                          properties:
                            code:
                              type: string
                              example: WTI_USD
                            name:
                              type: string
                              example: WTI Crude Oil
                            price:
                              type: number
                              format: float
                              example: 68.65
                            currency:
                              type: string
                              example: USD
                            unit:
                              type: string
                              example: barrel
                            change_24h_pct:
                              type: number
                              format: float
                              nullable: true
                              example: 1.51
                            change_24h_abs:
                              type: number
                              format: float
                              nullable: true
                              example: 1.02
                            as_of:
                              type: string
                              format: date-time
                            source:
                              type: string
                              example: market_reporting
                            stale:
                              type: boolean
                              example: false
                            forecast_1m:
                              type: object
                              nullable: true
                              properties:
                                point:
                                  type: number
                                  format: float
                                  example: 77.4
                                low:
                                  type: number
                                  format: float
                                  example: 74.56
                                high:
                                  type: number
                                  format: float
                                  example: 80.24
                                confidence:
                                  type: number
                                  format: float
                                  example: 0.7
                      spreads:
                        type: array
                        items:
                          type: object
                      context:
                        type: object
                        nullable: true
                        description: Present only when `narrative=true`.
        '400':
          description: Missing/invalid `codes` parameter (`{"status":"fail","data":{"error":"VALIDATION_ERROR",...}}`).
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/market_brief":
    get:
      summary: Multi-commodity market brief (underscore alias)
      operationId: getV1MarketBriefLegacyAlias
      tags:
      - Market Brief
      description: |
        Backward-compatible underscore alias for `/v1/market-brief`.
        Returns the same compact multi-commodity snapshot for agents and MCP clients.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: codes
        in: query
        required: true
        description: Comma-separated commodity codes (e.g. `WTI_USD,BRENT_CRUDE_USD`).
        schema:
          type: string
        example: WTI_USD,BRENT_CRUDE_USD
      - name: narrative
        in: query
        required: false
        description: When `true`, adds a `data.context` block (disruptions, macro
          indicators).
        schema:
          type: boolean
          default: false
          example: true
      responses:
        '200':
          description: Market brief
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
        '400':
          description: Missing/invalid `codes` parameter.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/subscriptions":
    get:
      summary: List price watches
      operationId: getV1Subscriptions
      tags:
      - Subscriptions
      description: Persistent price "watches" for the authenticated user. Poll `/v1/subscriptions/events`
        for triggered events.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: List of subscriptions
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      subscriptions:
                        type: array
                        items:
                          "$ref": "#/components/schemas/PriceWatch"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    post:
      summary: Create a price watch
      operationId: postV1Subscriptions
      tags:
      - Subscriptions
      description: Create a persistent price watch that emits events when its condition
        is met.
      security:
      - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - interval_seconds
              properties:
                name:
                  type: string
                  example: My WTI watch
                codes:
                  type: array
                  description: Commodity codes to evaluate. Codes and minimum interval
                    depend on the account tier.
                  minItems: 1
                  items:
                    type: string
                  example:
                  - WTI_USD
                  - BRENT_CRUDE_USD
                code:
                  type: string
                  deprecated: true
                  description: Legacy single-code shorthand; folded into `codes`.
                  example: WTI_USD
                interval_seconds:
                  type: integer
                  minimum: 1
                  description: Evaluation interval in seconds, subject to the account
                    tier's minimum.
                  example: 3600
                deliver_webhook:
                  type: boolean
                  default: false
                  example: true
                source:
                  type: string
                  enum:
                  - api
                  - mcp
                  - dashboard
                  example: mcp
                tool_name:
                  type: string
                  example: watch_commodity
      responses:
        '200':
          description: Price watch created
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PriceWatchResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '402':
          description: Account watch count, code count, or interval entitlement requires
            an upgrade.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PaymentRequiredResponse"
        '422':
          description: Price watch validation failed.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/subscriptions/events":
    get:
      summary: Poll price watch events
      operationId: getV1SubscriptionsEvents
      tags:
      - Subscriptions
      description: |
        Poll-based feed of events triggered by your price watches. Pass the response `cursor`
        back as `since` to fetch only newer events. Polling this operation does not consume the
        account's monthly request quota and has its own rate-limit lane.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: since
        in: query
        required: false
        description: Return events whose sequence is greater than this cursor. Defaults
          to 0.
        schema:
          type: integer
          minimum: 0
          default: 0
          example: 1001
      - name: limit
        in: query
        required: false
        description: Maximum events to return. Values are clamped to 1 through 500.
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 100
          example: 100
      - name: watch_id
        in: query
        required: false
        description: Restrict events to one price watch owned by the authenticated
          account.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Events feed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      cursor:
                        type: integer
                        example: 0
                      has_more:
                        type: boolean
                        example: false
                      events:
                        type: array
                        items:
                          type: object
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/subscriptions/{id}":
    get:
      summary: Get a price watch
      operationId: getV1SubscriptionsById
      description: Retrieve one price watch owned by the authenticated account.
      tags:
      - Subscriptions
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Resource identifier.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Subscription details
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PriceWatchResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Subscription not found (`{"error":{"code":"NOT_FOUND",...}}`).
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    patch:
      summary: Update a price watch
      operationId: patchV1SubscriptionsById
      description: Update the configurable fields of one price watch owned by the
        authenticated account.
      tags:
      - Subscriptions
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Resource identifier.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: My energy watch
                codes:
                  type: array
                  minItems: 1
                  items:
                    type: string
                  example:
                  - WTI_USD
                code:
                  type: string
                  deprecated: true
                  description: Legacy single-code shorthand; folded into `codes`.
                  example: WTI_USD
                interval_seconds:
                  type: integer
                  minimum: 1
                  description: Evaluation interval in seconds, subject to the account
                    tier's minimum.
                  example: 900
                deliver_webhook:
                  type: boolean
                  example: true
                status:
                  type: string
                  enum:
                  - active
                  - paused
                  example: active
      responses:
        '200':
          description: Subscription updated
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PriceWatchResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '422':
          description: Price watch validation failed.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/FailErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
    delete:
      summary: Delete a price watch
      operationId: deleteV1SubscriptionsById
      description: Delete one price watch owned by the authenticated account.
      tags:
      - Subscriptions
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Resource identifier.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '204':
          description: Subscription deleted; no response body is returned.
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/subscriptions/{id}/pause":
    post:
      summary: Pause a price watch
      operationId: postV1SubscriptionsByIdPause
      description: Pause evaluation of one price watch owned by the authenticated
        account.
      tags:
      - Subscriptions
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Price watch identifier.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Price watch paused
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PriceWatchResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/subscriptions/{id}/resume":
    post:
      summary: Resume a price watch
      operationId: postV1SubscriptionsByIdResume
      description: Resume evaluation and immediately re-arm one price watch owned
        by the authenticated account.
      tags:
      - Subscriptions
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        required: true
        description: Price watch identifier.
        schema:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
      responses:
        '200':
          description: Price watch resumed and re-armed
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PriceWatchResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Subscription not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production":
    get:
      summary: Well production summary
      operationId: getV1WellProduction
      tags:
      - Well Production
      description: |
        National and top-state oil/gas production summary. Sourced from state regulators
        (TX RRC, NM OCD, ND NDIC, AOGCC) and EIA.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Production summary
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      national:
                        type: object
                        nullable: true
                      top_states:
                        type: array
                        items:
                          "$ref": "#/components/schemas/StateProduction"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/summary":
    get:
      summary: Well production summary
      operationId: getV1WellProductionSummary
      tags:
      - Well Production
      description: |
        Alias for `/v1/well-production`. Returns the national and top-state oil/gas
        production summary from state regulators and EIA.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Production summary
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      national:
                        type: object
                        nullable: true
                      top_states:
                        type: array
                        items:
                          "$ref": "#/components/schemas/StateProduction"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/states":
    get:
      summary: List states with production data
      operationId: getV1WellProductionStates
      description: List states with available well-production coverage and their latest
        available period.
      tags:
      - Well Production
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: States with available production data
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/states/{state_code}":
    get:
      summary: Monthly production time series for a state
      operationId: getV1WellProductionStatesByStateCode
      description: Retrieve the monthly well-production time series for one covered
        state.
      tags:
      - Well Production
      security:
      - ApiKeyAuth: []
      parameters:
      - name: state_code
        in: path
        required: true
        description: Two-letter state code (e.g. TX, NM, ND, AK).
        schema:
          type: string
          example: TX
        example: TX
      responses:
        '200':
          description: Monthly production series
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      state:
                        type: string
                        example: TX
                      period:
                        type: object
                        properties:
                          start:
                            type: string
                            format: date
                          end:
                            type: string
                            format: date
                      count:
                        type: integer
                      data:
                        type: array
                        items:
                          type: object
                          properties:
                            period:
                              type: string
                              example: 2025-06
                            oil_bbl:
                              type: number
                              nullable: true
                            gas_mcf:
                              type: number
                              nullable: true
                            water_bbl:
                              type: number
                              nullable: true
                            boe:
                              type: number
                              nullable: true
                            days_producing:
                              type: integer
                              nullable: true
                            source:
                              type: string
                              example: eia_api
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/wells/{api_number}":
    get:
      summary: Production for a single well
      operationId: getV1WellProductionWellsByApiNumber
      tags:
      - Well Production
      description: Production history for a single well by its 14-digit API well number.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: api_number
        in: path
        required: true
        description: 14-digit API well number.
        schema:
          type: string
        example: '42329447130000'
      responses:
        '200':
          description: Well production history
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
        '400':
          description: API number is not 14 digits (`{"error":{"code":"INVALID_PARAMETER",...}}`).
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Well not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/top-producers":
    get:
      summary: Top producing wells
      operationId: getV1WellProductionTopProducers
      tags:
      - Well Production
      description: Highest-producing wells over the trailing period, optionally scoped
        to a state.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: state
        in: query
        required: false
        description: Two-letter state code to scope results.
        schema:
          type: string
        example: TX
      responses:
        '200':
          description: Top producers
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      state:
                        type: string
                        example: TX
                      period:
                        type: object
                        properties:
                          start:
                            type: string
                            format: date
                          end:
                            type: string
                            format: date
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/cycle-time":
    get:
      summary: Well cycle-time statistics
      operationId: getV1WellProductionCycleTime
      tags:
      - Well Production
      description: |
        Aggregate spud-to-completion and completion-to-production cycle-time statistics
        (median, percentiles) across wells, with optional filters.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Cycle-time statistics
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      filters:
                        type: object
                      well_count:
                        type: integer
                        example: 10000
                      wells_with_cycle_data:
                        type: integer
                        example: 45
                      cycle_time_stats:
                        "$ref": "#/components/schemas/CycleTimeStats"
                      stage_breakdown:
                        type: object
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-production/cycle-time/cohorts":
    get:
      summary: Cycle-time by cohort
      operationId: getV1WellProductionCycleTimeCohorts
      tags:
      - Well Production
      description: Cycle-time statistics grouped into cohorts (e.g. by spud quarter).
      security:
      - ApiKeyAuth: []
      parameters:
      - name: group_by
        in: query
        required: false
        description: Cohort grouping (e.g. `quarter`).
        schema:
          type: string
          default: quarter
          example: operator
      responses:
        '200':
          description: Cohort cycle-time statistics
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      group_by:
                        type: string
                        example: quarter
                      cohorts:
                        type: object
                        additionalProperties:
                          type: object
                          properties:
                            well_count:
                              type: integer
                            wells_with_data:
                              type: integer
                            stats:
                              "$ref": "#/components/schemas/CycleTimeStats"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-lifecycle/states":
    get:
      summary: Well lifecycle state availability
      operationId: getV1WellLifecycleStates
      tags:
      - Well Lifecycle
      description: |
        Returns customer-safe lifecycle availability statuses by state. This endpoint
        classifies states as available, partial, repair_required, or unavailable so
        clients do not mistake missing lifecycle coverage for valid zero data.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: states
        in: query
        required: false
        description: Comma-separated two-letter state codes. Defaults to promoted
          lifecycle states; pass states explicitly to inspect unavailable or repair-gated
          states.
        schema:
          type: string
        example: TX,NM,WY
      - name: api_limit
        in: query
        required: false
        description: Maximum permit APIs analyzed per state for bounded online validation.
          Defaults to 1 for the no-param overview and 1000 for explicit state requests.
        schema:
          type: integer
          default: 1000
          example: 100
      - name: include_samples
        in: query
        required: false
        description: Include diagnostic sample rows in list responses.
        schema:
          type: boolean
          default: false
          example: false
      responses:
        '200':
          description: Lifecycle state availability list
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      generated_at:
                        type: string
                        format: date-time
                      count:
                        type: integer
                      states:
                        type: array
                        items:
                          "$ref": "#/components/schemas/WellLifecycleStateAvailability"
                      meta:
                        type: object
        '400':
          description: Invalid state code
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Enterprise plan required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-lifecycle/states/{state_code}":
    get:
      summary: Well lifecycle availability for one state
      operationId: getV1WellLifecycleStatesByStateCode
      tags:
      - Well Lifecycle
      description: Detailed lifecycle availability report for a state, including reason
        codes and diagnostic samples.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: state_code
        in: path
        required: true
        description: Two-letter state code.
        schema:
          type: string
          example: TX
        example: TX
      - name: api_limit
        in: query
        required: false
        description: Maximum permit APIs analyzed for bounded online validation.
        schema:
          type: integer
          default: 1000
          example: 100
      - name: full
        in: query
        required: false
        description: Run an unbounded full-state validation report. Use carefully
          for large states.
        schema:
          type: boolean
          default: false
          example: true
      responses:
        '200':
          description: Lifecycle state availability report
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    "$ref": "#/components/schemas/WellLifecycleStateAvailability"
        '400':
          description: Invalid state code
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Enterprise plan required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-lifecycle/wells/{api_number}":
    get:
      summary: Well lifecycle summary for one well
      operationId: getV1WellLifecycleWellsByApiNumber
      tags:
      - Well Lifecycle
      description: |
        Returns the persisted permit-to-production lifecycle summary for a single
        promoted-state well. Runtime requests read materialized lifecycle summaries
        and do not perform large raw permit/production joins.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: api_number
        in: path
        required: true
        description: 10-, 12-, or 14-digit API number. Common dashed formats are accepted
          and normalized to a 14-digit API number.
        schema:
          type: string
        example: '30015234560000'
      responses:
        '200':
          description: Persisted lifecycle summary
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    "$ref": "#/components/schemas/WellLifecycleWellSummary"
        '400':
          description: Malformed API number
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Enterprise plan required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Lifecycle summary unavailable for this well or state
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/well-lifecycle/cohorts":
    get:
      summary: Well lifecycle cohorts
      operationId: getV1WellLifecycleCohorts
      tags:
      - Well Lifecycle
      description: |
        Returns cohort-level cycle-time summaries from persisted lifecycle summaries
        for promoted states. Supported grouping dimensions are operator, county, and
        permit quarter.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: state
        in: query
        required: true
        description: Promoted two-letter state code.
        schema:
          type: string
          enum:
          - NM
          - WY
          - ND
          - AK
        example: NM
      - name: group_by
        in: query
        required: false
        description: Cohort grouping dimension.
        schema:
          type: string
          enum:
          - operator
          - county
          - quarter
          default: operator
          example: operator
        example: operator
      responses:
        '200':
          description: Lifecycle cohort summaries
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    "$ref": "#/components/schemas/WellLifecycleCohorts"
        '400':
          description: Invalid state or grouping parameter
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '403':
          description: Enterprise plan required
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '404':
          description: Lifecycle cohorts unavailable for this state
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/meta/limits":
    get:
      summary: Get machine-readable plan request limits
      operationId: getV1MetaLimits
      tags:
      - Plan Metadata
      description: |
        Canonical, keyless source of truth for the free-tier allowance and every
        paid plan's request limit and window (#5793). First-party clients — the
        website, docs, SDKs, spreadsheet add-ins and the browser extension — read
        this instead of hardcoding a limit, which is how "200 requests/month"
        previously drifted across 229 call sites.

        Unauthenticated and heavily cached. Prefer this over parsing pricing copy.
      security: []
      responses:
        '200':
          description: Current free-tier allowance and the paid plan ladder
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      free:
                        type: object
                        description: The free-tier allowance.
                        properties:
                          limit:
                            type: integer
                            example: 50
                          window:
                            type: string
                            description: The period the limit resets over.
                            enum:
                            - day
                            - month
                            example: day
                          copy:
                            type: string
                            description: Pre-rendered display string for UI copy.
                            example: 50/day
                      plans:
                        type: array
                        description: Paid plan ladder, ascending by limit.
                        items:
                          type: object
                          properties:
                            plan:
                              type: string
                              example: developer
                            limit:
                              type: integer
                              example: 10000
                            window:
                              type: string
                              enum:
                              - day
                              - month
                              example: month
                            copy:
                              type: string
                              example: 10,000/month
        '429':
          description: |
            Rate limited. This endpoint is keyless, so it is throttled by IP via
            Rack::Attack rather than by plan entitlement. Honour Retry-After.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/spreads/crack":
    get:
      summary: Get the current crack spread
      operationId: getV1SpreadsCrack
      tags:
      - Spreads
      description: Refining crack spread with its crude and product legs.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get the current crack spread
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      spread_type:
                        type: string
                      crude_benchmark:
                        type: string
                      value:
                        type: number
                      unit:
                        type: string
                      components:
                        type: object
                        properties:
                          crude:
                            type: object
                            properties:
                              code:
                                type: string
                              price:
                                type: number
                              unit:
                                type: string
                          gasoline:
                            type: object
                            properties:
                              code:
                                type: string
                              price:
                                type: number
                              unit:
                                type: string
                          diesel:
                            type: object
                            properties:
                              code:
                                type: string
                              price:
                                type: number
                              unit:
                                type: string
                      timestamp:
                        type: string
                        format: date-time
                      changes:
                        type: object
                        properties:
                          change_1d:
                            type: number
                          change_1d_pct:
                            type: number
                          change_7d:
                            type: number
                          change_7d_pct:
                            type: number
                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"
        '404':
          description: A current gasoil or Brent futures leg is not available.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/v1/spreads/crack/historical":
    get:
      summary: Get crack spread history
      operationId: getV1SpreadsCrackHistorical
      tags:
      - Spreads
      description: Historical crack spread series.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get crack spread 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
                      spread_type:
                        type: string
                      crude_benchmark:
                        type: string
                      coverage:
                        type: string
                      data_revised_at:
                        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: period
        in: query
        required: false
        schema:
          type: string
          example: 30d
        description: Lookback window for the series.
  "/v1/spreads/crack/all":
    get:
      summary: Get all crack spreads
      operationId: getV1SpreadsCrackAll
      tags:
      - Spreads
      description: Every crack spread currently calculated.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get all crack spreads
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      crude_benchmark:
                        type: string
                      spreads:
                        type: array
                        items:
                          type: object
                          properties:
                            spread_type:
                              type: string
                            value:
                              type: number
                            unit:
                              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/spreads/basis":
    get:
      summary: Get a basis spread
      operationId: getV1SpreadsBasis
      tags:
      - Spreads
      description: Location or grade basis spread between two benchmarks.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get a basis spread
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      pair:
                        type: string
                      spread_name:
                        type: string
                      value:
                        type: number
                      unit:
                        type: string
                      signal:
                        type: string
                      percentile_1y:
                        type: number
                      components:
                        type: object
                        properties: {}
                      changes:
                        type: object
                        properties:
                          change_1d:
                            type: number
                          change_1d_pct:
                            type: number
                          change_7d:
                            type: number
                          change_7d_pct:
                            type: number
                      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: pair
        in: query
        required: true
        schema:
          type: string
          enum:
          - WAHA_HH
          - BRENT_WTI
          - BRENT_DUBAI
          - TTF_HH
          - BRENT_OMAN
          example: BRENT_WTI
        description: Benchmark pair. The 400 response enumerates valid values.
  "/v1/spreads/basis/historical":
    get:
      summary: Get basis spread history
      operationId: getV1SpreadsBasisHistorical
      tags:
      - Spreads
      description: Historical basis spread series.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get basis spread 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
                      pair:
                        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: pair
        in: query
        required: true
        schema:
          type: string
          enum:
          - WAHA_HH
          - BRENT_WTI
          - BRENT_DUBAI
          - TTF_HH
          - BRENT_OMAN
          example: BRENT_WTI
        description: Benchmark pair. The 400 response enumerates valid values.
      - name: period
        in: query
        required: false
        schema:
          type: string
          example: 30d
        description: Lookback window for the series.
  "/v1/spreads/basis/all":
    get:
      summary: Get all basis spreads
      operationId: getV1SpreadsBasisAll
      tags:
      - Spreads
      description: Every basis spread currently calculated.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get all basis spreads
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      spreads:
                        type: array
                        items:
                          type: object
                          properties:
                            pair:
                              type: string
                            value:
                              type: number
                            unit:
                              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/spreads/margin":
    get:
      summary: Get the refining margin index
      operationId: getV1SpreadsMargin
      tags:
      - Spreads
      description: Refining margin index with signal and one-year percentile.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get the refining margin index
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      index:
                        type: string
                      name:
                        type: string
                      margin_usd_bbl:
                        type: number
                      crude_input:
                        type: string
                      product_basket:
                        type: object
                        properties: {}
                      signal:
                        type: string
                      percentile_1y:
                        type: number
                      changes:
                        type: object
                        properties:
                          change_1d:
                            type: number
                          change_1d_pct:
                            type: number
                          change_7d:
                            type: number
                          change_7d_pct:
                            type: number
                      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/spreads/margin/historical":
    get:
      summary: Get refining margin history
      operationId: getV1SpreadsMarginHistorical
      tags:
      - Spreads
      description: Historical refining margin series.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get refining margin 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
                      index:
                        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/spreads/margin/all":
    get:
      summary: Get all refining margins
      operationId: getV1SpreadsMarginAll
      tags:
      - Spreads
      description: Every refining margin index currently calculated.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get all refining margins
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      margins:
                        type: array
                        items:
                          type: object
                          properties:
                            index:
                              type: string
                            margin_usd_bbl:
                              type: number
                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/spreads/curve-structure":
    get:
      summary: Get futures curve structure
      operationId: getV1SpreadsCurveStructure
      tags:
      - Spreads
      description: Contango or backwardation structure for a futures curve.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get futures curve structure
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      commodity:
                        type: string
                      display_name:
                        type: string
                      structure:
                        type: string
                      signal:
                        type: string
                      severity:
                        type: string
                      front_month:
                        type: object
                        properties: {}
                      back_month_6:
                        type: object
                        properties: {}
                      spreads:
                        type: object
                        properties: {}
                      curve_points:
                        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: commodity
        in: query
        required: true
        schema:
          type: string
          enum:
          - ICE_BRENT
          - ICE_WTI
          - ICE_GASOIL
          - NYMEX_NG
          - ICE_TTF
          example: ICE_BRENT
        description: Futures curve. The 400 response enumerates valid values.
  "/v1/spreads/curve-structure/all":
    get:
      summary: Get all curve structures
      operationId: getV1SpreadsCurveStructureAll
      tags:
      - Spreads
      description: Curve structure across every supported futures curve.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get all curve structures
          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
                            structure:
                              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/spreads/physical-premium":
    get:
      summary: Get a physical premium
      operationId: getV1SpreadsPhysicalPremium
      tags:
      - Spreads
      description: Physical grade premium against its benchmark.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get a physical premium
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      commodity:
                        type: string
                      name:
                        type: string
                      premium:
                        type: number
                      premium_pct:
                        type: number
                      percentile_1y:
                        type: number
                      elevated_streak_days:
                        type: integer
                      data_stale:
                        type: boolean
                      components:
                        type: object
                        properties: {}
                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
          example: WTI_MIDLAND
        description: Physical grade. Omit for the default grade.
  "/v1/spreads/physical-premium/historical":
    get:
      summary: Get physical premium history
      operationId: getV1SpreadsPhysicalPremiumHistorical
      tags:
      - Spreads
      description: Historical physical premium series.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get physical premium 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
                      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: period
        in: query
        required: false
        schema:
          type: string
          example: 30d
        description: Lookback window for the series.
  "/v1/spreads/physical-premium/all":
    get:
      summary: Get all physical premiums
      operationId: getV1SpreadsPhysicalPremiumAll
      tags:
      - Spreads
      description: Every physical premium currently calculated.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Get all physical premiums
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      premiums:
                        type: array
                        items:
                          type: object
                          properties:
                            commodity:
                              type: string
                            premium:
                              type: number
                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":
    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:
                        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 Commitments of Traders positioning for a commodity.
      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
                      week_change:
                        type: object
                        properties: {}
                      report_date:
                        type: string
                        format: date
                      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
          example: ICE_BRENT
        description: Commodity. Omit for the default commodity.
  "/v1/indicators/cftc-positioning/historical":
    get:
      summary: Get CFTC positioning history
      operationId: getV1IndicatorsCftcPositioningHistorical
      tags:
      - Indicators
      description: Historical CFTC positioning series.
      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: string
                        example: 30d
                      count:
                        type: integer
                      data:
                        type: array
                        items:
                          type: object
                          properties:
                            date:
                              type: string
                            value:
                              type: number
                      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: period
        in: query
        required: false
        schema:
          type: string
          example: 30d
        description: Lookback window for the series.
  "/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.
  "/v1/spreads/gasoil-crack":
    get:
      summary: Get the European gasoil crack
      operationId: getV1SpreadsGasoilCrack
      tags:
      - Spreads
      description: |-
        ICE Low Sulphur Gasoil against ICE Brent — the European refining-margin benchmark, and an exchange-listed instrument (ICE 'Low Sulphur Gasoil/Brent Futures Crack'; CME NYMEX rulebook ch.143).

        Computed as `(gasoil USD/tonne / 7.45) - brent USD/bbl`, where 7.45 is the exchange-standard barrels per metric tonne.

        Distinct from `/v1/spreads/crack`, which computes SPOT cracks on the US product slate. This one is futures-native — there is no gasoil spot code — so the response names the exact contract month used for each leg.
      security:
      - ApiKeyAuth: []
      responses:
        '200':
          description: Current European gasoil crack
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      spread_type:
                        type: string
                        example: gasoil
                      name:
                        type: string
                      value:
                        type: number
                        example: 76.73
                      unit:
                        type: string
                        example: USD/bbl
                      components:
                        type: object
                        properties:
                          product:
                            type: object
                            properties:
                              code:
                                type: string
                                example: GASOIL_FUTURES_2026_09
                              contract_month:
                                type: string
                                example: 2026-09
                              updated_at:
                                type: string
                                format: date-time
                                description: When this leg's settle was collected.
                                  On a weekend this is Friday's settle time — futures-derived
                                  data serves under the same bound as /v1/futures/*.
                              settlement_date:
                                type: string
                                format: date
                                description: Exchange trading session the settle belongs
                                  to, when known.
                              price:
                                type: number
                                example: 1208.5
                              unit:
                                type: string
                                example: USD/tonne
                          crude:
                            type: object
                            properties:
                              code:
                                type: string
                                example: BRENT_FUTURES_2026_11
                              contract_month:
                                type: string
                                example: 2026-11
                              updated_at:
                                type: string
                                format: date-time
                                description: When this leg's settle was collected.
                              settlement_date:
                                type: string
                                format: date
                                description: Exchange trading session the settle belongs
                                  to, when known.
                              price:
                                type: number
                                example: 85.48
                              unit:
                                type: string
                                example: USD/bbl
                      conversion:
                        type: object
                        properties:
                          barrels_per_tonne:
                            type: number
                            example: 7.45
                          basis:
                            type: string
                          gasoil_usd_per_bbl:
                            type: number
                            example: 162.21
                      timestamp:
                        type: string
                        format: date-time
                      updated_at:
                        type: string
                        format: date-time
                        description: Newest collection time across the two legs.
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        '500':
          "$ref": "#/components/responses/InternalServerError"
  "/sample":
    get:
      summary: No-key sample commodity prices
      operationId: getPublicSamplePrices
      tags:
      - Discovery
      description: Public no-auth sample endpoint for agent discovery. Returns representative
        public prices only; organization-owned private rows are excluded.
      security: []
      parameters:
      - name: by_code
        in: query
        required: false
        description: Representative commodity code to sample.
        schema:
          type: string
          enum:
          - WTI_USD
          - BRENT_CRUDE_USD
          - NATURAL_GAS_USD
          example: WTI_USD
      - name: measure
        in: query
        required: false
        description: Sample measurement to return.
        schema:
          type: string
          enum:
          - spot_price
          - change_24h
          - source_timestamp
          default: spot_price
          example: spot_price
      responses:
        '200':
          description: Representative public sample prices
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '422':
          description: Unsupported code or measure
        '429':
          description: Anonymous sample rate limit exceeded
  "/v1/sample":
    get:
      summary: No-key sample commodity prices
      operationId: getV1PublicSamplePrices
      tags:
      - Discovery
      description: Public no-auth sample endpoint for agent discovery. Returns representative
        public prices only; organization-owned private rows are excluded.
      security: []
      parameters:
      - name: by_code
        in: query
        required: false
        description: Representative commodity code to sample.
        schema:
          type: string
          enum:
          - WTI_USD
          - BRENT_CRUDE_USD
          - NATURAL_GAS_USD
          example: WTI_USD
      - name: measure
        in: query
        required: false
        description: Sample measurement to return.
        schema:
          type: string
          enum:
          - spot_price
          - change_24h
          - source_timestamp
          default: spot_price
          example: spot_price
      responses:
        '200':
          description: Representative public sample prices
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '422':
          description: Unsupported code or measure
        '429':
          description: Anonymous sample rate limit exceeded
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'API key as: Authorization: Token YOUR_API_KEY'
  headers:
    XPage:
      description: Current one-based page number.
      schema:
        type: integer
        minimum: 1
        example: 1
    XPerPage:
      description: Page size actually applied by the server.
      schema:
        type: integer
        minimum: 1
        example: 500
    XTotal:
      description: Total records available for the request when countable.
      schema:
        type: integer
        minimum: 0
        example: 9121
    XTotalPages:
      description: Total number of pages available.
      schema:
        type: integer
        minimum: 0
        example: 19
  responses:
    RateLimited:
      description: Rolling rate limit exceeded. Retry with bounded backoff.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ErrorResponse"
    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"
  parameters:
    FuelSurchargeCarrier:
      name: carrier
      in: path
      required: true
      description: Covered LTL carrier slug returned by the list endpoint
      schema:
        type: string
        example: odfl
    ParcelFuelSurchargeCarrier:
      name: carrier
      in: path
      required: true
      description: Covered parcel carrier slug returned by the parcel list endpoint
      schema:
        type: string
        example: ups
    FuelSurchargeServiceLevel:
      name: service_level
      in: query
      required: false
      description: Optional carrier service-level identifier, such as `ground`
      schema:
        type: string
        example: ground
    Page:
      name: page
      in: query
      required: false
      description: One-indexed result page
      schema:
        type: integer
        minimum: 1
        default: 1
    FuelSurchargePerPage:
      name: per_page
      in: query
      required: false
      description: Results per page, capped at 100
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 100
  schemas:
    ApiKey:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
          description: Optional label for the key
        token_hint:
          type: string
          description: First 8 characters of the token
          example: a1b2c3d4
        active:
          type: boolean
        created_at:
          type: string
          format: date-time
        revoked_at:
          type: string
          format: date-time
          nullable: true
        plain_token:
          type: string
          description: Full token — only returned on create and roll responses
    DemoPricesResponse:
      type: object
      description: Response from demo API endpoint (no authentication required)
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            prices:
              type: array
              items:
                "$ref": "#/components/schemas/DemoPrice"
            meta:
              type: object
              properties:
                demo_mode:
                  type: boolean
                  example: true
                rate_limit:
                  type: string
                  example: 20 requests per hour
                signup_url:
                  type: string
                  example: https://www.oilpriceapi.com/signup
                documentation_url:
                  type: string
                  example: https://docs.oilpriceapi.com
            examples:
              type: object
              properties:
                curl:
                  type: string
                python:
                  type: string
                javascript:
                  type: string
    DemoPrice:
      type: object
      description: Price data returned from demo endpoint
      properties:
        code:
          type: string
          description: Commodity code
          example: BRENT_CRUDE_USD
        name:
          type: string
          description: Human-readable commodity name
          example: Brent Crude Oil
        price:
          type: number
          format: float
          description: Current price
          example: 75.42
        currency:
          type: string
          description: Price currency
          example: USD
        updated_at:
          type: string
          format: date-time
          description: When the price was last updated
        source:
          type: string
          description: Data source
          example: OilPriceAPI
    Price:
      type: object
      properties:
        price:
          type: number
          format: float
          description: Numeric price value
          example: 75.42
        formatted:
          type: string
          description: Formatted price with currency symbol
          example: "$75.42"
        currency:
          type: string
          description: Currency code
          example: USD
        code:
          type: string
          description: Commodity code
          example: BRENT_CRUDE_USD
        created_at:
          type: string
          format: date-time
          description: Timestamp when price was recorded
          example: '2025-01-20T10:30:00.000Z'
        updated_at:
          type: string
          format: date-time
          description: Timestamp when price was last updated (alias for created_at)
          example: '2025-01-20T10:30:00.000Z'
        type:
          type: string
          description: Price type
          example: spot_price
        change_24h:
          type: number
          format: float
          nullable: true
          description: Price change vs 24 hours ago (absolute value). Returns null
            when insufficient historical data exists for comparison. A value of 0.0
            means the price is unchanged.
          example: 0.74
        change_24h_percent:
          type: number
          format: float
          nullable: true
          description: Price change vs 24 hours ago (percentage). Returns null when
            insufficient historical data exists for comparison. A value of 0.0 means
            the price is unchanged.
          example: 1.25
    PriceData:
      type: object
      description: |
        A single commodity price point. Returned as the flat `data` object for a single-commodity
        request, or as an element of `data.prices` for multi-commodity / historical requests.
      properties:
        price:
          type: number
          format: float
          example: 68.58
        formatted:
          type: string
          example: "$68.58"
        currency:
          type: string
          example: USD
        code:
          type: string
          example: WTI_USD
        created_at:
          type: string
          format: date-time
          example: '2026-07-03T13:43:01.099Z'
        updated_at:
          type: string
          format: date-time
          example: '2026-07-03T13:43:01.099Z'
        type:
          type: string
          example: spot_price
        unit:
          type: string
          example: barrel
        source:
          type: string
          description: Customer-safe source label. Non-government market sources are
            returned as `market_reporting`.
          example: market_reporting
        observed_at:
          type: string
          format: date-time
          description: Source observation timestamp when the upstream series supplies
            one.
          example: '2026-07-13T12:00:00.000Z'
        source_date:
          type: string
          format: date
          description: Source observation date when available.
          example: '2026-07-13'
        as_of:
          type: string
          format: date-time
          description: Timestamp when the value was last a genuine source observation.
          example: '2026-07-13T12:00:00.000Z'
        collected_at:
          type: string
          format: date-time
          description: Timestamp when OilPriceAPI collected or produced this row.
          example: '2026-07-15T21:00:00.000Z'
        stale:
          type: boolean
          description: Whether `as_of` exceeds this series' expected publication cadence.
          example: false
        age_days:
          type: integer
          minimum: 0
          description: Whole days between `as_of` and response generation.
          example: 2
        synthetic:
          type: boolean
          description: True only for carried-forward heartbeat rows rather than genuine
            source observations.
          example: false
        price_type:
          type: string
          description: Underlying price type for aggregated historical rows.
          example: spot_price
        data_status:
          type: string
          description: Freshness classification of the price.
          example: current
        freshness:
          type: object
          properties:
            status:
              type: string
              example: current
            age_seconds:
              type: integer
              example: 275
            expected_max_age_seconds:
              type: integer
              example: 1800
        changes:
          type: object
          description: Price change over rolling windows. Keys are 24h/7d/30d/90d.
          properties:
            24h:
              "$ref": "#/components/schemas/PriceChange"
            7d:
              "$ref": "#/components/schemas/PriceChange"
            30d:
              "$ref": "#/components/schemas/PriceChange"
            90d:
              "$ref": "#/components/schemas/PriceChange"
    HistoricalPricesResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
          example: success
        data:
          type: object
          required:
          - prices
          properties:
            prices:
              type: array
              items:
                "$ref": "#/components/schemas/PriceData"
            metadata:
              type: object
              description: Present for bounded or relative windows; describes the
                applied interval, entitlement-aware window, pagination, and availability.
              additionalProperties: true
            missing:
              type: array
              description: Requested commodity codes with no matching data in the
                applied window.
              items:
                type: object
                additionalProperties: true
    PriceChange:
      type: object
      properties:
        amount:
          type: number
          format: float
          example: 0.72
        percent:
          type: number
          format: float
          example: 1.06
        previous_price:
          type: number
          format: float
          example: 67.86
    LatestPriceResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          allOf:
          - "$ref": "#/components/schemas/PriceData"
          - type: object
            properties:
              metadata:
                type: object
                properties:
                  source:
                    type: string
                    example: market_reporting
                  source_description:
                    type: string
                    example: Aggregated from published market sources
    LatestPricesResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            prices:
              type: array
              items:
                "$ref": "#/components/schemas/PriceData"
            metadata:
              type: object
              properties:
                request_id:
                  type: string
                  example: 6390b34903a8d3f0
                timestamp:
                  type: string
                  format: date-time
                  example: '2026-07-03T13:47:37Z'
                version:
                  type: string
                  example: v1
    PricesResponse:
      type: object
      properties:
        prices:
          type: array
          items:
            "$ref": "#/components/schemas/Price"
        meta:
          type: object
          properties:
            current_page:
              type: integer
              example: 1
            total_pages:
              type: integer
              example: 10
            total_count:
              type: integer
              example: 250
            per_page:
              type: integer
              example: 25
    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
              nullable: true
              example: https://www.oilpriceapi.com/auth/signup
            demo_endpoint:
              type: string
              nullable: true
              example: "/v1/demo/prices"
    FailErrorResponse:
      type: object
      properties:
        status:
          type: string
          example: fail
        data:
          type: object
          properties:
            error:
              type: string
              example: invalid_code
            message:
              type: string
              example: Code 'NOT_REAL' not found. See /v1/commodities for all available
                codes.
            suggestions:
              type: array
              items:
                type: string
              example: []
            invalid_codes:
              type: array
              items:
                type: string
              example:
              - NOT_REAL
    PriceWatch:
      type: object
      description: A persistent commodity watch evaluated on the configured interval.
      required:
      - id
      - codes
      - interval_seconds
      - status
      - deliver_webhook
      - source
      - created_at
      properties:
        id:
          type: string
          example: '018f47a2-4d4d-7a44-9fa4-123456789abc'
        name:
          type: string
          nullable: true
          example: My WTI watch
        codes:
          type: array
          minItems: 1
          items:
            type: string
          example:
          - WTI_USD
          - BRENT_CRUDE_USD
        interval_seconds:
          type: integer
          minimum: 1
          example: 3600
        status:
          type: string
          enum:
          - active
          - paused
          example: active
        deliver_webhook:
          type: boolean
          example: false
        source:
          type: string
          enum:
          - api
          - mcp
          - dashboard
          example: api
        tool_name:
          type: string
          nullable: true
          example: watch_commodity
        last_evaluated_at:
          type: string
          format: date-time
          nullable: true
        next_run_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
    PriceWatchResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
          example: success
        data:
          type: object
          required:
          - subscription
          properties:
            subscription:
              "$ref": "#/components/schemas/PriceWatch"
    StateProduction:
      type: object
      properties:
        state:
          type: string
          example: TX
        period:
          type: string
          example: 2026-03
        oil_bbl:
          type: number
          nullable: true
          example: 179126000
        oil_bpd:
          type: number
          nullable: true
          example: 5778258
        gas_mcf:
          type: number
          nullable: true
        boe:
          type: number
          nullable: true
          example: 179126000
    WellLifecycleStateAvailability:
      type: object
      properties:
        state:
          type: string
          example: TX
        status:
          type: string
          enum:
          - available
          - partial
          - repair_required
          - unavailable
          example: repair_required
        validation_status:
          type: string
          example: research_required
        success:
          type: boolean
          example: true
        reasons:
          type: array
          items:
            type: string
          example:
          - duplicate_source_records_need_state_policy
        metrics:
          type: object
          properties:
            permit_apis:
              type: integer
            production_matches:
              type: integer
            exact_match_rate_pct:
              type: number
            clean_permit_to_production_rate_pct:
              type: number
            chronology_error_rate_pct:
              type: number
        production_window:
          type: object
          nullable: true
        scope:
          type: object
          properties:
            api_limit:
              type: integer
              nullable: true
            bounded:
              type: boolean
        thresholds:
          type: object
          nullable: true
        caveats:
          type: array
          items:
            type: string
        samples:
          type: object
          nullable: true
        summary:
          "$ref": "#/components/schemas/WellLifecycleStateSummary"
    WellLifecycleStateSummary:
      type: object
      properties:
        status:
          type: string
          enum:
          - summary_available
          - summary_not_built
          - not_promoted
          example: summary_available
        summary_wells:
          type: integer
          example: 12450
        production_window:
          type: object
          nullable: true
          properties:
            first_production_month:
              type: string
              format: date
              nullable: true
              example: '2019-01-01'
            latest_production_month:
              type: string
              format: date
              nullable: true
              example: '2026-04-01'
        cumulative:
          type: object
          nullable: true
          properties:
            oil_bbl:
              type: number
              nullable: true
              example: 1850000
            gas_mcf:
              type: number
              nullable: true
              example: 4250000
            water_bbl:
              type: number
              nullable: true
              example: 3100000
            boe:
              type: number
              nullable: true
              example: 2558333.33
        coverage_statuses:
          type: object
          additionalProperties:
            type: integer
          example:
            full_chain: 11890
            permit_spud_production_no_completion: 560
        frac_focus:
          type: object
          properties:
            matched_wells:
              type: integer
              example: 10420
            match_rate_pct:
              type: number
              nullable: true
              example: 83.7
            latest_job_start_date:
              type: string
              format: date
              nullable: true
              example: '2026-07-10'
        summary_generated_at:
          type: string
          format: date-time
          nullable: true
    WellLifecycleWellSummary:
      type: object
      properties:
        api_number:
          type: string
          example: '30015234560000'
        state:
          type: string
          example: NM
        county:
          type: string
          nullable: true
          example: Eddy
        operator:
          type: string
          nullable: true
          example: Example Energy LLC
        well_name:
          type: string
          nullable: true
          example: STATE 1H
        source:
          type: string
          example: New Mexico OCD
        lifecycle_dates:
          type: object
          properties:
            permit_date:
              type: string
              format: date
              nullable: true
            approval_date:
              type: string
              format: date
              nullable: true
            spud_date:
              type: string
              format: date
              nullable: true
            year_spudded:
              type: integer
              nullable: true
            completion_date:
              type: string
              format: date
              nullable: true
            first_production_month:
              type: string
              format: date
              nullable: true
            latest_production_month:
              type: string
              format: date
              nullable: true
        production:
          type: object
          properties:
            production_months:
              type: integer
              example: 18
            cumulative_oil_bbl:
              type: number
              nullable: true
              example: 125000
            cumulative_gas_mcf:
              type: number
              nullable: true
              example: 400000
            cumulative_water_bbl:
              type: number
              nullable: true
              example: 210000
            cumulative_boe:
              type: number
              nullable: true
              example: 191666.67
        cycle_times:
          type: object
          properties:
            permit_to_spud_days:
              type: integer
              nullable: true
              example: 40
            spud_to_completion_days:
              type: integer
              nullable: true
              example: 70
            completion_to_first_prod_days:
              type: integer
              nullable: true
              example: 26
            permit_to_first_prod_days:
              type: integer
              nullable: true
              example: 136
            permit_to_frac_days:
              type: integer
              nullable: true
              example: 69
            completion_to_frac_days:
              type: integer
              nullable: true
              example: 9
            frac_to_first_prod_days:
              type: integer
              nullable: true
              example: 52
        frac_focus:
          type: object
          properties:
            matched:
              type: boolean
              example: true
            disclosure_count:
              type: integer
              example: 1
            match_status:
              type: string
              enum:
              - no_match
              - exact_api_match
              - exact_api_match_missing_job_date
              - multiple_exact_api_matches
              - multiple_exact_api_matches_missing_primary_job_date
              example: exact_api_match
            match_confidence:
              type: integer
              nullable: true
              example: 100
            primary_upload_key:
              type: string
              nullable: true
              example: ff-upload-1
            job_start_date:
              type: string
              format: date
              nullable: true
              example: '2024-03-10'
            job_end_date:
              type: string
              format: date
              nullable: true
              example: '2024-03-12'
            water_gallons:
              type: integer
              format: int64
              nullable: true
              example: 12750000
            non_water_gallons:
              type: integer
              format: int64
              nullable: true
              example: 100
            chemical_count:
              type: integer
              nullable: true
              example: 42
            source:
              type: string
              example: FracFocus
        source_coverage_status:
          type: string
          enum:
          - full_chain
          - permit_spud_production_no_completion
          - permit_completion_production_no_spud
          - permit_production_only
          - production_join_without_permit_date
          example: full_chain
        data_quality_flags:
          type: array
          items:
            type: string
          example:
          - missing_completion_date
        summary_generated_at:
          type: string
          format: date-time
    WellLifecycleCohorts:
      type: object
      properties:
        state:
          type: string
          example: NM
        group_by:
          type: string
          enum:
          - operator
          - county
          - quarter
          example: operator
        count:
          type: integer
          example: 25
        cohorts:
          type: array
          items:
            "$ref": "#/components/schemas/WellLifecycleCohort"
    WellLifecycleCohort:
      type: object
      properties:
        key:
          type: string
          example: Example Energy LLC
        well_count:
          type: integer
          example: 150
        cycle_time_stats:
          type: object
          properties:
            avg_permit_to_first_prod_days:
              type: number
              nullable: true
              example: 126.8
            min_permit_to_first_prod_days:
              type: number
              nullable: true
              example: 45
            max_permit_to_first_prod_days:
              type: number
              nullable: true
              example: 260
            avg_permit_to_spud_days:
              type: number
              nullable: true
              example: 45.2
            avg_spud_to_completion_days:
              type: number
              nullable: true
              example: 58.7
            avg_completion_to_first_prod_days:
              type: number
              nullable: true
              example: 21.4
            avg_permit_to_frac_days:
              type: number
              nullable: true
              example: 69.2
            avg_completion_to_frac_days:
              type: number
              nullable: true
              example: 8.7
            avg_frac_to_first_prod_days:
              type: number
              nullable: true
              example: 52.1
    CycleTimeStats:
      type: object
      properties:
        count:
          type: integer
          example: 45
        median_days:
          type: number
          example: 30
        p25_days:
          type: number
          example: 20
        p75_days:
          type: number
          example: 50
        p90_days:
          type: number
          example: 133
        min_days:
          type: number
          example: 1
        max_days:
          type: number
          example: 332
        avg_days:
          type: number
          example: 52
    RateLimitErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: RATE_LIMIT_EXCEEDED
            message:
              type: string
              example: Rate limit exceeded
            details:
              type: object
              properties:
                limit:
                  type: integer
                  example: 100
                remaining:
                  type: integer
                  example: 0
                reset_at:
                  type: string
                  format: date-time
                  example: '2025-01-20T11:00:00.000Z'
                retry_after:
                  type: integer
                  example: 3600
            documentation_url:
              type: string
              example: https://docs.oilpriceapi.com/rate-limits
    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
          nullable: true
          description: Customer-safe source label; internal venue and scraper names
            are masked
        update_frequency:
          type: string
          nullable: true
          description: Expected source-specific refresh cadence
        status:
          type: string
          enum:
          - available
          - unavailable
        has_data:
          type: boolean
        unavailable_reason:
          type: string
          nullable: true
          enum:
          - never_had_data
          - not_served
          - withheld
          - discontinued
        unavailable_detail:
          type: string
          nullable: true
        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
    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
            nullable: true
            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'
    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
                      nullable: true
    CommodityDetailResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          "$ref": "#/components/schemas/CommodityWithPrice"
    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
              nullable: true
              properties:
                min:
                  type: integer
                  example: 2
                max:
                  type: integer
                  example: 8
            revisions:
              type: string
              nullable: true
              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
    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
    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
          format: date
          nullable: true
          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.
    FuelSurchargeRate:
      type: object
      required:
      - carrier
      - carrier_name
      - mode
      - surcharge_percent
      - effective_date
      - doe_diesel_price
      - diesel_band
      - source
      - retrieved_at
      properties:
        carrier:
          type: string
          example: odfl
        carrier_name:
          type: string
          example: Old Dominion Freight Line
        mode:
          type: string
          enum:
          - ltl
          - parcel
        service_level:
          type: string
          description: Present for parcel rates
          example: ground
        surcharge_percent:
          type: number
          format: float
          example: 25.5
        effective_date:
          type: string
          format: date
        doe_diesel_price:
          type: number
          format: float
          nullable: true
        diesel_band:
          type: object
          nullable: true
          required:
          - min
          - max
          properties:
            min:
              type: number
              format: float
              nullable: true
            max:
              type: number
              format: float
              nullable: true
        source:
          type: string
          format: uri
          description: Carrier-published schedule URL
        retrieved_at:
          type: string
          format: date-time
    ParcelFuelSurchargeCarrier:
      type: object
      required:
      - carrier
      - carrier_name
      - mode
      - service_levels
      properties:
        carrier:
          type: string
          example: ups
        carrier_name:
          type: string
          example: UPS
        mode:
          type: string
          enum:
          - parcel
        service_levels:
          type: array
          items:
            "$ref": "#/components/schemas/FuelSurchargeRate"
    FuelSurchargeHistoryMeta:
      type: object
      required:
      - page
      - per_page
      - total_count
      - total_pages
      properties:
        page:
          type: integer
          minimum: 1
        per_page:
          type: integer
          minimum: 1
          maximum: 100
        total_count:
          type: integer
          minimum: 0
        total_pages:
          type: integer
          minimum: 0
    FuelSurchargeListResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          type: object
          required:
          - carriers
          properties:
            carriers:
              type: array
              items:
                "$ref": "#/components/schemas/FuelSurchargeRate"
    FuelSurchargeRateResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          "$ref": "#/components/schemas/FuelSurchargeRate"
    FuelSurchargeHistoryResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          type: object
          required:
          - history
          - meta
          properties:
            history:
              type: array
              items:
                "$ref": "#/components/schemas/FuelSurchargeRate"
            meta:
              "$ref": "#/components/schemas/FuelSurchargeHistoryMeta"
    ParcelFuelSurchargeListResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          type: object
          required:
          - carriers
          properties:
            carriers:
              type: array
              items:
                "$ref": "#/components/schemas/ParcelFuelSurchargeCarrier"
    ParcelFuelSurchargeCarrierResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          "$ref": "#/components/schemas/ParcelFuelSurchargeCarrier"
    DatasetCoverageResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          enum:
          - success
        data:
          "$ref": "#/components/schemas/DatasetCoverage"
    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
          nullable: true
        currency:
          type: string
        unit:
          type: string
        availability:
          type: string
          enum:
          - active
          - stale
          - discontinued
          - source_limited
          - unavailable
          - empty
        availability_reason:
          type: string
          nullable: true
        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
              format: date-time
              nullable: true
            stale:
              type: boolean
              nullable: true
            age_days:
              type: integer
              nullable: true
        history:
          type: object
          required:
          - available_from
          - available_to
          - granularities
          - coverage_type
          - measured_at
          - sample_count
          properties:
            available_from:
              type: string
              format: date
              nullable: true
            available_to:
              type: string
              format: date
              nullable: true
            granularities:
              type: array
              items:
                type: string
            coverage_type:
              type: string
              enum:
              - observed_series
              - unknown
            measured_at:
              type: string
              format: date-time
              nullable: true
            sample_count:
              type: integer
              nullable: true
        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
    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
    MarinePortsResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            ports:
              type: array
              items:
                "$ref": "#/components/schemas/MarinePort"
            count:
              type: integer
              example: 8
            filters:
              type: object
              properties:
                region:
                  type: string
                  nullable: true
                country:
                  type: string
                  nullable: true
                major_ports_only:
                  type: boolean
    MarinePortDetailResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            port:
              "$ref": "#/components/schemas/MarinePortWithPrices"
    MarinePort:
      type: object
      properties:
        code:
          type: string
          example: SGSIN
          description: Unique port identifier
        name:
          type: string
          example: Singapore
          description: Port name
        country:
          type: string
          example: Singapore
          description: Country where port is located
        region:
          type: string
          example: Asia
          description: Geographic region
        major_port:
          type: boolean
          example: true
          description: Whether this is a major bunkering hub
        coordinates:
          type: object
          properties:
            latitude:
              type: number
              format: float
              example: 1.2966
            longitude:
              type: number
              format: float
              example: 103.7764
        fuel_services:
          type: array
          items:
            type: string
          example:
          - MGO_05S
          - VLSFO
          - HFO_380
          - HFO_180
          description: Available fuel types at this port
        trading_hours:
          type: string
          example: 24/7
          description: Port operating hours
    MarinePortWithPrices:
      allOf:
      - "$ref": "#/components/schemas/MarinePort"
      - type: object
        properties:
          metadata:
            type: object
            properties:
              timezone:
                type: string
                example: Asia/Singapore
              annual_volume_mt:
                type: integer
                example: 50000000
                description: Annual bunkering volume in metric tons
          recent_prices:
            type: array
            items:
              "$ref": "#/components/schemas/MarineFuelPrice"
          statistics:
            type: object
            properties:
              total_fuel_types:
                type: integer
                example: 4
              recent_price_updates:
                type: integer
                example: 10
              last_update:
                type: string
                format: date-time
                example: '2025-08-05T00:32:10Z'
    MarineFuelPrice:
      type: object
      properties:
        fuel_type:
          type: string
          example: MGO_05S
          description: Fuel grade code
        fuel_name:
          type: string
          example: Marine Gas Oil 0.5%S
          description: Full fuel name
        price:
          type: number
          format: float
          example: 682.5
          description: Price in USD per metric ton
        formatted:
          type: string
          example: "$682.50"
          description: Formatted price string
        currency:
          type: string
          example: USD
          description: Price currency
        unit:
          type: string
          example: metric_ton
          description: Price unit
        source:
          type: string
          example: market_reporting
          description: Data source
        timestamp:
          type: string
          format: date-time
          example: '2025-08-05T00:32:05.928Z'
          description: Price update timestamp
    RigCountLatestResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            code:
              type: string
              example: US_RIG_COUNT
            region:
              type: string
              example: United States
            count:
              type: integer
              example: 540
            unit:
              type: string
              example: rigs
            source:
              type: string
              example: baker_hughes
            created_at:
              type: string
              format: date-time
              example: '2025-08-02T20:15:00Z'
            week_over_week_change:
              type: integer
              example: -5
            year_over_year_change:
              type: integer
              example: 45
    RigCountHistoricalResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        rig_counts:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
                example: US_RIG_COUNT
              region:
                type: string
                example: United States
              count:
                type: integer
                example: 540
              unit:
                type: string
                example: rigs
              source:
                type: string
                example: baker_hughes
              created_at:
                type: string
                format: date-time
                example: '2025-08-02T20:15:00Z'
        meta:
          "$ref": "#/components/schemas/PaginationMeta"
    DrillingIntelligenceSummaryResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          required:
          - rig_counts
          - frac_spread_count
          - well_permits
          - duc_wells_total
          - deltas
          - last_updated
          properties:
            rig_counts:
              type: object
              additionalProperties:
                type: integer
              example:
                US_RIG_COUNT: 587
                CANADA_RIG_COUNT: 204
                INTERNATIONAL_RIG_COUNT: 1073
            frac_spread_count:
              type: integer
              nullable: true
              example: 196
            well_permits:
              type: object
              properties:
                last_30d:
                  type: integer
                  example: 671
                by_state:
                  type: object
                  additionalProperties:
                    type: integer
            duc_wells_total:
              type: integer
              example: 2421
            deltas:
              type: object
              additionalProperties: true
            last_updated:
              type: string
              format: date-time
              nullable: true
              example: '2026-07-27T00:00:00Z'
    FracSpreadsResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          required:
          - frac_spreads
          - summary
          properties:
            frac_spreads:
              type: array
              items:
                "$ref": "#/components/schemas/DrillingDataPoint"
            summary:
              type: object
              properties:
                national_count:
                  type: integer
                  nullable: true
                  example: 196
                by_basin:
                  type: object
                  additionalProperties:
                    type: number
                last_updated:
                  type: string
                  format: date-time
                  nullable: true
    WellPermitsResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          required:
          - well_permits
          - summary
          - pagination
          properties:
            well_permits:
              type: array
              items:
                type: object
                properties:
                  api_number:
                    type: string
                  state:
                    type: string
                    example: TX
                  county:
                    type: string
                    nullable: true
                  operator:
                    type: string
                    nullable: true
                  permit_number:
                    type: string
                    nullable: true
                  permit_type:
                    type: string
                    nullable: true
                  permit_status:
                    type: string
                    nullable: true
                  permit_date:
                    type: string
                    format: date
                    nullable: true
                  approval_date:
                    type: string
                    format: date
                    nullable: true
                  spud_date:
                    type: string
                    format: date
                    nullable: true
                  well_name:
                    type: string
                    nullable: true
                  latitude:
                    type: number
                    nullable: true
                  longitude:
                    type: number
                    nullable: true
            summary:
              type: object
              properties:
                total:
                  type: integer
                by_state:
                  type: object
                  additionalProperties:
                    type: integer
                days:
                  type: integer
                last_updated:
                  type: string
                  format: date-time
                  nullable: true
            pagination:
              type: object
              properties:
                page:
                  type: integer
                per_page:
                  type: integer
                total:
                  type: integer
                total_pages:
                  type: integer
    DrillingDataPoint:
      type: object
      required:
      - code
      - name
      - value
      - unit
      - source
      - created_at
      - formatted_date
      properties:
        code:
          type: string
          example: US_RIG_COUNT
        name:
          type: string
          example: US Rig Count
        value:
          type: number
          example: 540
        unit:
          type: string
          example: rigs
        source:
          type: string
          example: Baker Hughes
        created_at:
          type: string
          format: date-time
          example: '2026-07-27T00:00:00Z'
        formatted_date:
          type: string
          example: 2026-07-27 00:00:00 UTC
    DrillingBasinSeriesResponse:
      type: object
      required:
      - status
      - data
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          required:
          - summary
          properties:
            duc_wells:
              type: array
              items:
                "$ref": "#/components/schemas/DrillingDataPoint"
            completions:
              type: array
              items:
                "$ref": "#/components/schemas/DrillingDataPoint"
            wells_drilled:
              type: array
              items:
                "$ref": "#/components/schemas/DrillingDataPoint"
            summary:
              type: object
              required:
              - total
              - by_basin
              - last_updated
              properties:
                total:
                  type: number
                  example: 2815
                by_basin:
                  type: object
                  additionalProperties:
                    type: number
                  example:
                    PERMIAN: 893
                    BAKKEN: 420
                last_updated:
                  type: string
                  format: date-time
                  nullable: true
    WebhookListResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        webhooks:
          type: array
          items:
            "$ref": "#/components/schemas/Webhook"
        meta:
          "$ref": "#/components/schemas/PaginationMeta"
    WebhookResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        webhook:
          "$ref": "#/components/schemas/Webhook"
    Webhook:
      type: object
      properties:
        id:
          type: string
          example: wh_1a2b3c4d5e6f
        url:
          type: string
          format: uri
          example: https://api.yourcompany.com/webhooks/oilpriceapi
        events:
          type: array
          items:
            type: string
            enum:
            - price.updated
            - price.significant_change
            - drilling.rig_count.updated
            - drilling.frac_spread.updated
            - drilling.well_permit.updated
            - drilling.duc_well.updated
            - api.limit.warning
            - api.limit.exceeded
          example:
          - price.updated
          - drilling.rig_count.updated
        secret:
          type: string
          example: whsec_1234567890abcdef
          description: HMAC signing secret for verification
        active:
          type: boolean
          example: true
        created_at:
          type: string
          format: date-time
          example: '2025-08-10T10:30:00Z'
        updated_at:
          type: string
          format: date-time
          example: '2025-08-10T10:30:00Z'
        last_delivery:
          type: object
          properties:
            attempted_at:
              type: string
              format: date-time
              example: '2025-08-10T12:00:00Z'
            status:
              type: string
              enum:
              - success
              - failed
              - pending
              example: success
            response_code:
              type: integer
              example: 200
    CreateWebhookRequest:
      type: object
      required:
      - url
      - events
      properties:
        url:
          type: string
          format: uri
          example: https://api.yourcompany.com/webhooks/oilpriceapi
          description: Webhook endpoint URL (must be HTTPS)
        events:
          type: array
          minItems: 1
          items:
            type: string
            enum:
            - price.updated
            - price.significant_change
            - drilling.rig_count.updated
            - drilling.frac_spread.updated
            - drilling.well_permit.updated
            - drilling.duc_well.updated
            - api.limit.warning
            - api.limit.exceeded
          example:
          - price.updated
          - drilling.rig_count.updated
          description: Events to subscribe to
        description:
          type: string
          example: Production webhook for price updates
          description: Optional description for the webhook
    UpdateWebhookRequest:
      type: object
      properties:
        url:
          type: string
          format: uri
          example: https://api.yourcompany.com/webhooks/oilpriceapi
          description: Webhook endpoint URL (must be HTTPS)
        events:
          type: array
          items:
            type: string
            enum:
            - price.updated
            - price.significant_change
            - drilling.rig_count.updated
            - drilling.frac_spread.updated
            - drilling.well_permit.updated
            - drilling.duc_well.updated
            - api.limit.warning
            - api.limit.exceeded
          example:
          - price.updated
          - drilling.rig_count.updated
          description: Events to subscribe to
        active:
          type: boolean
          example: true
          description: Enable or disable the webhook
        description:
          type: string
          example: Production webhook for price updates
          description: Optional description for the webhook
    InsufficientPlanError:
      type: object
      properties:
        status:
          type: string
          example: error
        error:
          type: object
          properties:
            code:
              type: string
              example: INSUFFICIENT_PLAN
            message:
              type: string
              example: Drilling intelligence data is available exclusively to Scale
                subscribers
            details:
              type: object
              properties:
                required_tier:
                  type: string
                  example: reservoir_mastery
                upgrade_url:
                  type: string
                  example: https://oilpriceapi.com/pricing
                current_plan:
                  type: string
                  example: free
    PaginationMeta:
      type: object
      properties:
        current_page:
          type: integer
          example: 1
        per_page:
          type: integer
          example: 100
        total_pages:
          type: integer
          example: 5
        total_count:
          type: integer
          example: 450
        next_page:
          type: integer
          nullable: true
          example: 2
        prev_page:
          type: integer
          nullable: true
          example: 
    AllPricesResponse:
      type: object
      description: |
        Returns all commodity prices in a single response. Prices are indexed by commodity code
        for O(1) lookup. Includes 24-hour price change data when available (calculated by
        the most recently available calculation).
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            prices:
              type: object
              description: Commodity prices indexed by code (e.g., BRENT_CRUDE_USD,
                WTI_USD)
              additionalProperties:
                "$ref": "#/components/schemas/Price"
              example:
                BRENT_CRUDE_USD:
                  code: BRENT_CRUDE_USD
                  price: 59.76
                  currency: USD
                  updated_at: '2025-12-17T16:03:13Z'
                  change_24h: 0.74
                  change_24h_percent: 1.25
                WTI_USD:
                  code: WTI_USD
                  price: 56.04
                  currency: USD
                  updated_at: '2025-12-17T16:07:01Z'
                  change_24h: 0.59
                  change_24h_percent: 1.06
            count:
              type: integer
              description: Number of commodities returned
              example: 42
            timestamp:
              type: string
              format: date-time
              description: Server timestamp when response was generated
            cached_at:
              type: string
              format: date-time
              description: When the data was cached; evaluate freshness using response
                timestamps and metadata
        metadata:
          type: object
          description: Additional metadata (only included when include_metadata=true)
          properties:
            categories:
              type: array
              items:
                type: string
              example:
              - oil
              - gas
              - metals
              - forex
            data_sources:
              type: integer
              example: 12
    DataHealthResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            fresh:
              type: array
              items:
                type: string
              example:
              - WTI_USD
              - BRENT_CRUDE_USD
            stale:
              type: array
              items:
                type: string
              example:
              - COAL_USD
            last_update:
              type: string
              format: date-time
    CushingStorageResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            current_storage:
              type: number
              example: 42500000
              description: Current storage in barrels
            capacity:
              type: number
              example: 76000000
              description: Total capacity in barrels
            utilization:
              type: number
              example: 55.92
              description: Utilization percentage
            week_change:
              type: number
              example: -1250000
              description: Week-over-week change in barrels
            month_change:
              type: number
              example: -3500000
              description: Month-over-month change in barrels
            market_signal:
              type: string
              enum:
              - bullish
              - bearish
              - neutral
              example: bullish
            trend:
              type: string
              enum:
              - building
              - drawing
              - stable
              example: drawing
            updated_at:
              type: string
              format: date-time
    BrentFuturesResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            spot:
              type: number
              example: 82.45
            contracts:
              type: array
              items:
                type: object
                properties:
                  month:
                    type: string
                    example: M1
                  contract_date:
                    type: string
                    example: 2025-02
                  price:
                    type: number
                    example: 82.3
                  volume:
                    type: integer
                    example: 125000
                  open_interest:
                    type: integer
                    example: 450000
            curve_structure:
              type: string
              enum:
              - contango
              - backwardation
              - flat
              example: backwardation
            updated_at:
              type: string
              format: date-time
    WtiFuturesResponse:
      type: object
      properties:
        commodity:
          type: string
          example: WTI_FUTURES
        source:
          type: string
          example: market_reporting
        updated_at:
          type: string
          format: date-time
        trading_hours:
          type: string
          example: 01:00-23:00 GMT
        contracts:
          type: array
          items:
            type: object
            properties:
              contract_month:
                type: string
                example: 2026-04
              last_price:
                type: number
                example: 61.0
              currency:
                type: string
                example: USD
              days_to_expiry:
                type: integer
                example: 35
              contract_status:
                type: string
                description: Contract lifecycle state. "expired" is returned only
                  by historical/OHLC endpoints; the live curve filters expired contracts
                  out.
                enum:
                - front_month
                - near_expiry
                - active
                - expired
                example: front_month
              is_front_month:
                type: boolean
                example: true
              expiry_date:
                type: string
                format: date
                example: '2026-02-27'
              updated_at:
                type: string
                format: date-time
        metadata:
          type: object
          properties:
            total_contracts:
              type: integer
              example: 13
            front_month_contract:
              type: string
              example: 2026-04
            data_source:
              type: string
              description: Customer-safe machine label for the data source category.
                Aggregated market data is labeled "market_reporting"; government/official
                sources (e.g. EIA) are named. The underlying collection source is
                tracked internally on the `prices.source` column.
              example: market_reporting
            enhanced_data:
              type: boolean
              example: true
    NatGasFuturesResponse:
      type: object
      properties:
        commodity:
          type: string
          example: NATURAL_GAS_FUTURES
        source:
          type: string
          example: market_reporting
        updated_at:
          type: string
          format: date-time
        contracts:
          type: array
          items:
            type: object
            properties:
              contract_month:
                type: string
                example: 2026-03
              last_price:
                type: number
                example: 3.45
              currency:
                type: string
                example: USD
              unit:
                type: string
                example: MMBtu
              days_to_expiry:
                type: integer
                example: 28
              contract_status:
                type: string
                description: Contract lifecycle state. "expired" is returned only
                  by historical/OHLC endpoints; the live curve filters expired contracts
                  out.
                enum:
                - front_month
                - near_expiry
                - active
                - expired
                example: front_month
              is_front_month:
                type: boolean
                example: true
              expiry_date:
                type: string
                format: date
              updated_at:
                type: string
                format: date-time
        metadata:
          type: object
          properties:
            total_contracts:
              type: integer
            front_month_contract:
              type: string
            data_source:
              type: string
            enhanced_data:
              type: boolean
    HistoricalFuturesResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              contract_month:
                type: string
                example: M1
              price:
                type: number
                example: 82.45
              volume:
                type: integer
              open_interest:
                type: integer
    FuturesSpreadsResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              spread:
                type: string
                example: M1-M2
              value:
                type: number
                example: 0.15
              percentage:
                type: number
                example: 0.18
    MarineFuelsResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              port_code:
                type: string
                example: SINGAPORE
              port_name:
                type: string
                example: Singapore
              prices:
                type: object
                properties:
                  VLSFO:
                    type: number
                    example: 685
                  HFO_380:
                    type: number
                    example: 545
                  MGO:
                    type: number
                    example: 875
              currency:
                type: string
                example: USD
              unit:
                type: string
                example: per MT
              updated_at:
                type: string
                format: date-time
    MarineFuelLatestResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            port_code:
              type: string
              example: SINGAPORE
            fuel_type:
              type: string
              example: VLSFO
            price:
              type: number
              example: 685
            currency:
              type: string
              example: USD
            unit:
              type: string
              example: per MT
            week_change:
              type: number
              example: 15
            month_change:
              type: number
              example: -25
            updated_at:
              type: string
              format: date-time
    MarineFuelHistoricalResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              price:
                type: number
                example: 685
              volume:
                type: integer
                nullable: true
    PaymentRequiredResponse:
      type: object
      description: |
        Returned when a free-tier user has exhausted their daily request limit.
        AI agents should interpret this as "upgrade required to continue" (not "retry later").
        Paid users who exceed their limit receive 429 Too Many Requests instead.
      properties:
        error:
          type: string
          example: Payment Required
        error_code:
          type: string
          example: PAYMENT_REQUIRED
        message:
          type: string
          example: You've used all 50 requests for Free tier today
        current_usage:
          type: object
          properties:
            used:
              type: integer
              example: 50
            limit:
              type: integer
              example: 50
            remaining:
              type: integer
              example: 0
            tier:
              type: string
              example: free
        upgrade_options:
          type: array
          items:
            type: object
            properties:
              plan:
                type: string
                example: exploration
              price:
                type: integer
                description: Price in cents (USD)
                example: 1500
              currency:
                type: string
                example: usd
              requests:
                type: integer
                example: 10000
              checkout_url:
                type: string
                example: https://www.oilpriceapi.com/pricing
        docs:
          type: string
          example: https://docs.oilpriceapi.com/billing
