Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

OilPriceAPI Node.js SDK

Official Node.js and TypeScript client for source-timestamped OilPriceAPI energy data. It provides typed resources, bounded retries, explicit errors, raw response access, and executable example manifests.

npm versionTestsLicense: MIT

Mutable offer, catalog, freshness, entitlement, and data-rights wording is governed by the reviewed product-facts.json contract. Latest available values include source timestamps; cadence, history depth, and access vary by source, market hours, dataset, and account entitlement.

Install

npm install oilpriceapi

The SDK requires Node.js 18 or newer. An installed resource helper does not imply that every dataset or workflow is enabled for an account; confirm access in the current API response and documentation.

Authenticate

Create an API key in the OilPriceAPI dashboard and provide it through the environment. Do not put a key in source code, a URL, logs, screenshots, generated artifacts, or issue text.

export OILPRICEAPI_KEY="your-key-from-the-dashboard"

The API authentication header is Authorization: Token YOUR_API_KEY.

First Request With Source Context

The canonical first request is GET /v1/prices/latest?by_code=BRENT_CRUDE_USD. This TypeScript example fails closed if the response omits the context needed to interpret the value:

import{OilPriceAPI}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY,retries: 0,timeout: 30_000,});const[record]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});consttimestampFields=["as_of","source_timestamp","created_at","updated_at",]asconst;consttimestampField=timestampFields.find((field)=>typeofrecord?.[field]==="string"&&record[field].trim(),);if(!record||!Number.isFinite(record.price)||typeofrecord.code!=="string"||typeofrecord.currency!=="string"||typeofrecord.unit!=="string"||typeofrecord.source!=="string"||!timestampField){thrownewError("MALFORMED_RESPONSE: source context is incomplete");}console.log({code: record.code,price: record.price,currency: record.currency,unit: record.unit,source: record.source,apiTimestampField: timestampField,apiTimestamp: record[timestampField],freshness: record.data_status,});

The reviewed standalone form is examples/snippets/latest-price.ts. CI type-checks and executes it against production-shaped fixtures, then publishes its exact code and checksum in the release snippet manifest.

Several Prices In One Request

by_code accepts up to 20 comma-separated commodity codes, and the whole call counts as one request — not one per code. Batching is the cheapest way to make an allowance go further: twenty codes in one call stretches it twenty times.

constprices=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD",});for(constpofprices){console.log(p.code,p.price,p.currency);}

Asking for more than 20 codes returns 400 Too many commodity codes requested (max: 20, requested: N). An unrecognised code also returns 400, with a "did you mean" suggestion — so validate your code list once rather than on every poll.

For current plan allowances and the polling interval that fits them, see Rate Limiting.

Permit To Production

Well-level production coverage is narrower than permit coverage. Check the live coverage response before following a permit into monthly production history:

constsummary=awaitclient.wellProduction.summary();if(!summary.coverage){thrownewError("MALFORMED_RESPONSE: well-production coverage is missing");}constcoveredStates=newSet(summary.coverage.well_level_states_with_data??[]);constpermits=awaitclient.ei.wellPermits.searchLatest({states: "TX",well_name: "Eagle",});for(constpermitofpermits){if(!coveredStates.has(permit.state_code)||!/^\d{14}$/.test(permit.api_number??"")){continue;}constproduction=awaitclient.wellProduction.wellDetail(permit.api_number!);console.log(permit.well.name,production.data);}

An empty search or history is a valid data state. Do not infer nationwide well-level coverage from the presence of permit data or an SDK method.

CommonJS

const{ OilPriceAPI }=require("oilpriceapi");constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});const[price]=awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(price.code,price.price,price.currency,price.unit,price.created_at);

Recovery

The package exposes typed errors for customer-recoverable boundaries:

import{AuthenticationError,OilPriceAPI,OilPriceAPIError,RateLimitError,TimeoutError,isEntitlementError,isQuotaError,}from"oilpriceapi";constclient=newOilPriceAPI({apiKey: process.env.OILPRICEAPI_KEY});try{awaitclient.getLatestPrices({commodity: "BRENT_CRUDE_USD"});}catch(error){if(errorinstanceofAuthenticationError){console.error("Replace the missing, expired, or revoked API key.");}elseif(errorinstanceofRateLimitError){console.error("Wait for the API-provided reset window.");}elseif(errorinstanceofTimeoutError){console.error("Retry once, then check https://status.oilpriceapi.com.");}elseif(isQuotaError(error)){console.error(`Request quota exhausted; ${error.remediationUrl??"follow the API-provided recovery details"}.`,);}elseif(isEntitlementError(error)){console.error(`This dataset needs the ${error.requiredPlan??"required"} plan.`);}elseif(errorinstanceofOilPriceAPIError){console.error(error.requestId ? `Request ID: ${error.requestId}` : "Unexpected API error.");}else{throwerror;}}

Executable recovery examples cover 401, 403, 429, and timeout responses under examples/snippets/. Empty or malformed successful responses should stop processing rather than inventing a price, unit, currency, source, or timestamp.

All HTTP failures expose statusCode, code, requestId, recovery links and plan metadata when the API supplies them. rawBody and headers are retained for diagnostics; the configured API key is redacted before either is exposed.

Capabilities

The client includes resources for latest and historical values plus additional dataset and workflow families. Availability is determined by the live API and account entitlement, not by the presence of a method or exported type.

Standard plans provide API access, normalization, monitoring, and delivery; they do not transfer ownership of underlying source data or unrestricted raw data redistribution rights.

Raw Responses

client.raw returns response data together with HTTP status and response headers when the application needs request IDs, rate-limit metadata, or an unwrapped payload. Do not log authorization headers or mutable account data.

constresponse=awaitclient.raw.getLatestPrices({commodity: "BRENT_CRUDE_USD",});console.log(response.status,response.headers.get("x-request-id"),response.data);

Reproducible Examples

Website and documentation snippets are maintained in examples/snippets/. Every release attaches a versioned manifest containing the package version, minimum runtime, source commit, expected response shape, exact code, and SHA-256 for each example.

npm run snippets:check
npm run snippets:build -- --source-commit "$(git rev-parse HEAD)"

Development

npm ci
npm run storefront:check
npm run check:secrets
npm run lint
npm test
npm run build
npm pack --dry-run

Live tests require an explicitly supplied non-customer test credential. Unit and snippet tests use local fixtures and do not print or persist credentials.

Support

Licensed under the MIT License.

About

Official Node.js SDK for source-timestamped OilPriceAPI energy data with typed recovery and executable capability metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages