@fedpulse/sdk 1.0.4 → 1.0.6

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 (2) hide show
  1. package/README.md +360 -346
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,346 +1,360 @@
1
- # @fedpulse/sdk
2
-
3
- [![npm version](https://img.shields.io/npm/v/@fedpulse/sdk)](https://www.npmjs.com/package/@fedpulse/sdk)
4
- [![Node.js ≥18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
-
7
- Official JavaScript / TypeScript SDK for the [FedPulse API](https://fedpulse.dev). Search federal contract opportunities, check vendor exclusions, retrieve entity registrations, and access market intelligence — all with zero runtime dependencies.
8
-
9
- ---
10
-
11
- ## Features
12
-
13
- - **Typed end-to-end** — full TypeScript definitions for every request and response
14
- - **Dual ESM + CJS** — works in Node.js (ESM / CommonJS), Deno, Bun, and bundlers
15
- - **Zero runtime dependencies** — only uses Node.js built-ins (`fetch`, `crypto`)
16
- - **Automatic retry** — exponential back-off with full jitter for 5xx / network errors
17
- - **In-memory LRU cache** — 256-entry, 60 s TTL on all GET requests
18
- - **Webhook verification** — HMAC-SHA256 signature + replay-attack protection
19
- - **Cursor + offset pagination** — async generator helpers for all list endpoints
20
-
21
- ---
22
-
23
- ## Requirements
24
-
25
- - Node.js **≥ 18.0.0** (native `fetch` + `crypto`)
26
- - A FedPulse API key — generate one at [app.fedpulse.dev/dashboard](https://app.fedpulse.dev/dashboard)
27
-
28
- ---
29
-
30
- ## Installation
31
-
32
- ```bash
33
- npm install @fedpulse/sdk
34
- ```
35
-
36
- ---
37
-
38
- ## Quick start
39
-
40
- ```ts
41
- import { FedPulse } from '@fedpulse/sdk';
42
-
43
- const client = new FedPulse({ apiKey: process.env.FEDPULSE_API_KEY! });
44
-
45
- // Search opportunities
46
- const result = await client.opportunities.list({
47
- keyword: 'cybersecurity',
48
- naics: ['541519', '541512'],
49
- postedAfter: '2025-01-01',
50
- limit: 25,
51
- });
52
-
53
- console.log(result.data); // typed OpportunitySummary[]
54
- console.log(result.pagination); // { total, page, limit, … }
55
- ```
56
-
57
- ---
58
-
59
- ## Authentication
60
-
61
- Pass your API key to the constructor. It is sent as `Authorization: Bearer <key>` on every request.
62
-
63
- ```ts
64
- const client = new FedPulse({ apiKey: 'fp_live_…' });
65
- ```
66
-
67
- Never hard-code keys in source — use environment variables.
68
-
69
- ---
70
-
71
- ## Resources
72
-
73
- ### `client.opportunities`
74
-
75
- ```ts
76
- // List / search opportunities
77
- await client.opportunities.list({ keyword: 'cloud', naics: ['541512'] });
78
-
79
- // Retrieve a single opportunity
80
- await client.opportunities.get('abc123-notice-id');
81
-
82
- // Aggregate statistics
83
- await client.opportunities.stats({ postedAfter: '2025-01-01' });
84
-
85
- // Request a data export (async job)
86
- await client.opportunities.createExport({ format: 'csv', filter: { keyword: 'AI' } });
87
-
88
- // Async generator — walks all pages automatically
89
- for await (const page of client.opportunities.paginate({ keyword: 'defense' })) {
90
- console.log(page.data);
91
- }
92
- ```
93
-
94
- ### `client.exclusions`
95
-
96
- ```ts
97
- // List all current exclusions
98
- await client.exclusions.list({ active: true });
99
-
100
- // Retrieve one record
101
- await client.exclusions.get('exclusion-id');
102
-
103
- // Bulk check up to 100 entities
104
- await client.exclusions.check({
105
- entities: [
106
- { uei: 'ABC123DEF456' },
107
- { cage: '1A2B3' },
108
- { name: 'Acme Corp' },
109
- ],
110
- });
111
-
112
- // Stats
113
- await client.exclusions.stats();
114
-
115
- // Page through all exclusions
116
- for await (const page of client.exclusions.paginate()) {
117
- console.log(page.data);
118
- }
119
- ```
120
-
121
- ### `client.entities`
122
-
123
- ```ts
124
- // List registered entities
125
- await client.entities.list({ naics: ['336411'], state: 'VA' });
126
-
127
- // Entity by UEI
128
- await client.entities.get('ABCDEF123456');
129
-
130
- // Contracts awarded to an entity
131
- await client.entities.opportunities('ABCDEF123456', { limit: 50 });
132
-
133
- // Exclusion check (never cached)
134
- await client.entities.exclusionCheck('ABCDEF123456');
135
-
136
- // Stats
137
- await client.entities.stats();
138
-
139
- // All pages
140
- for await (const page of client.entities.paginate({ state: 'TX' })) {
141
- console.log(page.data);
142
- }
143
- ```
144
-
145
- ### `client.intelligence`
146
-
147
- ```ts
148
- // 360° entity intelligence profile
149
- await client.intelligence.entityProfile('ABCDEF123456');
150
-
151
- // Market analysis for a NAICS code
152
- await client.intelligence.marketAnalysis('541512');
153
-
154
- // Single-entity compliance check
155
- await client.intelligence.complianceCheck({ uei: 'ABCDEF123456' });
156
- ```
157
-
158
- ### `client.assistance`
159
-
160
- Federal grants and assistance listings (CFDA programs).
161
-
162
- ```ts
163
- // Search listings
164
- await client.assistance.list({ keyword: 'broadband', agency: 'USDA' });
165
-
166
- // Retrieve one by CFDA program number (format: "XX.XXX")
167
- await client.assistance.get('10.001');
168
-
169
- // Aggregated stats
170
- await client.assistance.stats();
171
-
172
- // Auto-paginate all listings
173
- for await (const page of client.assistance.paginate({ agency: 'HHS' })) {
174
- console.log(page.data);
175
- }
176
- ```
177
-
178
- ### `client.analytics`
179
-
180
- Per-user API usage analytics — scoped to the authenticated key.
181
-
182
- ```ts
183
- // KPI totals (requests today, this month, error rates)
184
- await client.analytics.summary({ range: '30d' });
185
-
186
- // Per-day breakdown for charting (up to 90 days)
187
- await client.analytics.chart({ range: '30d' });
188
-
189
- // Top endpoints by request volume and P95 latency
190
- await client.analytics.endpoints({ range: '7d' });
191
-
192
- // Paginated raw request log
193
- await client.analytics.logs({ limit: 20 });
194
- ```
195
-
196
- ### `client.webhooks`
197
-
198
- ```ts
199
- // List configured webhooks
200
- await client.webhooks.list();
201
-
202
- // Create
203
- await client.webhooks.create({ url: 'https://example.com/hook', events: ['opportunity.new'] });
204
-
205
- // Update / delete
206
- await client.webhooks.update('wh_id', { active: false });
207
- await client.webhooks.delete('wh_id');
208
-
209
- // Deliveries log
210
- await client.webhooks.listDeliveries('wh_id');
211
- await client.webhooks.getDelivery('wh_id', 'delivery-id');
212
- ```
213
-
214
- ---
215
-
216
- ## Webhook signature verification
217
-
218
- ```ts
219
- import { FedPulse } from '@fedpulse/sdk';
220
-
221
- // In your Express / Fastify handler:
222
- app.post('/webhooks', (req, res) => {
223
- const { signatureHeader, timestampHeader } = FedPulse.extractWebhookHeaders(req.headers);
224
-
225
- let event;
226
- try {
227
- event = FedPulse.verifyWebhook({
228
- rawBody: req.body, // Buffer or string — the raw unparsed body
229
- signatureHeader,
230
- timestampHeader,
231
- secret: process.env.FEDPULSE_WEBHOOK_SECRET!,
232
- options: { maxAgeSeconds: 300 },
233
- });
234
- } catch (err) {
235
- return res.status(400).send('Invalid signature');
236
- }
237
-
238
- console.log(event.event, event.data);
239
- res.sendStatus(200);
240
- });
241
- ```
242
-
243
- ---
244
-
245
- ## Pagination helpers
246
-
247
- Every list resource exposes a `paginate()` async generator that walks all pages for you:
248
-
249
- ```ts
250
- const allOpps: OpportunitySummary[] = [];
251
-
252
- for await (const page of client.opportunities.paginate({ keyword: 'cloud' })) {
253
- allOpps.push(...page.data);
254
- }
255
- ```
256
-
257
- ---
258
-
259
- ## Error handling
260
-
261
- All errors extend `FedPulseError`. Import specific classes for precise handling:
262
-
263
- ```ts
264
- import {
265
- FedPulse,
266
- AuthenticationError,
267
- PermissionError,
268
- NotFoundError,
269
- ValidationError,
270
- RateLimitError,
271
- ServerError,
272
- NetworkError,
273
- TimeoutError,
274
- RetryExhaustedError,
275
- } from '@fedpulse/sdk';
276
-
277
- try {
278
- await client.opportunities.get('bad-id');
279
- } catch (err) {
280
- if (err instanceof NotFoundError) {
281
- console.log('Not found');
282
- } else if (err instanceof RateLimitError) {
283
- console.log(`Rate limited. Retry after: ${err.retryAfter}s`);
284
- } else if (err instanceof RetryExhaustedError) {
285
- console.log(`Failed after ${err.attempts} attempts`, err.lastError);
286
- } else if (err instanceof NetworkError) {
287
- console.log('Network issue — check internet connection');
288
- }
289
- }
290
- ```
291
-
292
- | Class | Status | When thrown |
293
- |---|---|---|
294
- | `AuthenticationError` | 401 | Invalid or missing API key |
295
- | `PermissionError` | 403 | Key lacks required permission |
296
- | `NotFoundError` | 404 | Resource does not exist |
297
- | `ValidationError` | 400/422 | Bad request parameters |
298
- | `RateLimitError` | 429 | Too many requests (check `retryAfter`) |
299
- | `ServerError` | 5xx | FedPulse server error |
300
- | `NetworkError` | | DNS failure, ECONNREFUSED, etc. |
301
- | `TimeoutError` | | Request exceeded `timeoutMs` |
302
- | `RetryExhaustedError` | — | All retry attempts failed |
303
-
304
- ---
305
-
306
- ## Configuration
307
-
308
- ```ts
309
- const client = new FedPulse({
310
- apiKey: 'fp_live_…', // required
311
- baseUrl: 'https://api.fedpulse.dev', // optional override
312
- timeoutMs: 30_000, // per-attempt timeout (default: 30 s)
313
- maxRetries: 3, // retries for 5xx / network errors (default: 3)
314
- cacheSize: 256, // LRU cache entries, 0 to disable (default: 256)
315
- cacheTtlMs: 60_000, // cache TTL in ms (default: 60 s)
316
- });
317
- ```
318
-
319
- ### Rate limit info
320
-
321
- ```ts
322
- const { data } = await client.opportunities.list({ keyword: 'cloud' });
323
- console.log(client.rateLimit);
324
- // { limit: 1000, remaining: 987, reset: 1740000000 }
325
- ```
326
-
327
- ### Clear cache
328
-
329
- ```ts
330
- client.clearCache();
331
- ```
332
-
333
- ---
334
-
335
- ## CommonJS usage
336
-
337
- ```js
338
- const { FedPulse } = require('@fedpulse/sdk');
339
- const client = new FedPulse({ apiKey: process.env.FEDPULSE_API_KEY });
340
- ```
341
-
342
- ---
343
-
344
- ## License
345
-
346
- MIT © [FedPulse](https://fedpulse.dev)
1
+ # @fedpulse/sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@fedpulse/sdk)](https://www.npmjs.com/package/@fedpulse/sdk)
4
+ [![Node.js ≥18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Official JavaScript / TypeScript SDK for the [FedPulse API](https://fedpulse.dev). Search federal contract opportunities, check vendor exclusions, retrieve entity registrations, and access market intelligence — all with zero runtime dependencies.
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - **Typed end-to-end** — full TypeScript definitions for every request and response
14
+ - **Dual ESM + CJS** — works in Node.js (ESM / CommonJS), Deno, Bun, and bundlers
15
+ - **Zero runtime dependencies** — only uses Node.js built-ins (`fetch`, `crypto`)
16
+ - **Automatic retry** — exponential back-off with full jitter for 5xx / network errors
17
+ - **In-memory LRU cache** — 256-entry, 60 s TTL on all GET requests
18
+ - **Webhook verification** — HMAC-SHA256 signature + replay-attack protection
19
+ - **Cursor + offset pagination** — async generator helpers for all list endpoints
20
+
21
+ ---
22
+
23
+ ## Requirements
24
+
25
+ - Node.js **≥ 18.0.0** (native `fetch` + `crypto`)
26
+ - A FedPulse API key — generate one at [app.fedpulse.dev/dashboard](https://app.fedpulse.dev/dashboard)
27
+
28
+ ---
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install @fedpulse/sdk
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Quick start
39
+
40
+ ```ts
41
+ import { FedPulse } from '@fedpulse/sdk';
42
+
43
+ const client = new FedPulse({ apiKey: process.env.FEDPULSE_API_KEY! });
44
+
45
+ // Search opportunities
46
+ const result = await client.opportunities.list({
47
+ q: 'cybersecurity',
48
+ naics: ['541519', '541512'],
49
+ postedAfter: '2025-01-01',
50
+ limit: 25,
51
+ });
52
+
53
+ console.log(result.data); // typed OpportunitySummary[]
54
+ console.log(result.pagination); // { total, page, limit, … }
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Authentication
60
+
61
+ Pass your API key to the constructor. It is sent as `Authorization: Bearer <key>` on every request.
62
+
63
+ ```ts
64
+ const client = new FedPulse({ apiKey: 'fp_live_…' });
65
+ ```
66
+
67
+ Never hard-code keys in source — use environment variables.
68
+
69
+ ---
70
+
71
+ ## Resources
72
+
73
+ ### `client.opportunities`
74
+
75
+ ```ts
76
+ // List / search opportunities
77
+ await client.opportunities.list({ q: 'cloud', naics: ['541512'] });
78
+
79
+ // Retrieve a single opportunity
80
+ await client.opportunities.get('abc123-notice-id');
81
+
82
+ // Aggregate statistics
83
+ await client.opportunities.stats({ postedAfter: '2025-01-01' });
84
+
85
+ // Request a data export (async job — returns immediately with a job ID; poll exportId for status)
86
+ await client.opportunities.createExport({ format: 'csv', q: 'AI' });
87
+
88
+ // Async generator — walks all pages automatically
89
+ for await (const page of client.opportunities.paginate({ q: 'defense' })) {
90
+ console.log(page.data);
91
+ }
92
+ ```
93
+
94
+ ### `client.exclusions`
95
+
96
+ ```ts
97
+ // List all current exclusions
98
+ await client.exclusions.list({ activeOnly: true });
99
+
100
+ // Retrieve one record
101
+ await client.exclusions.get('exclusion-id');
102
+
103
+ // Bulk check up to 100 entities
104
+ await client.exclusions.check({
105
+ entities: [
106
+ { uei: 'ABC123DEF456' },
107
+ { cage: '1A2B3' },
108
+ { name: 'Acme Corp' },
109
+ ],
110
+ });
111
+
112
+ // Stats
113
+ await client.exclusions.stats();
114
+
115
+ // Page through all exclusions
116
+ for await (const page of client.exclusions.paginate()) {
117
+ console.log(page.data);
118
+ }
119
+ ```
120
+
121
+ ### `client.entities`
122
+
123
+ ```ts
124
+ // List registered entities
125
+ await client.entities.list({ naics: ['336411'], state: 'VA' });
126
+
127
+ // Entity by UEI
128
+ await client.entities.get('ABCDEF123456');
129
+
130
+ // Contracts awarded to an entity
131
+ await client.entities.opportunities('ABCDEF123456', { limit: 50 });
132
+
133
+ // Exclusion check (never cached)
134
+ await client.entities.exclusionCheck('ABCDEF123456');
135
+
136
+ // Stats
137
+ await client.entities.stats();
138
+
139
+ // All pages
140
+ for await (const page of client.entities.paginate({ state: 'TX' })) {
141
+ console.log(page.data);
142
+ }
143
+ ```
144
+
145
+ ### `client.intelligence`
146
+
147
+ ```ts
148
+ // 360° entity intelligence profile
149
+ await client.intelligence.entityProfile('ABCDEF123456');
150
+
151
+ // Market analysis for a NAICS code
152
+ await client.intelligence.marketAnalysis('541512');
153
+
154
+ // Single-entity compliance check
155
+ await client.intelligence.complianceCheck({ uei: 'ABCDEF123456' });
156
+ ```
157
+
158
+ ### `client.assistance`
159
+
160
+ Federal grants and assistance listings (CFDA programs).
161
+
162
+ ```ts
163
+ // Search listings
164
+ await client.assistance.list({ q: 'broadband', agency: 'USDA' });
165
+
166
+ // Retrieve one by CFDA program number (format: "XX.XXX")
167
+ await client.assistance.get('10.001');
168
+
169
+ // Aggregated stats
170
+ await client.assistance.stats();
171
+
172
+ // Auto-paginate all listings
173
+ for await (const page of client.assistance.paginate({ agency: 'HHS' })) {
174
+ console.log(page.data);
175
+ }
176
+ ```
177
+
178
+ ### `client.analytics`
179
+
180
+ Per-user API usage analytics — scoped to the authenticated key.
181
+
182
+ ```ts
183
+ // KPI totals (requests today, this month, error rates)
184
+ await client.analytics.summary({ range: '30d' });
185
+
186
+ // Per-day breakdown for charting (up to 90 days)
187
+ await client.analytics.chart({ range: '30d' });
188
+
189
+ // Top endpoints by request volume and P95 latency
190
+ await client.analytics.endpoints({ range: '7d' });
191
+
192
+ // Paginated raw request log
193
+ await client.analytics.logs({ limit: 20 });
194
+ ```
195
+
196
+ ### `client.webhooks`
197
+
198
+ ```ts
199
+ // List configured webhooks
200
+ await client.webhooks.list();
201
+
202
+ // Get a single webhook
203
+ await client.webhooks.get('00000000-0000-0000-0000-000000000001');
204
+
205
+ // Create
206
+ await client.webhooks.create({ url: 'https://example.com/hook', events: ['opportunity.new'] });
207
+
208
+ // Update / delete
209
+ await client.webhooks.update('00000000-0000-0000-0000-000000000001', { is_active: false });
210
+ await client.webhooks.delete('00000000-0000-0000-0000-000000000001');
211
+
212
+ // Send a test event to the endpoint immediately
213
+ await client.webhooks.test('00000000-0000-0000-0000-000000000001');
214
+
215
+ // Resume a paused webhook (auto-paused after 5 consecutive failures)
216
+ await client.webhooks.resume('00000000-0000-0000-0000-000000000001');
217
+
218
+ // Deliveries log
219
+ await client.webhooks.listDeliveries('00000000-0000-0000-0000-000000000001', { status: 'failed' });
220
+ await client.webhooks.getDelivery('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
221
+
222
+ // Auto-paginate all delivery history
223
+ for await (const page of client.webhooks.deliveryPages('00000000-0000-0000-0000-000000000001', { status: 'failed' })) {
224
+ console.log(page.data);
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Webhook signature verification
231
+
232
+ ```ts
233
+ import { FedPulse } from '@fedpulse/sdk';
234
+
235
+ // In your Express / Fastify handler:
236
+ app.post('/webhooks', (req, res) => {
237
+ const { signatureHeader, timestampHeader } = FedPulse.extractWebhookHeaders(req.headers);
238
+
239
+ let event;
240
+ try {
241
+ event = FedPulse.verifyWebhook({
242
+ rawBody: req.body, // Buffer or string — the raw unparsed body
243
+ signatureHeader,
244
+ timestampHeader,
245
+ secret: process.env.FEDPULSE_WEBHOOK_SECRET!,
246
+ options: { maxAgeSeconds: 300 },
247
+ });
248
+ } catch (err) {
249
+ return res.status(400).send('Invalid signature');
250
+ }
251
+
252
+ console.log(event.event, event.data);
253
+ res.sendStatus(200);
254
+ });
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Pagination helpers
260
+
261
+ Every list resource exposes a `paginate()` async generator that walks all pages for you:
262
+
263
+ ```ts
264
+ const allOpps: OpportunitySummary[] = [];
265
+
266
+ for await (const page of client.opportunities.paginate({ q: 'cloud' })) {
267
+ allOpps.push(...page.data);
268
+ }
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Error handling
274
+
275
+ All errors extend `FedPulseError`. Import specific classes for precise handling:
276
+
277
+ ```ts
278
+ import {
279
+ FedPulse,
280
+ AuthenticationError,
281
+ PermissionError,
282
+ NotFoundError,
283
+ ValidationError,
284
+ RateLimitError,
285
+ ServerError,
286
+ NetworkError,
287
+ TimeoutError,
288
+ RetryExhaustedError,
289
+ } from '@fedpulse/sdk';
290
+
291
+ try {
292
+ await client.opportunities.get('bad-id');
293
+ } catch (err) {
294
+ if (err instanceof NotFoundError) {
295
+ console.log('Not found');
296
+ } else if (err instanceof RateLimitError) {
297
+ console.log(`Rate limited. Retry after: ${err.retryAfter}s`);
298
+ } else if (err instanceof RetryExhaustedError) {
299
+ console.log(`Failed after ${err.attempts} attempts`, err.lastError);
300
+ } else if (err instanceof NetworkError) {
301
+ console.log('Network issuecheck internet connection');
302
+ }
303
+ }
304
+ ```
305
+
306
+ | Class | Status | When thrown |
307
+ |---|---|---|
308
+ | `AuthenticationError` | 401 | Invalid or missing API key |
309
+ | `PermissionError` | 403 | Key lacks required permission |
310
+ | `NotFoundError` | 404 | Resource does not exist |
311
+ | `ValidationError` | 400/422 | Bad request parameters |
312
+ | `RateLimitError` | 429 | Too many requests (check `retryAfter`) |
313
+ | `ServerError` | 5xx | FedPulse server error |
314
+ | `NetworkError` | | DNS failure, ECONNREFUSED, etc. |
315
+ | `TimeoutError` | | Request exceeded `timeoutMs` |
316
+ | `RetryExhaustedError` | — | All retry attempts failed |
317
+
318
+ ---
319
+
320
+ ## Configuration
321
+
322
+ ```ts
323
+ const client = new FedPulse({
324
+ apiKey: 'fp_live_…', // required
325
+ baseUrl: 'https://api.fedpulse.dev', // optional override
326
+ timeoutMs: 30_000, // per-attempt timeout (default: 30 s)
327
+ maxRetries: 3, // retries for 5xx / network errors (default: 3)
328
+ cacheSize: 256, // LRU cache entries, 0 to disable (default: 256)
329
+ cacheTtlMs: 60_000, // cache TTL in ms (default: 60 s)
330
+ });
331
+ ```
332
+
333
+ ### Rate limit info
334
+
335
+ ```ts
336
+ const { data } = await client.opportunities.list({ q: 'cloud' });
337
+ console.log(client.rateLimit);
338
+ // { limit: 1000, remaining: 987, reset: 1740000000 }
339
+ ```
340
+
341
+ ### Clear cache
342
+
343
+ ```ts
344
+ client.clearCache();
345
+ ```
346
+
347
+ ---
348
+
349
+ ## CommonJS usage
350
+
351
+ ```js
352
+ const { FedPulse } = require('@fedpulse/sdk');
353
+ const client = new FedPulse({ apiKey: process.env.FEDPULSE_API_KEY });
354
+ ```
355
+
356
+ ---
357
+
358
+ ## License
359
+
360
+ MIT © [FedPulse](https://fedpulse.dev)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedpulse/sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Official JavaScript/TypeScript SDK for the FedPulse API — federal contracts, exclusions, entities, assistance listings, and market intelligence.",
5
5
  "keywords": [
6
6
  "fedpulse",