oilpriceapi 0.5.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +395 -110
  2. package/dist/client.d.ts +83 -3
  3. package/dist/client.js +118 -38
  4. package/dist/index.d.ts +31 -6
  5. package/dist/index.js +17 -3
  6. package/dist/resources/alerts.d.ts +52 -15
  7. package/dist/resources/alerts.js +143 -85
  8. package/dist/resources/analytics.d.ts +325 -0
  9. package/dist/resources/analytics.js +221 -0
  10. package/dist/resources/bunker-fuels.d.ts +270 -0
  11. package/dist/resources/bunker-fuels.js +191 -0
  12. package/dist/resources/commodities.d.ts +148 -0
  13. package/dist/resources/commodities.js +110 -0
  14. package/dist/resources/data-quality.d.ts +229 -0
  15. package/dist/resources/data-quality.js +139 -0
  16. package/dist/resources/data-sources.d.ts +365 -0
  17. package/dist/resources/data-sources.js +349 -0
  18. package/dist/resources/drilling.d.ts +403 -0
  19. package/dist/resources/drilling.js +264 -0
  20. package/dist/resources/ei/drilling-productivity.d.ts +173 -0
  21. package/dist/resources/ei/drilling-productivity.js +103 -0
  22. package/dist/resources/ei/forecasts.d.ts +177 -0
  23. package/dist/resources/ei/forecasts.js +101 -0
  24. package/dist/resources/ei/frac-focus.d.ts +212 -0
  25. package/dist/resources/ei/frac-focus.js +150 -0
  26. package/dist/resources/ei/index.d.ts +140 -0
  27. package/dist/resources/ei/index.js +87 -0
  28. package/dist/resources/ei/oil-inventories.d.ts +155 -0
  29. package/dist/resources/ei/oil-inventories.js +92 -0
  30. package/dist/resources/ei/opec-production.d.ts +146 -0
  31. package/dist/resources/ei/opec-production.js +92 -0
  32. package/dist/resources/ei/rig-counts.d.ts +131 -0
  33. package/dist/resources/ei/rig-counts.js +88 -0
  34. package/dist/resources/ei/well-permits.d.ts +178 -0
  35. package/dist/resources/ei/well-permits.js +119 -0
  36. package/dist/resources/forecasts.d.ts +200 -0
  37. package/dist/resources/forecasts.js +157 -0
  38. package/dist/resources/futures.d.ts +322 -0
  39. package/dist/resources/futures.js +228 -0
  40. package/dist/resources/rig-counts.d.ts +221 -0
  41. package/dist/resources/rig-counts.js +157 -0
  42. package/dist/resources/storage.d.ts +182 -0
  43. package/dist/resources/storage.js +161 -0
  44. package/dist/resources/webhooks.d.ts +290 -0
  45. package/dist/resources/webhooks.js +297 -0
  46. package/dist/types.d.ts +106 -6
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +3 -3
package/README.md CHANGED
@@ -18,6 +18,7 @@ Official Node.js SDK for [Oil Price API](https://www.oilpriceapi.com) - Get real
18
18
  - 🐛 **Debuggable** - Built-in debug logging mode
19
19
  - ⛽ **NEW v0.4.0** - Diesel prices (state averages + station-level pricing)
20
20
  - 🔔 **NEW v0.5.0** - Price alerts with webhook notifications
21
+ - 📊 **NEW v0.7.0** - Futures, storage, rig counts, analytics, drilling intelligence, webhooks, and energy intelligence
21
22
 
22
23
  ## Installation
23
24
 
@@ -28,13 +29,13 @@ npm install oilpriceapi
28
29
  ## Quick Start
29
30
 
30
31
  ```typescript
31
- import { OilPriceAPI } from 'oilpriceapi';
32
+ import { OilPriceAPI } from "oilpriceapi";
32
33
 
33
34
  // Initialize the client
34
35
  const client = new OilPriceAPI({
35
- apiKey: 'your_api_key_here', // Get your free key at https://www.oilpriceapi.com
36
- retries: 3, // Automatic retries (default: 3)
37
- timeout: 30000 // Request timeout in ms (default: 30000)
36
+ apiKey: "your_api_key_here", // Get your free key at https://www.oilpriceapi.com
37
+ retries: 3, // Automatic retries (default: 3)
38
+ timeout: 30000, // Request timeout in ms (default: 30000)
38
39
  });
39
40
 
40
41
  // Get latest prices
@@ -68,11 +69,11 @@ const prices = await client.getLatestPrices();
68
69
 
69
70
  ```typescript
70
71
  // Get only WTI crude oil price
71
- const wti = await client.getLatestPrices({ commodity: 'WTI_USD' });
72
+ const wti = await client.getLatestPrices({ commodity: "WTI_USD" });
72
73
  console.log(`WTI: ${wti[0].formatted} per barrel`);
73
74
 
74
75
  // Get only Brent crude price
75
- const brent = await client.getLatestPrices({ commodity: 'BRENT_CRUDE_USD' });
76
+ const brent = await client.getLatestPrices({ commodity: "BRENT_CRUDE_USD" });
76
77
  console.log(`Brent: ${brent[0].formatted} per barrel`);
77
78
  ```
78
79
 
@@ -80,8 +81,8 @@ console.log(`Brent: ${brent[0].formatted} per barrel`);
80
81
 
81
82
  ```typescript
82
83
  const weekPrices = await client.getHistoricalPrices({
83
- period: 'past_week',
84
- commodity: 'WTI_USD'
84
+ period: "past_week",
85
+ commodity: "WTI_USD",
85
86
  });
86
87
 
87
88
  console.log(`Got ${weekPrices.length} data points from the past week`);
@@ -91,21 +92,40 @@ console.log(`Got ${weekPrices.length} data points from the past week`);
91
92
 
92
93
  ```typescript
93
94
  const prices = await client.getHistoricalPrices({
94
- startDate: '2024-01-01',
95
- endDate: '2024-12-31',
96
- commodity: 'BRENT_CRUDE_USD'
95
+ startDate: "2024-01-01",
96
+ endDate: "2024-12-31",
97
+ commodity: "BRENT_CRUDE_USD",
97
98
  });
98
99
 
99
100
  console.log(`Got ${prices.length} data points for 2024`);
100
101
  ```
101
102
 
103
+ ### Performance Optimization (New in v0.6.0)
104
+
105
+ For year-long queries, use the `interval` parameter to dramatically improve response times:
106
+
107
+ ```typescript
108
+ // FAST: Daily aggregation returns 365 data points (~1 second)
109
+ const yearlyPrices = await client.getHistoricalPrices({
110
+ period: "past_year",
111
+ commodity: "BRENT_CRUDE_USD",
112
+ interval: "daily", // Options: 'raw', 'hourly', 'daily', 'weekly', 'monthly'
113
+ });
114
+
115
+ console.log(`Got ${yearlyPrices.length} daily averages`);
116
+ // Output: Got 365 daily averages
117
+
118
+ // SLOW: Raw data returns 600k+ points (can take 74+ seconds)
119
+ // Only use 'raw' when you need every individual price point
120
+ ```
121
+
102
122
  ### Get Diesel Prices (New in v0.4.0)
103
123
 
104
124
  #### Get State Average Diesel Price
105
125
 
106
126
  ```typescript
107
127
  // Get California diesel price
108
- const caPrice = await client.diesel.getPrice('CA');
128
+ const caPrice = await client.diesel.getPrice("CA");
109
129
  console.log(`California diesel: $${caPrice.price}/gallon`);
110
130
  console.log(`Source: ${caPrice.source}`);
111
131
  console.log(`Last updated: ${caPrice.updated_at}`);
@@ -121,16 +141,18 @@ console.log(`Last updated: ${caPrice.updated_at}`);
121
141
  ```typescript
122
142
  // Find diesel stations near San Francisco
123
143
  const result = await client.diesel.getStations({
124
- lat: 37.7749, // San Francisco latitude
144
+ lat: 37.7749, // San Francisco latitude
125
145
  lng: -122.4194, // San Francisco longitude
126
- radius: 8047 // 5 miles in meters (default if not specified)
146
+ radius: 8047, // 5 miles in meters (default if not specified)
127
147
  });
128
148
 
129
149
  console.log(`Regional average: $${result.regional_average.price}/gallon`);
130
- console.log(`Found ${result.stations.length} stations within ${result.search_area.radius_miles} miles`);
150
+ console.log(
151
+ `Found ${result.stations.length} stations within ${result.search_area.radius_miles} miles`,
152
+ );
131
153
 
132
154
  // Print each station
133
- result.stations.forEach(station => {
155
+ result.stations.forEach((station) => {
134
156
  console.log(`\n${station.name}`);
135
157
  console.log(` Address: ${station.address}`);
136
158
  console.log(` Price: ${station.formatted_price}`);
@@ -156,18 +178,20 @@ result.stations.forEach(station => {
156
178
 
157
179
  ```typescript
158
180
  const result = await client.diesel.getStations({
159
- lat: 34.0522, // Los Angeles
181
+ lat: 34.0522, // Los Angeles
160
182
  lng: -118.2437,
161
- radius: 5000 // ~3 miles
183
+ radius: 5000, // ~3 miles
162
184
  });
163
185
 
164
186
  // Find the cheapest station
165
187
  const cheapest = result.stations.reduce((min, station) =>
166
- station.diesel_price < min.diesel_price ? station : min
188
+ station.diesel_price < min.diesel_price ? station : min,
167
189
  );
168
190
 
169
191
  console.log(`Cheapest diesel: ${cheapest.name} at ${cheapest.formatted_price}`);
170
- console.log(`Savings: ${Math.abs(cheapest.price_delta!).toFixed(2)} per gallon vs regional average`);
192
+ console.log(
193
+ `Savings: ${Math.abs(cheapest.price_delta!).toFixed(2)} per gallon vs regional average`,
194
+ );
171
195
  ```
172
196
 
173
197
  **Note:** Station-level diesel prices are available on paid tiers (Exploration and above). State averages are free.
@@ -179,13 +203,13 @@ console.log(`Savings: ${Math.abs(cheapest.price_delta!).toFixed(2)} per gallon v
179
203
  ```typescript
180
204
  // Create an alert when Brent crude exceeds $85
181
205
  const alert = await client.alerts.create({
182
- name: 'Brent High Alert',
183
- commodity_code: 'BRENT_CRUDE_USD',
184
- condition_operator: 'greater_than',
185
- condition_value: 85.00,
186
- webhook_url: 'https://your-app.com/webhooks/price-alert',
206
+ name: "Brent High Alert",
207
+ commodity_code: "BRENT_CRUDE_USD",
208
+ condition_operator: "greater_than",
209
+ condition_value: 85.0,
210
+ webhook_url: "https://your-app.com/webhooks/price-alert",
187
211
  enabled: true,
188
- cooldown_minutes: 60 // Wait 60 minutes between triggers
212
+ cooldown_minutes: 60, // Wait 60 minutes between triggers
189
213
  });
190
214
 
191
215
  console.log(`Alert created: ${alert.name} (ID: ${alert.id})`);
@@ -196,11 +220,13 @@ console.log(`Alert created: ${alert.name} (ID: ${alert.id})`);
196
220
  ```typescript
197
221
  const alerts = await client.alerts.list();
198
222
 
199
- alerts.forEach(alert => {
200
- console.log(`${alert.name}: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`);
201
- console.log(` Status: ${alert.enabled ? 'Active' : 'Disabled'}`);
223
+ alerts.forEach((alert) => {
224
+ console.log(
225
+ `${alert.name}: ${alert.commodity_code} ${alert.condition_operator} ${alert.condition_value}`,
226
+ );
227
+ console.log(` Status: ${alert.enabled ? "Active" : "Disabled"}`);
202
228
  console.log(` Triggers: ${alert.trigger_count}`);
203
- console.log(` Last triggered: ${alert.last_triggered_at || 'Never'}`);
229
+ console.log(` Last triggered: ${alert.last_triggered_at || "Never"}`);
204
230
  });
205
231
  ```
206
232
 
@@ -212,13 +238,13 @@ await client.alerts.update(alertId, { enabled: false });
212
238
 
213
239
  // Change threshold and cooldown
214
240
  await client.alerts.update(alertId, {
215
- condition_value: 90.00,
216
- cooldown_minutes: 120
241
+ condition_value: 90.0,
242
+ cooldown_minutes: 120,
217
243
  });
218
244
 
219
245
  // Update webhook URL
220
246
  await client.alerts.update(alertId, {
221
- webhook_url: 'https://new-app.com/webhook'
247
+ webhook_url: "https://new-app.com/webhook",
222
248
  });
223
249
  ```
224
250
 
@@ -226,22 +252,25 @@ await client.alerts.update(alertId, {
226
252
 
227
253
  ```typescript
228
254
  await client.alerts.delete(alertId);
229
- console.log('Alert deleted successfully');
255
+ console.log("Alert deleted successfully");
230
256
  ```
231
257
 
232
258
  #### Test Webhook Endpoint
233
259
 
234
260
  ```typescript
235
- const result = await client.alerts.testWebhook('https://your-app.com/webhook');
261
+ const result = await client.alerts.testWebhook("https://your-app.com/webhook");
236
262
 
237
263
  if (result.success) {
238
- console.log(`Webhook OK (${result.status_code}) - ${result.response_time_ms}ms`);
264
+ console.log(
265
+ `Webhook OK (${result.status_code}) - ${result.response_time_ms}ms`,
266
+ );
239
267
  } else {
240
268
  console.error(`Webhook failed: ${result.error}`);
241
269
  }
242
270
  ```
243
271
 
244
272
  **Alert Operators:**
273
+
245
274
  - `greater_than` - Trigger when price exceeds threshold
246
275
  - `less_than` - Trigger when price falls below threshold
247
276
  - `equals` - Trigger when price matches threshold exactly
@@ -250,6 +279,7 @@ if (result.success) {
250
279
 
251
280
  **Webhook Payload Example:**
252
281
  When an alert triggers, a POST request is sent to your webhook URL with:
282
+
253
283
  ```json
254
284
  {
255
285
  "event": "price_alert.triggered",
@@ -257,36 +287,247 @@ When an alert triggers, a POST request is sent to your webhook URL with:
257
287
  "alert_name": "Brent High Alert",
258
288
  "commodity_code": "BRENT_CRUDE_USD",
259
289
  "condition_operator": "greater_than",
260
- "condition_value": 85.00,
261
- "current_price": 86.50,
290
+ "condition_value": 85.0,
291
+ "current_price": 86.5,
262
292
  "triggered_at": "2025-12-15T14:30:00Z"
263
293
  }
264
294
  ```
265
295
 
266
296
  **Limits:**
297
+
267
298
  - Maximum 100 alerts per user
268
299
  - Cooldown period: 0-1440 minutes (24 hours)
269
300
  - Condition value: Must be between $0.01 and $1,000,000
270
301
  - Webhook URL: Must use HTTPS protocol
271
302
 
303
+ ### Commodities Metadata (New in v0.7.0)
304
+
305
+ ```typescript
306
+ // List all available commodities
307
+ const { commodities } = await client.commodities.list();
308
+ console.log(`${commodities.length} commodities available`);
309
+
310
+ // Get specific commodity details
311
+ const wti = await client.commodities.get("WTI_USD");
312
+ console.log(`${wti.name}: ${wti.description}`);
313
+ console.log(`Unit: ${wti.unit}, Currency: ${wti.currency}`);
314
+
315
+ // Get commodities by category
316
+ const categories = await client.commodities.categories();
317
+ console.log(`Oil category: ${categories.oil.commodities.length} commodities`);
318
+ ```
319
+
320
+ ### Futures Contracts (New in v0.7.0)
321
+
322
+ ```typescript
323
+ // Get latest futures price
324
+ const wti = await client.futures.latest("CL.1");
325
+ console.log(`WTI Front Month: $${wti.price}`);
326
+
327
+ // Get OHLC data
328
+ const ohlc = await client.futures.ohlc("CL.1", "2024-01-15");
329
+ console.log(`High: $${ohlc.high}, Low: $${ohlc.low}`);
330
+
331
+ // Get futures curve
332
+ const curve = await client.futures.curve("CL");
333
+ curve.curve.forEach((point) => {
334
+ console.log(`${point.months_out} months: $${point.price}`);
335
+ });
336
+ ```
337
+
338
+ ### Storage Levels (New in v0.7.0)
339
+
340
+ ```typescript
341
+ // Get total US crude storage
342
+ const storage = await client.storage.all();
343
+ console.log(`US inventory: ${storage.level} ${storage.unit}`);
344
+
345
+ // Get Cushing hub levels
346
+ const cushing = await client.storage.cushing();
347
+ console.log(`Cushing: ${cushing.level} ${cushing.unit}`);
348
+
349
+ // Get Strategic Petroleum Reserve
350
+ const spr = await client.storage.spr();
351
+ console.log(`SPR: ${spr.level} ${spr.unit}`);
352
+ ```
353
+
354
+ ### Rig Counts (New in v0.7.0)
355
+
356
+ ```typescript
357
+ // Get latest Baker Hughes rig count
358
+ const rigCounts = await client.rigCounts.latest();
359
+ console.log(`Total rigs: ${rigCounts.total}`);
360
+ console.log(`Oil: ${rigCounts.oil}, Gas: ${rigCounts.gas}`);
361
+
362
+ // Get summary with changes
363
+ const summary = await client.rigCounts.summary();
364
+ console.log(`Week-over-week: ${summary.week_change}`);
365
+ console.log(`Year-over-year: ${summary.year_change}`);
366
+ ```
367
+
368
+ ### Analytics (New in v0.7.0)
369
+
370
+ ```typescript
371
+ // Get performance metrics
372
+ const perf = await client.analytics.performance({
373
+ commodity: "WTI_USD",
374
+ days: 30,
375
+ });
376
+ console.log(`30-day return: ${perf.return_percent}%`);
377
+ console.log(`Volatility: ${perf.volatility}`);
378
+
379
+ // Analyze correlation between commodities
380
+ const corr = await client.analytics.correlation(
381
+ "WTI_USD",
382
+ "BRENT_CRUDE_USD",
383
+ 90,
384
+ );
385
+ console.log(`Correlation: ${corr.correlation} (${corr.strength})`);
386
+ ```
387
+
388
+ ### Drilling Intelligence (New in v0.7.0)
389
+
390
+ ```typescript
391
+ // Get latest drilling activity
392
+ const drilling = await client.drilling.latest();
393
+ console.log(`Active rigs: ${drilling.total_rigs}`);
394
+ console.log(`Frac spreads: ${drilling.total_frac_spreads}`);
395
+
396
+ // Get basin-specific data
397
+ const permian = await client.drilling.basin("Permian");
398
+ console.log(`Permian rigs: ${permian.active_rigs}`);
399
+ console.log(`DUC wells: ${permian.duc_wells}`);
400
+ ```
401
+
402
+ ### Energy Intelligence (New in v0.7.0)
403
+
404
+ Access comprehensive energy market intelligence from EIA, Baker Hughes, and FracFocus.
405
+
406
+ ```typescript
407
+ // Rig counts
408
+ const rigCounts = await client.ei.rigCounts.latest();
409
+ console.log(`Total rigs: ${rigCounts.total_rigs}`);
410
+
411
+ // Oil inventories
412
+ const inventories = await client.ei.oilInventories.latest();
413
+ console.log(`Crude stocks: ${inventories.level} ${inventories.unit}`);
414
+
415
+ // OPEC production
416
+ const opec = await client.ei.opecProduction.total();
417
+ console.log(`OPEC production: ${opec.total_production_bpd} bpd`);
418
+
419
+ // Well timeline
420
+ const timeline = await client.ei.wellTimeline("42-123-12345");
421
+ timeline.events.forEach((e) => {
422
+ console.log(`${e.date}: ${e.event_type}`);
423
+ });
424
+ ```
425
+
426
+ ### Webhooks (New in v0.7.0)
427
+
428
+ ```typescript
429
+ // Create a webhook
430
+ const webhook = await client.webhooks.create({
431
+ name: "Price Updates",
432
+ url: "https://myapp.com/webhooks/prices",
433
+ events: ["price.updated", "alert.triggered"],
434
+ enabled: true,
435
+ });
436
+
437
+ // Test the webhook
438
+ const test = await client.webhooks.test(webhook.id);
439
+ console.log(`Test ${test.success ? "passed" : "failed"}`);
440
+
441
+ // List all webhooks
442
+ const webhooks = await client.webhooks.list();
443
+ webhooks.forEach((wh) => {
444
+ console.log(`${wh.name}: ${wh.successful_deliveries} successful`);
445
+ });
446
+ ```
447
+
448
+ ### Bunker Fuels (New in v0.7.0)
449
+
450
+ ```typescript
451
+ // Get bunker fuel prices at all ports
452
+ const bunkerPrices = await client.bunkerFuels.all();
453
+ console.log(`${bunkerPrices.length} port prices available`);
454
+
455
+ // Get prices at specific port
456
+ const singapore = await client.bunkerFuels.port("SGSIN");
457
+ console.log(`Singapore VLSFO: $${singapore.prices.VLSFO}/MT`);
458
+
459
+ // Compare prices across ports
460
+ const comparison = await client.bunkerFuels.compare("VLSFO");
461
+ comparison.ports.forEach((p) => {
462
+ console.log(`${p.port_name}: $${p.price}/MT (rank ${p.rank})`);
463
+ });
464
+ ```
465
+
466
+ ### Forecasts (New in v0.7.0)
467
+
468
+ ```typescript
469
+ // Get monthly forecasts
470
+ const forecasts = await client.forecasts.monthly();
471
+ forecasts.forEach((f) => {
472
+ console.log(`${f.period}: $${f.forecast_price} (${f.source})`);
473
+ });
474
+
475
+ // Check forecast accuracy
476
+ const accuracy = await client.forecasts.accuracy();
477
+ console.log(`EIA MAPE: ${accuracy.mape}%`);
478
+
479
+ // Get specific forecast
480
+ const wtiQ2 = await client.forecasts.get({
481
+ commodity: "WTI_USD",
482
+ period: "2024-Q2",
483
+ });
484
+ console.log(`WTI Q2 forecast: $${wtiQ2.forecast_price}`);
485
+ ```
486
+
487
+ ### Data Sources (New in v0.7.0)
488
+
489
+ Manage custom data source integrations for Bring Your Own Source (BYOS).
490
+
491
+ ```typescript
492
+ // Create a data source
493
+ const source = await client.dataSources.create({
494
+ name: "Internal Pricing Database",
495
+ type: "database",
496
+ config: { host: "db.example.com", port: 5432 },
497
+ sync_frequency_minutes: 60,
498
+ });
499
+
500
+ // Test the connection
501
+ const test = await client.dataSources.test(source.id);
502
+ console.log(`Connection ${test.success ? "OK" : "failed"}`);
503
+
504
+ // View sync logs
505
+ const logs = await client.dataSources.logs(source.id);
506
+ logs.forEach((log) => {
507
+ console.log(
508
+ `${log.timestamp}: ${log.status} - ${log.records_synced} records`,
509
+ );
510
+ });
511
+ ```
512
+
272
513
  ### Advanced Configuration
273
514
 
274
515
  ```typescript
275
- import { OilPriceAPI } from 'oilpriceapi';
516
+ import { OilPriceAPI } from "oilpriceapi";
276
517
 
277
518
  const client = new OilPriceAPI({
278
- apiKey: 'your_key',
519
+ apiKey: "your_key",
279
520
 
280
521
  // Retry configuration
281
- retries: 3, // Max retry attempts (default: 3)
282
- retryDelay: 1000, // Initial delay in ms (default: 1000)
283
- retryStrategy: 'exponential', // 'exponential', 'linear', or 'fixed'
522
+ retries: 3, // Max retry attempts (default: 3)
523
+ retryDelay: 1000, // Initial delay in ms (default: 1000)
524
+ retryStrategy: "exponential", // 'exponential', 'linear', or 'fixed'
284
525
 
285
526
  // Timeout configuration
286
- timeout: 30000, // Request timeout in ms (default: 30000)
527
+ timeout: 30000, // Request timeout in ms (default: 30000)
287
528
 
288
529
  // Debug mode
289
- debug: true // Enable debug logging (default: false)
530
+ debug: true, // Enable debug logging (default: false)
290
531
  });
291
532
  ```
292
533
 
@@ -299,26 +540,30 @@ import {
299
540
  RateLimitError,
300
541
  NotFoundError,
301
542
  TimeoutError,
302
- ServerError
303
- } from 'oilpriceapi';
543
+ ServerError,
544
+ } from "oilpriceapi";
304
545
 
305
- const client = new OilPriceAPI({ apiKey: 'your_key' });
546
+ const client = new OilPriceAPI({ apiKey: "your_key" });
306
547
 
307
548
  try {
308
549
  const prices = await client.getLatestPrices();
309
550
  } catch (error) {
310
551
  if (error instanceof AuthenticationError) {
311
- console.error('Invalid API key:', error.message);
552
+ console.error("Invalid API key:", error.message);
312
553
  } else if (error instanceof RateLimitError) {
313
- console.error('Rate limit exceeded. Retry after:', error.retryAfter, 'seconds');
554
+ console.error(
555
+ "Rate limit exceeded. Retry after:",
556
+ error.retryAfter,
557
+ "seconds",
558
+ );
314
559
  } else if (error instanceof TimeoutError) {
315
- console.error('Request timed out:', error.message);
560
+ console.error("Request timed out:", error.message);
316
561
  } else if (error instanceof ServerError) {
317
- console.error('Server error:', error.statusCode, error.message);
562
+ console.error("Server error:", error.statusCode, error.message);
318
563
  } else if (error instanceof NotFoundError) {
319
- console.error('Commodity not found:', error.message);
564
+ console.error("Commodity not found:", error.message);
320
565
  } else {
321
- console.error('Unknown error:', error);
566
+ console.error("Unknown error:", error);
322
567
  }
323
568
  }
324
569
  ```
@@ -329,8 +574,8 @@ Enable debug logging to see detailed request/response information:
329
574
 
330
575
  ```typescript
331
576
  const client = new OilPriceAPI({
332
- apiKey: 'your_key',
333
- debug: true
577
+ apiKey: "your_key",
578
+ debug: true,
334
579
  });
335
580
 
336
581
  // This will log all requests, responses, retries, and errors
@@ -355,49 +600,54 @@ See the [`examples/`](./examples) directory for complete, runnable code examples
355
600
  ### Quick Examples
356
601
 
357
602
  **Get Latest Price:**
603
+
358
604
  ```typescript
359
- const prices = await client.getLatestPrices({ commodity: 'WTI_USD' });
605
+ const prices = await client.getLatestPrices({ commodity: "WTI_USD" });
360
606
  console.log(prices[0].formatted); // "$74.25"
361
607
  ```
362
608
 
363
609
  **Historical Data:**
610
+
364
611
  ```typescript
365
612
  const history = await client.getHistoricalPrices({
366
- commodity: 'BRENT_CRUDE_USD',
367
- period: 'past_week'
613
+ commodity: "BRENT_CRUDE_USD",
614
+ period: "past_week",
368
615
  });
369
616
  ```
370
617
 
371
618
  **Commodity Metadata:**
619
+
372
620
  ```typescript
373
621
  const { commodities } = await client.getCommodities();
374
622
  console.log(`Found ${commodities.length} commodities`);
375
623
  ```
376
624
 
377
625
  **Diesel Prices:**
626
+
378
627
  ```typescript
379
628
  // State average (free)
380
- const caPrice = await client.diesel.getPrice('CA');
629
+ const caPrice = await client.diesel.getPrice("CA");
381
630
  console.log(`CA diesel: $${caPrice.price}/gal`);
382
631
 
383
632
  // Nearby stations (paid tiers)
384
633
  const stations = await client.diesel.getStations({
385
634
  lat: 37.7749,
386
635
  lng: -122.4194,
387
- radius: 8047 // 5 miles
636
+ radius: 8047, // 5 miles
388
637
  });
389
638
  console.log(`Found ${stations.stations.length} stations`);
390
639
  ```
391
640
 
392
641
  **Price Alerts:**
642
+
393
643
  ```typescript
394
644
  // Create an alert
395
645
  const alert = await client.alerts.create({
396
- name: 'Brent High Alert',
397
- commodity_code: 'BRENT_CRUDE_USD',
398
- condition_operator: 'greater_than',
399
- condition_value: 85.00,
400
- webhook_url: 'https://your-app.com/webhook'
646
+ name: "Brent High Alert",
647
+ commodity_code: "BRENT_CRUDE_USD",
648
+ condition_operator: "greater_than",
649
+ condition_value: 85.0,
650
+ webhook_url: "https://your-app.com/webhook",
401
651
  });
402
652
 
403
653
  // List all alerts
@@ -407,13 +657,37 @@ const alerts = await client.alerts.list();
407
657
  await client.alerts.update(alert.id, { enabled: false });
408
658
  ```
409
659
 
660
+ **Futures & Storage:**
661
+
662
+ ```typescript
663
+ // Get WTI futures price
664
+ const wti = await client.futures.latest("CL.1");
665
+ console.log(`WTI: $${wti.price}`);
666
+
667
+ // Get Cushing storage
668
+ const cushing = await client.storage.cushing();
669
+ console.log(`Cushing: ${cushing.level} ${cushing.unit}`);
670
+ ```
671
+
672
+ **Analytics:**
673
+
674
+ ```typescript
675
+ // Get performance metrics
676
+ const perf = await client.analytics.performance({
677
+ commodity: "WTI_USD",
678
+ days: 30,
679
+ });
680
+ console.log(`30-day return: ${perf.return_percent}%`);
681
+ ```
682
+
410
683
  **Error Handling:**
684
+
411
685
  ```typescript
412
686
  try {
413
687
  const prices = await client.getLatestPrices();
414
688
  } catch (error) {
415
689
  if (error instanceof RateLimitError) {
416
- console.log('Rate limited, retry after:', error.retryAfter);
690
+ console.log("Rate limited, retry after:", error.retryAfter);
417
691
  }
418
692
  }
419
693
  ```
@@ -431,6 +705,7 @@ new OilPriceAPI(config: OilPriceAPIConfig)
431
705
  ```
432
706
 
433
707
  **Parameters:**
708
+
434
709
  - `config.apiKey` (string, required) - Your API key from https://www.oilpriceapi.com
435
710
  - `config.baseUrl` (string, optional) - Custom API base URL (for testing)
436
711
 
@@ -441,6 +716,7 @@ new OilPriceAPI(config: OilPriceAPIConfig)
441
716
  Get the latest prices for all commodities or a specific commodity.
442
717
 
443
718
  **Parameters:**
719
+
444
720
  - `options.commodity` (string, optional) - Filter by commodity code (e.g., "WTI_USD")
445
721
 
446
722
  **Returns:** `Promise<Price[]>`
@@ -450,10 +726,14 @@ Get the latest prices for all commodities or a specific commodity.
450
726
  Get historical prices for a time period.
451
727
 
452
728
  **Parameters:**
729
+
453
730
  - `options.period` (string, optional) - One of: "past_week", "past_month", "past_year"
454
731
  - `options.commodity` (string, optional) - Filter by commodity code
455
732
  - `options.startDate` (string, optional) - Start date in ISO 8601 format (YYYY-MM-DD)
456
733
  - `options.endDate` (string, optional) - End date in ISO 8601 format (YYYY-MM-DD)
734
+ - `options.interval` (string, optional) - Aggregation interval: "raw", "hourly", "daily", "weekly", "monthly". **Performance tip:** Use "daily" for year-long queries (365 points vs 600k+ raw points)
735
+ - `options.perPage` (number, optional) - Results per page (default: 100, max: 1000)
736
+ - `options.page` (number, optional) - Page number for pagination (default: 1)
457
737
 
458
738
  **Returns:** `Promise<Price[]>`
459
739
 
@@ -474,6 +754,7 @@ Get all commodity categories with their commodities.
474
754
  Get metadata for a specific commodity by code.
475
755
 
476
756
  **Parameters:**
757
+
477
758
  - `code` (string, required) - Commodity code (e.g., "WTI_USD")
478
759
 
479
760
  **Returns:** `Promise<Commodity>` - Commodity metadata object
@@ -487,13 +768,15 @@ Resource for diesel price data (state averages and station-level pricing).
487
768
  Get average diesel price for a US state from EIA data.
488
769
 
489
770
  **Parameters:**
771
+
490
772
  - `state` (string, required) - Two-letter US state code (e.g., "CA", "TX", "NY")
491
773
 
492
774
  **Returns:** `Promise<DieselPrice>`
493
775
 
494
776
  **Example:**
777
+
495
778
  ```typescript
496
- const caPrice = await client.diesel.getPrice('CA');
779
+ const caPrice = await client.diesel.getPrice("CA");
497
780
  console.log(`California: $${caPrice.price}/gallon`);
498
781
  ```
499
782
 
@@ -502,6 +785,7 @@ console.log(`California: $${caPrice.price}/gallon`);
502
785
  Get nearby diesel stations with current pricing from Google Maps data.
503
786
 
504
787
  **Parameters:**
788
+
505
789
  - `options.lat` (number, required) - Latitude (-90 to 90)
506
790
  - `options.lng` (number, required) - Longitude (-180 to 180)
507
791
  - `options.radius` (number, optional) - Search radius in meters (default: 8047 = 5 miles, max: 50000)
@@ -511,18 +795,19 @@ Get nearby diesel stations with current pricing from Google Maps data.
511
795
  **Tier Requirements:** Available on paid tiers (Exploration and above)
512
796
 
513
797
  **Example:**
798
+
514
799
  ```typescript
515
800
  const result = await client.diesel.getStations({
516
801
  lat: 37.7749,
517
802
  lng: -122.4194,
518
- radius: 8047 // 5 miles
803
+ radius: 8047, // 5 miles
519
804
  });
520
805
 
521
806
  console.log(`Found ${result.stations.length} stations`);
522
807
  console.log(`Regional average: $${result.regional_average.price}/gallon`);
523
808
 
524
809
  const cheapest = result.stations.reduce((min, s) =>
525
- s.diesel_price < min.diesel_price ? s : min
810
+ s.diesel_price < min.diesel_price ? s : min,
526
811
  );
527
812
  console.log(`Cheapest: ${cheapest.name} at ${cheapest.formatted_price}`);
528
813
  ```
@@ -533,14 +818,14 @@ console.log(`Cheapest: ${cheapest.name} at ${cheapest.formatted_price}`);
533
818
 
534
819
  ```typescript
535
820
  interface Price {
536
- code: string; // Commodity code (e.g., "WTI_USD")
537
- name: string; // Human-readable name
538
- value: number; // Price value
539
- currency: string; // Currency code (e.g., "USD")
540
- unit: string; // Unit of measurement (e.g., "barrel")
541
- timestamp: string; // ISO 8601 timestamp
542
- created_at: string; // ISO 8601 timestamp
543
- updated_at: string; // ISO 8601 timestamp
821
+ code: string; // Commodity code (e.g., "WTI_USD")
822
+ name: string; // Human-readable name
823
+ value: number; // Price value
824
+ currency: string; // Currency code (e.g., "USD")
825
+ unit: string; // Unit of measurement (e.g., "barrel")
826
+ timestamp: string; // ISO 8601 timestamp
827
+ created_at: string; // ISO 8601 timestamp
828
+ updated_at: string; // ISO 8601 timestamp
544
829
  }
545
830
  ```
546
831
 
@@ -548,14 +833,14 @@ interface Price {
548
833
 
549
834
  ```typescript
550
835
  interface DieselPrice {
551
- state: string; // State code (e.g., "CA", "TX")
552
- price: number; // Average diesel price in USD per gallon
553
- currency: string; // Currency code (always "USD")
554
- unit: string; // Unit of measurement (always "gallon")
555
- granularity: string; // Level (e.g., "state", "national")
556
- source: string; // Data source (e.g., "EIA")
557
- updated_at: string; // ISO 8601 timestamp of last update
558
- cached?: boolean; // Whether served from cache
836
+ state: string; // State code (e.g., "CA", "TX")
837
+ price: number; // Average diesel price in USD per gallon
838
+ currency: string; // Currency code (always "USD")
839
+ unit: string; // Unit of measurement (always "gallon")
840
+ granularity: string; // Level (e.g., "state", "national")
841
+ source: string; // Data source (e.g., "EIA")
842
+ updated_at: string; // ISO 8601 timestamp of last update
843
+ cached?: boolean; // Whether served from cache
559
844
  }
560
845
  ```
561
846
 
@@ -563,20 +848,20 @@ interface DieselPrice {
563
848
 
564
849
  ```typescript
565
850
  interface DieselStation {
566
- name: string; // Station name
567
- address: string; // Full street address
851
+ name: string; // Station name
852
+ address: string; // Full street address
568
853
  location: {
569
- lat: number; // Latitude
570
- lng: number; // Longitude
854
+ lat: number; // Latitude
855
+ lng: number; // Longitude
571
856
  };
572
- diesel_price: number; // Price at this station (USD per gallon)
573
- formatted_price: string;// Formatted price (e.g., "$3.89")
574
- currency: string; // Currency code (always "USD")
575
- unit: string; // Unit (always "gallon")
576
- price_delta?: number; // Difference from regional average
857
+ diesel_price: number; // Price at this station (USD per gallon)
858
+ formatted_price: string; // Formatted price (e.g., "$3.89")
859
+ currency: string; // Currency code (always "USD")
860
+ unit: string; // Unit (always "gallon")
861
+ price_delta?: number; // Difference from regional average
577
862
  price_vs_average?: string; // Human-readable comparison
578
- fuel_types?: string[]; // Available fuel types
579
- last_updated?: string; // ISO 8601 timestamp
863
+ fuel_types?: string[]; // Available fuel types
864
+ last_updated?: string; // ISO 8601 timestamp
580
865
  }
581
866
  ```
582
867
 
@@ -585,28 +870,28 @@ interface DieselStation {
585
870
  ```typescript
586
871
  interface DieselStationsResponse {
587
872
  regional_average: {
588
- price: number; // Regional average price
589
- currency: string; // Currency code
590
- unit: string; // Unit
591
- region: string; // Region name
592
- granularity: string; // Granularity level
593
- source: string; // Data source
873
+ price: number; // Regional average price
874
+ currency: string; // Currency code
875
+ unit: string; // Unit
876
+ region: string; // Region name
877
+ granularity: string; // Granularity level
878
+ source: string; // Data source
594
879
  };
595
880
  stations: DieselStation[]; // List of nearby stations
596
881
  search_area: {
597
882
  center: {
598
- lat: number; // Search center latitude
599
- lng: number; // Search center longitude
883
+ lat: number; // Search center latitude
884
+ lng: number; // Search center longitude
600
885
  };
601
- radius_meters: number;// Search radius in meters
886
+ radius_meters: number; // Search radius in meters
602
887
  radius_miles: number; // Search radius in miles
603
888
  };
604
889
  metadata: {
605
890
  total_stations: number; // Number of stations found
606
- source: string; // Data source
607
- cached: boolean; // Whether served from cache
608
- api_cost: number; // Cost in dollars
609
- timestamp: string; // ISO 8601 timestamp
891
+ source: string; // Data source
892
+ cached: boolean; // Whether served from cache
893
+ api_cost: number; // Cost in dollars
894
+ timestamp: string; // ISO 8601 timestamp
610
895
  cache_age_hours?: number; // Cache age in hours
611
896
  };
612
897
  }