# GENERATED FILE — do not edit by hand.
# Synced from https://api.oilpriceapi.com/swagger.yaml by scripts/inject-openapi.js (prebuild).
# Upstream is authoritative. Only paths in PRESERVE_ALLOWLIST survive if
# upstream omits them; anything else upstream drops is dropped here too.
openapi: 3.0.3
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 API
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
        '400':
          description: Missing or invalid code, date, interval, or relative window.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailErrorResponse'
        '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'
        '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'
        '401':
          description: Unauthorized - Invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Port not found
          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'
        '401':
          description: Unauthorized - 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/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'
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsufficientPlanError'
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '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'
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsufficientPlanError'
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '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
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsufficientPlanError'
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
    patch:
      summary: Partially update webhook endpoint
      tags:
        - Webhooks
      description: |
        Partially 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'
        '403':
          description: Insufficient plan - Scale required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsufficientPlanError'
        '404':
          description: Webhook not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      operationId: patchV1WebhooksByWebhookId
  /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
  /v1/futures/ice-brent/historical:
    get:
      summary: Get historical ICE Brent futures data
      tags:
        - Futures
        - Premium
      parameters:
        - name: contract_month
          in: query
          required: false
          description: Specific contract month (e.g., "M1", "M2")
          schema:
            type: string
        - name: period
          in: query
          required: false
          description: Time period
          schema:
            type: string
            enum:
              - 1d
              - 1w
              - 1m
              - 3m
              - 1y
            default: 1w
        - name: interval
          in: query
          required: false
          description: Data interval for historical data
          schema:
            type: string
            enum:
              - hourly
              - daily
              - weekly
              - monthly
            default: daily
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HistoricalFuturesResponse'
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesIceBrentHistorical
      description: Get historical ICE Brent futures data
  /v1/futures/ice-brent/spreads:
    get:
      summary: Get ICE Brent calendar spreads
      tags:
        - Futures
        - Premium
      description: Calendar spread analysis between contract months
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures spreads data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FuturesSpreadsResponse'
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesIceBrentSpreads
  /v1/prices/excel-latest:
    get:
      summary: Excel latest-price gateway
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Spreadsheet-shaped latest-price response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesExcelLatest
      description: Excel latest-price gateway
  /v1/prices/crude-oil:
    get:
      summary: Crude oil latest-price helper
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Crude oil price response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesCrudeOil
      description: Crude oil latest-price helper
  /v1/prices/data-connector:
    get:
      summary: Data connector price payload
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Data connector response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesDataConnector
      description: Data connector price payload
  /v1/prices/history:
    get:
      summary: Legacy price history surface
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical price response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesHistory
      description: Legacy price history surface
  /v1/prices/metrics:
    get:
      summary: Price API metrics
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Metrics response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesMetrics
      description: Price API metrics
  /v1/prices/widget:
    get:
      summary: General price widget payload
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Widget response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesWidget
      description: General price widget payload
  /v1/prices/widget/diesel:
    get:
      summary: Diesel widget payload
      tags:
        - Prices
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Diesel widget response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesWidgetDiesel
      description: Diesel widget payload
  /v1/prices/widget/ping:
    get:
      summary: Widget health check
      tags:
        - Prices
      responses:
        '200':
          description: Widget service health response
      operationId: getV1PricesWidgetPing
      description: Widget health check
      security: []
  /v1/prices/marine-fuels/ports:
    get:
      summary: Marine fuel port list
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Marine fuel ports response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1PricesMarineFuelsPorts
      description: Marine fuel port list
  /v1/natural-gas/storage:
    get:
      summary: Natural gas storage
      tags:
        - Natural Gas
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Natural gas storage response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1NaturalGasStorage
      description: Natural gas storage
  /v1/futures/eua-carbon:
    get:
      summary: EUA carbon futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbon
      description: EUA carbon futures
  /v1/futures/eua-carbon/historical:
    get:
      summary: EUA carbon historical futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonHistorical
      description: EUA carbon historical futures
  /v1/futures/eua-carbon/ohlc:
    get:
      summary: EUA carbon OHLC
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OHLC response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonOhlc
      description: EUA carbon OHLC
  /v1/futures/eua-carbon/intraday:
    get:
      summary: EUA carbon intraday futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Intraday futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonIntraday
      description: EUA carbon intraday futures
  /v1/futures/eua-carbon/spreads:
    get:
      summary: EUA carbon calendar spreads
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Calendar spread response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonSpreads
      description: EUA carbon calendar spreads
  /v1/futures/eua-carbon/curve:
    get:
      summary: EUA carbon futures curve
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures curve response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonCurve
      description: EUA carbon futures curve
  /v1/futures/eua-carbon/spread-history:
    get:
      summary: EUA carbon spread history
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Spread history response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuaCarbonSpreadHistory
      description: EUA carbon spread history
  /v1/futures/eu-carbon:
    get:
      summary: EU carbon futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbon
      description: EU carbon futures
  /v1/futures/eu-carbon/historical:
    get:
      summary: EU carbon historical futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonHistorical
      description: EU carbon historical futures
  /v1/futures/eu-carbon/ohlc:
    get:
      summary: EU carbon OHLC
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OHLC response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonOhlc
      description: EU carbon OHLC
  /v1/futures/eu-carbon/intraday:
    get:
      summary: EU carbon intraday futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Intraday futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonIntraday
      description: EU carbon intraday futures
  /v1/futures/eu-carbon/spreads:
    get:
      summary: EU carbon calendar spreads
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Calendar spread response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonSpreads
      description: EU carbon calendar spreads
  /v1/futures/eu-carbon/curve:
    get:
      summary: EU carbon futures curve
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures curve response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonCurve
      description: EU carbon futures curve
  /v1/futures/eu-carbon/spread-history:
    get:
      summary: EU carbon spread history
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Spread history response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesEuCarbonSpreadHistory
      description: EU carbon spread history
  /v1/futures/ttf-gas:
    get:
      summary: TTF gas futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGas
      description: TTF gas futures
  /v1/futures/ttf-gas/historical:
    get:
      summary: TTF gas historical futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasHistorical
      description: TTF gas historical futures
  /v1/futures/ttf-gas/curve:
    get:
      summary: TTF gas futures curve
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures curve response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasCurve
      description: TTF gas futures curve
  /v1/futures/ttf-gas/ohlc:
    get:
      summary: TTF gas OHLC
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OHLC response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasOhlc
      description: TTF gas OHLC
  /v1/futures/ttf-gas/intraday:
    get:
      summary: TTF gas intraday futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Intraday futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasIntraday
      description: TTF gas intraday futures
  /v1/futures/ttf-gas/spreads:
    get:
      summary: TTF gas calendar spreads
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Calendar spread response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasSpreads
      description: TTF gas calendar spreads
  /v1/futures/ttf-gas/spread-history:
    get:
      summary: TTF gas spread history
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Spread history response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesTtfGasSpreadHistory
      description: TTF gas spread history
  /v1/futures/lng-jkm:
    get:
      summary: LNG JKM futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkm
      description: LNG JKM futures
  /v1/futures/lng-jkm/historical:
    get:
      summary: LNG JKM historical futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmHistorical
      description: LNG JKM historical futures
  /v1/futures/lng-jkm/curve:
    get:
      summary: LNG JKM futures curve
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures curve response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmCurve
      description: LNG JKM futures curve
  /v1/futures/lng-jkm/ohlc:
    get:
      summary: LNG JKM OHLC
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OHLC response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmOhlc
      description: LNG JKM OHLC
  /v1/futures/lng-jkm/intraday:
    get:
      summary: LNG JKM intraday futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Intraday futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmIntraday
      description: LNG JKM intraday futures
  /v1/futures/lng-jkm/spreads:
    get:
      summary: LNG JKM calendar spreads
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Calendar spread response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmSpreads
      description: LNG JKM calendar spreads
  /v1/futures/lng-jkm/spread-history:
    get:
      summary: LNG JKM spread history
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Spread history response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesLngJkmSpreadHistory
      description: LNG JKM spread history
  /v1/futures/uk-carbon:
    get:
      summary: UK carbon futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesUkCarbon
      description: UK carbon futures
  /v1/futures/uk-carbon/historical:
    get:
      summary: UK carbon historical futures
      tags:
        - Futures
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Historical futures response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1FuturesUkCarbonHistorical
      description: UK carbon historical futures
  /v1/bunker-fuels/all:
    get:
      summary: Bunker fuel bundle
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Bunker fuel response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1BunkerFuelsAll
      description: Bunker fuel bundle
  /v1/bunker-fuels/compare:
    get:
      summary: Compare bunker fuel prices
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Bunker comparison response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1BunkerFuelsCompare
      description: Compare bunker fuel prices
  /v1/bunker-fuels/export:
    get:
      summary: Export bunker fuel data
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Bunker export response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1BunkerFuelsExport
      description: Export bunker fuel data
  /v1/bunker-fuels/spreads/ports:
    get:
      summary: Bunker fuel port spreads
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Port spread response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1BunkerFuelsSpreadsPorts
      description: Bunker fuel port spreads
  /v1/maritime-fuels/bundle:
    get:
      summary: Maritime fuels bundle
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Maritime fuels bundle response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1MaritimeFuelsBundle
      description: Maritime fuels bundle
  /v1/maritime-fuels/historical:
    get:
      summary: Maritime fuels historical bundle
      tags:
        - Marine Fuels
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Maritime fuels historical response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1MaritimeFuelsHistorical
      description: Maritime fuels historical bundle
  /v1/indicators/congressional-trades:
    get:
      summary: Congressional trade indicators
      tags:
        - Indicators
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Congressional trade indicator response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1IndicatorsCongressionalTrades
      description: Congressional trade indicators
  /v1/benchmarks/close:
    get:
      summary: Benchmarks close
      tags:
        - Premium
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Benchmarks close response
        '403':
          description: Feature is sales-gated or not enabled for this account
      operationId: getV1BenchmarksClose
      description: Benchmarks close
  /v1/aviation-fuel/pilot:
    get:
      summary: Aviation fuel pilot
      tags:
        - Premium
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Aviation fuel pilot response
        '403':
          description: Feature is sales-gated or not enabled for this account
      operationId: getV1AviationFuelPilot
      description: Aviation fuel pilot
  /v1/webhooks/{webhook_id}/events:
    parameters:
      - name: webhook_id
        in: path
        required: true
        description: Webhook endpoint ID
        schema:
          type: string
          example: wh_123
    get:
      summary: Webhook event history
      tags:
        - Webhooks
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Webhook event history response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1WebhooksByWebhookIdEvents
      description: Webhook event history
  /v1/webhooks/{webhook_id}/test:
    parameters:
      - name: webhook_id
        in: path
        required: true
        description: Webhook endpoint ID
        schema:
          type: string
          example: wh_123
    post:
      summary: Send a webhook test event
      tags:
        - Webhooks
      security:
        - ApiKeyAuth: []
      responses:
        '202':
          description: Test webhook event accepted
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1WebhooksByWebhookIdTest
      description: Send a webhook test event
  /v1/alerts:
    get:
      summary: List alerts
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert list response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1Alerts
      description: List alerts
    post:
      summary: Create alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '201':
          description: Alert created
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1Alerts
      description: Create alert
  /v1/alerts/{alert_id}:
    parameters:
      - name: alert_id
        in: path
        required: true
        description: Alert ID
        schema:
          type: string
          example: alert_123
    get:
      summary: Get alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1AlertsByAlertId
      description: Get alert
    put:
      summary: Update alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert updated
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: putV1AlertsByAlertId
      description: Update alert
    patch:
      summary: Partially update alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert updated
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: patchV1AlertsByAlertId
      description: Partially update alert
    delete:
      summary: Delete alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '204':
          description: Alert deleted
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: deleteV1AlertsByAlertId
      description: Delete alert
  /v1/alerts/{alert_id}/test:
    parameters:
      - name: alert_id
        in: path
        required: true
        description: Alert ID
        schema:
          type: string
          example: alert_123
    post:
      summary: Test alert
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '202':
          description: Alert test accepted
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1AlertsByAlertIdTest
      description: Test alert
  /v1/alerts/test:
    post:
      summary: Test alert conditions
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert test response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1AlertsTest
      description: Test alert conditions
  /v1/alerts/analytics_history:
    get:
      summary: Alert analytics history
      tags:
        - Alerts
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Alert analytics response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1AlertsAnalyticsUnderscoreHistory
      description: Alert analytics history
  /v1/alerts/triggers:
    get:
      summary: Deprecated alert triggers endpoint
      tags:
        - Alerts
      deprecated: true
      security:
        - ApiKeyAuth: []
      responses:
        '410':
          description: Gone; use alerts, analytics history, and webhook delivery events
      operationId: getV1AlertsTriggers
      description: Deprecated alert triggers endpoint
  /v1/api-keys/{key_id}:
    parameters:
      - name: key_id
        in: path
        required: true
        description: API key ID
        schema:
          type: string
          example: key_123
    delete:
      summary: Revoke API key
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '204':
          description: API key revoked
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: deleteV1ApiKeysByKeyId
      description: Revoke API key
  /v1/api-keys/{key_id}/roll:
    parameters:
      - name: key_id
        in: path
        required: true
        description: API key ID
        schema:
          type: string
          example: key_123
    post:
      summary: Roll API key
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '201':
          description: Replacement API key created
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1ApiKeysByKeyIdRoll
      description: Roll API key
  /v1/subscriptions/{subscription_id}:
    parameters:
      - name: subscription_id
        in: path
        required: true
        description: Subscription ID
        schema:
          type: string
          example: sub_123
    get:
      summary: Get subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Subscription response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1SubscriptionsBySubscriptionId
      description: Get subscription
    put:
      summary: Update subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Subscription updated
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: putV1SubscriptionsBySubscriptionId
      description: Update subscription
    patch:
      summary: Partially update subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Subscription updated
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: patchV1SubscriptionsBySubscriptionId
      description: Partially update subscription
    delete:
      summary: Cancel subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '204':
          description: Subscription canceled
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: deleteV1SubscriptionsBySubscriptionId
      description: Cancel subscription
  /v1/subscriptions/{subscription_id}/pause:
    parameters:
      - name: subscription_id
        in: path
        required: true
        description: Subscription ID
        schema:
          type: string
          example: sub_123
    post:
      summary: Pause subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Subscription paused
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1SubscriptionsBySubscriptionIdPause
      description: Pause subscription
  /v1/subscriptions/{subscription_id}/resume:
    parameters:
      - name: subscription_id
        in: path
        required: true
        description: Subscription ID
        schema:
          type: string
          example: sub_123
    post:
      summary: Resume subscription
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Subscription resumed
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1SubscriptionsBySubscriptionIdResume
      description: Resume subscription
  /v1/users/health:
    get:
      summary: Account user health
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: User health response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1UsersHealth
      description: Account user health
  /v1/users/activate-trial:
    post:
      summary: Activate trial
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Trial activation response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: postV1UsersActivateTrial
      description: Activate trial
  /v1/organizations/{organization_id}/dashboard:
    parameters:
      - name: organization_id
        in: path
        required: true
        description: Organization ID
        schema:
          type: string
          example: org_123
    get:
      summary: Organization dashboard
      tags:
        - Account
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Organization dashboard response
        '401':
          description: Unauthorized — missing or invalid API key
      operationId: getV1OrganizationsByOrganizationIdDashboard
      description: Organization dashboard
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'API key as: Authorization: Token YOUR_API_KEY'
    JWTAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token authentication for user management endpoints
  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: null
    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
              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
    DrillingIntelligenceResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        drilling_intelligence:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
                example: US_RIG_COUNT
              name:
                type: string
                example: US Rig Count
              type:
                type: string
                example: rig_count
                enum:
                  - rig_count
                  - frac_spread
                  - well_permit
                  - duc_well
              region:
                type: string
                example: United States
              value:
                type: integer
                example: 622
              unit:
                type: string
                example: rigs
              currency:
                type: string
                example: COUNT
              source:
                type: string
                example: baker_hughes
              created_at:
                type: string
                format: date-time
                example: '2025-07-15T18:00:00.000Z'
              formatted_date:
                type: string
                example: 2025-07-15 18:00:00 UTC
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    BasinDrillingDataResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        basin:
          type: string
          example: permian
        data:
          type: object
          properties:
            rig_counts:
              type: array
              items:
                $ref: '#/components/schemas/DrillingDataPoint'
            frac_spreads:
              type: array
              items:
                $ref: '#/components/schemas/DrillingDataPoint'
            well_permits:
              type: array
              items:
                $ref: '#/components/schemas/DrillingDataPoint'
            duc_wells:
              type: array
              items:
                $ref: '#/components/schemas/DrillingDataPoint'
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    DrillingTrendsResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        type:
          type: string
          example: all
        period:
          type: string
          example: 6months
        trends:
          type: object
          properties:
            rig_counts:
              type: object
              properties:
                current:
                  type: integer
                  example: 540
                change:
                  type: integer
                  example: 45
                change_percent:
                  type: number
                  example: 9.1
                trend:
                  type: string
                  example: increasing
            frac_spreads:
              type: object
              properties:
                current:
                  type: integer
                  example: 200
                change:
                  type: integer
                  example: 15
                change_percent:
                  type: number
                  example: 8.1
                trend:
                  type: string
                  example: increasing
    DucWellsResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              basin:
                type: string
                example: PERMIAN
              duc_count:
                type: integer
                example: 893
              month_change:
                type: integer
                example: -45
              completion_rate:
                type: number
                example: 72.5
                description: Percentage of wells being completed
    DrillingOverviewResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: object
          properties:
            rig_count:
              type: object
              properties:
                total:
                  type: integer
                  example: 621
                oil:
                  type: integer
                  example: 479
                gas:
                  type: integer
                  example: 138
                misc:
                  type: integer
                  example: 4
                week_change:
                  type: integer
                  example: -5
                month_change:
                  type: integer
                  example: 12
            duc_wells:
              type: object
              properties:
                total:
                  type: integer
                  example: 4523
                permian:
                  type: integer
                  example: 893
                eagle_ford:
                  type: integer
                  example: 345
                bakken:
                  type: integer
                  example: 328
                month_change:
                  type: integer
                  example: -125
            updated_at:
              type: string
              format: date-time
    RigCountResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              region:
                type: string
                example: PERMIAN
              oil_rigs:
                type: integer
                example: 303
              gas_rigs:
                type: integer
                example: 12
              misc_rigs:
                type: integer
                example: 1
              total:
                type: integer
                example: 316
              week_change:
                type: integer
                example: -2
    DrillingHistoricalResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              value:
                type: integer
                example: 621
              metric:
                type: string
                example: rig_count
