Developer guide

OilPriceAPI with Python

Start with one authenticated Brent request, verify the returned source timestamp, then build outward from the canonical quickstart.

Runtime

Python 3.8+

Environment

OILPRICEAPI_KEY

Authentication

Authorization: Token YOUR_API_KEY

First request

/v1/prices/latest?by_code=BRENT_CRUDE_USD

First request

Prove the API path first

Store the key as OILPRICEAPI_KEY and run the request from a trusted server process. Do not expose the key in browser bundles, logs, notebooks, or shared documents.

No test-key prefix

OilPriceAPI does not issue special test keys. Use the keyless demo endpoint or fixtures for tests; keep customer keys out of CI.

python -m pip install oilpriceapi
#!/usr/bin/env python3
import json
import os
from typing import Dict, Union

from oilpriceapi import OilPriceAPI


def run() -> Dict[str, Union[str, None]]:
    with OilPriceAPI(
        api_key=os.environ["OILPRICEAPI_KEY"],
        base_url=os.environ.get("OILPRICEAPI_BASE_URL"),
        max_retries=1,
    ) as client:
        price = client.prices.get("BRENT_CRUDE_USD")

    return {
        "commodity": price.commodity,
        "currency": price.currency,
        "value_type": type(price.value).__name__,
        "timestamp_type": type(price.timestamp).__name__,
    }


if __name__ == "__main__":
    print(json.dumps(run(), sort_keys=True))

This exact example is exercised by the official SDK's fixture and guarded production CI.

Universal curl

Compare your client with the contract

curl "https://api.oilpriceapi.com/v1/prices/latest?by_code=BRENT_CRUDE_USD" \
  -H "Authorization: Token YOUR_API_KEY"

Expected shape

Read the timestamp from the response

{
  "status": "success",
  "data": {
    "code": "BRENT_CRUDE_USD",
    "price": 78.41,
    "currency": "USD",
    "created_at": "2026-03-09T12:00:00.000Z",
    "type": "spot_price"
  }
}

Keyless first touch

Use demo data before signup

The demo route is the supported no-key path. It is rate limited and intentionally narrower than authenticated, account-entitled access.

curl "https://api.oilpriceapi.com/v1/demo/prices"
Open demo response

Recover without guessing

ResultNext action
401Check that the header is exactly Authorization: Token YOUR_API_KEY.
402 / 403The dataset may require a plan or account entitlement. Check pricing or contact support.
429Read the rate-limit response and retry after the indicated reset; do not loop immediately.
Timeout / 5xxUse a bounded timeout and exponential backoff. Keep the last valid source timestamp visible.

Executable recovery paths

Handle API failures by type

401Invalid or missing credentialView code
GET /v1/prices/latestTested SDK source
#!/usr/bin/env python3
import json
import os
from typing import Dict, Union

from oilpriceapi import AuthenticationError, OilPriceAPI


def run() -> Dict[str, Union[bool, int]]:
    try:
        with OilPriceAPI(
            api_key=os.environ["OILPRICEAPI_KEY"],
            base_url=os.environ.get("OILPRICEAPI_BASE_URL"),
            max_retries=1,
        ) as client:
            client.prices.get("BRENT_CRUDE_USD")
    except AuthenticationError as error:
        return {"handled": True, "status_code": error.status_code or 401}

    raise RuntimeError("Expected the API to reject the credential")


if __name__ == "__main__":
    print(json.dumps(run(), sort_keys=True))
403Dataset entitlementView code
GET /v1/prices/latestTested SDK source
#!/usr/bin/env python3
import json
import os
from typing import Dict, Union

from oilpriceapi import OilPriceAPI, OilPriceAPIError


def run() -> Dict[str, Union[bool, int]]:
    try:
        with OilPriceAPI(
            api_key=os.environ["OILPRICEAPI_KEY"],
            base_url=os.environ.get("OILPRICEAPI_BASE_URL"),
            max_retries=1,
        ) as client:
            client.prices.get("BRENT_CRUDE_USD")
    except OilPriceAPIError as error:
        if error.status_code != 403:
            raise
        return {"handled": True, "status_code": error.status_code}

    raise RuntimeError("Expected the API to reject the account entitlement")


if __name__ == "__main__":
    print(json.dumps(run(), sort_keys=True))
429Request limit reachedView code
GET /v1/prices/latestTested SDK source
#!/usr/bin/env python3
import json
import os
from typing import Dict, Union

from oilpriceapi import OilPriceAPI, RateLimitError


def run() -> Dict[str, Union[bool, int]]:
    try:
        with OilPriceAPI(
            api_key=os.environ["OILPRICEAPI_KEY"],
            base_url=os.environ.get("OILPRICEAPI_BASE_URL"),
            max_retries=1,
        ) as client:
            client.prices.get("BRENT_CRUDE_USD")
    except RateLimitError as error:
        return {"handled": True, "status_code": error.status_code or 429}

    raise RuntimeError("Expected the API to enforce its request limit")


if __name__ == "__main__":
    print(json.dumps(run(), sort_keys=True))
TimeoutBounded timeoutView code
GET /v1/prices/latestTested SDK source
#!/usr/bin/env python3
import json
import os
from typing import Dict, Union

from oilpriceapi import OilPriceAPI, TimeoutError


def run() -> Dict[str, Union[bool, str]]:
    try:
        with OilPriceAPI(
            api_key=os.environ["OILPRICEAPI_KEY"],
            base_url=os.environ.get("OILPRICEAPI_BASE_URL"),
            max_retries=1,
            timeout=0.05,
        ) as client:
            client.prices.get("BRENT_CRUDE_USD")
    except TimeoutError:
        return {"handled": True, "error_type": "TimeoutError"}

    raise RuntimeError("Expected the request to time out")


if __name__ == "__main__":
    print(json.dumps(run(), sort_keys=True))

Current offer

7-day core commodity API trial

New accounts receive 10,000 trial requests without a credit card, followed by 200 requests per month on Free. Dataset access and limits vary by plan, source, and account entitlement.