@builtwith/sdk 1.2.0 → 1.4.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 (3) hide show
  1. package/README.md +23 -0
  2. package/package.json +1 -1
  3. package/src/index.js +48 -68
package/README.md CHANGED
@@ -60,6 +60,9 @@ if (result.ok) {
60
60
  | `financial({ lookup })` | Root domain | Financial data |
61
61
  | `social({ lookup })` | Root domain | Social profile related domains |
62
62
  | `vector_search({ query, limit? })` | Search query | Semantic technology/category search |
63
+ | `payment_discovery()` | — | Agent Payment API: credit balance |
64
+ | `payment_configuration()` | — | Agent Payment API: spending limits |
65
+ | `payment_purchase({ credits })` | Integer ≥ 2000 | Agent Payment API: purchase credits |
63
66
 
64
67
  ### Response Format
65
68
 
@@ -126,6 +129,9 @@ All methods accept a `CancellationToken` as an optional last parameter.
126
129
  | `financial(lookup)` | `string` | Financial data |
127
130
  | `social(lookup)` | `string` | Social profile related domains |
128
131
  | `vector_search(query, limit?)` | `string`, `int?` | Semantic technology/category search |
132
+ | `payment_discovery()` | — | Agent Payment API: credit balance |
133
+ | `payment_configuration()` | — | Agent Payment API: spending limits |
134
+ | `payment_purchase(credits)` | `int` ≥ 2000 | Agent Payment API: purchase credits |
129
135
 
130
136
  ### Response Format
131
137
 
@@ -148,6 +154,23 @@ BUILTWITH_API_KEY=your-key dotnet run
148
154
 
149
155
  ---
150
156
 
157
+ ## Agent Payment API
158
+
159
+ The payment methods let AI agents check credit balances, view spending configuration, and purchase credits. They route through the standard MCP endpoint using your existing API key. Configure billing at [payments.builtwith.com/agent-payment-api-config](https://payments.builtwith.com/agent-payment-api-config).
160
+
161
+ ```js
162
+ // Node.js
163
+ const result = await client.payment_discovery();
164
+ // result.data => { credits_total, credits_used, credits_available }
165
+ ```
166
+
167
+ ```csharp
168
+ // C#
169
+ var result = await client.payment_discovery();
170
+ ```
171
+
172
+ ---
173
+
151
174
  ## Prompt Helpers
152
175
 
153
176
  Both SDKs include prompt helper methods for use with AI agents:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builtwith/sdk",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "BuiltWith AI-first SDK for Node.js",
5
5
  "main": "src/index.js",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -7,7 +7,6 @@ const { URL } = require('url');
7
7
  // ── Constants ──────────────────────────────────────────────────────────────────
8
8
 
9
9
  const MCP_ENDPOINT = 'https://api.builtwith.com/mcp';
10
- const PAYMENTS_ENDPOINT = 'https://payments.builtwith.com';
11
10
  const MAX_RETRIES = 3;
12
11
  const INITIAL_BACKOFF_MS = 1000;
13
12
  const DOMAIN_RE = /^(?!-)[a-zA-Z0-9-]{1,63}(?<!-)(\.[a-zA-Z]{2,})+$/;
@@ -134,37 +133,6 @@ function _http_post(url_str, body, headers, timeout_ms) {
134
133
  });
135
134
  }
136
135
 
137
- function _http_get(url_str, headers, timeout_ms) {
138
- return new Promise((resolve, reject) => {
139
- const parsed = new URL(url_str);
140
- const transport = parsed.protocol === 'http:' ? http : https;
141
- const opts = {
142
- hostname: parsed.hostname,
143
- port: parsed.port || (parsed.protocol === 'http:' ? 80 : 443),
144
- path: parsed.pathname + parsed.search,
145
- method: 'GET',
146
- headers: {
147
- ...headers,
148
- 'Accept': 'application/json',
149
- },
150
- timeout: timeout_ms,
151
- };
152
-
153
- const req = transport.request(opts, (res) => {
154
- const chunks = [];
155
- res.on('data', chunk => chunks.push(chunk));
156
- res.on('end', () => {
157
- const raw_body = Buffer.concat(chunks).toString('utf-8');
158
- resolve({ status: res.statusCode, headers: res.headers, body: raw_body });
159
- });
160
- });
161
-
162
- req.on('error', reject);
163
- req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });
164
- req.end();
165
- });
166
- }
167
-
168
136
  // ── Client ─────────────────────────────────────────────────────────────────────
169
137
 
170
138
  class BuiltWithClient {
@@ -174,7 +142,6 @@ class BuiltWithClient {
174
142
  }
175
143
  this._api_key = api_key;
176
144
  this._endpoint = options.endpoint || MCP_ENDPOINT;
177
- this._payments_endpoint = options.payments_endpoint || PAYMENTS_ENDPOINT;
178
145
  this._max_retries = options.max_retries != null ? options.max_retries : MAX_RETRIES;
179
146
  this._timeout_ms = options.timeout_ms || 30000;
180
147
  }
@@ -271,38 +238,6 @@ class BuiltWithClient {
271
238
  return _err(last_error || new BuiltWithError('UNKNOWN_ERROR', 'Request failed', 0), mcp_tool);
272
239
  }
273
240
 
274
- // ── Payment API ────────────────────────────────────────────────────────────
275
-
276
- async _payment_request(method, path, body = null) {
277
- const url = this._payments_endpoint + path;
278
- const headers = { Authorization: `Bearer ${this._api_key}` };
279
- try {
280
- const res = method === 'GET'
281
- ? await _http_get(url, headers, this._timeout_ms)
282
- : await _http_post(url, body, headers, this._timeout_ms);
283
-
284
- const status = res.status;
285
-
286
- if (status === 400) return _err(new BuiltWithError('VALIDATION_ERROR', `HTTP 400: ${res.body.substring(0, 200)}`, status, null, 'Check request parameters.'), path);
287
- if (status === 401 || status === 403) return _err(new BuiltWithError('AUTH_ERROR', 'Authentication failed. Check your API key.', status, null, 'Verify your BuiltWith API key is correct and active.'), path);
288
- if (status === 402) return _err(new BuiltWithError('PAYMENT_FAILED', `HTTP 402: ${res.body.substring(0, 200)}`, status, null, 'Payment could not be processed. Check your billing details at payments.builtwith.com/agent-payment-api-config.'), path);
289
- if (status === 405) return _err(new BuiltWithError('METHOD_NOT_ALLOWED', `HTTP 405: wrong HTTP method.`, status), path);
290
- if (status >= 500) return _err(new BuiltWithError('SERVER_ERROR', `HTTP ${status}: ${res.body.substring(0, 200)}`, status, null, 'The server encountered an error. Try again later.'), path);
291
- if (status < 200 || status >= 300) return _err(new BuiltWithError('HTTP_ERROR', `HTTP ${status}: ${res.body.substring(0, 200)}`, status), path);
292
-
293
- let parsed;
294
- try {
295
- parsed = JSON.parse(res.body);
296
- } catch (_) {
297
- return _err(new BuiltWithError('PARSE_ERROR', 'Failed to parse response JSON.', status), path);
298
- }
299
-
300
- return _ok(parsed, parsed, path);
301
- } catch (err) {
302
- return _err(new BuiltWithError('NETWORK_ERROR', err.message, 0, null, 'Check network connectivity.'), path);
303
- }
304
- }
305
-
306
241
  // ── Public SDK methods ─────────────────────────────────────────────────────
307
242
 
308
243
  async domain_lookup_live(params) {
@@ -395,12 +330,22 @@ class BuiltWithClient {
395
330
  return this._request('vector-search', { query, ...(limit != null ? { limit } : {}) });
396
331
  }
397
332
 
333
+ async keyword_search(params) {
334
+ const { keyword, limit, offset } = params || {};
335
+ _validate_string('keyword', keyword);
336
+ return this._request('keyword-search-api', {
337
+ keyword,
338
+ ...(limit != null ? { limit } : {}),
339
+ ...(offset != null ? { offset } : {}),
340
+ });
341
+ }
342
+
398
343
  async payment_discovery() {
399
- return this._payment_request('GET', '/v1/billing/api-discovery');
344
+ return this._request('payment-balance', {});
400
345
  }
401
346
 
402
347
  async payment_configuration() {
403
- return this._payment_request('GET', '/v1/billing/api-configuration');
348
+ return this._request('payment-config', {});
404
349
  }
405
350
 
406
351
  async payment_purchase(params) {
@@ -414,7 +359,7 @@ class BuiltWithClient {
414
359
  if (credits < 2000) {
415
360
  throw new BuiltWithError('VALIDATION_ERROR', 'credits must be at least 2000.', 0, null, 'Minimum purchase is 2000 credits.');
416
361
  }
417
- return this._payment_request('POST', '/v1/billing/api-purchase', { credits });
362
+ return this._request('payment-purchase', { credits });
418
363
  }
419
364
 
420
365
  // ── Prompt helpers ─────────────────────────────────────────────────────────
@@ -448,6 +393,41 @@ class BuiltWithClient {
448
393
  _validate_domain(domain);
449
394
  return { mcp_prompt: 'check-domain-trust', arguments: { domain } };
450
395
  }
396
+
397
+ // ── Agent Device-Code Authorization (no API key required) ─────────────────
398
+
399
+ static async agent_auth_start() {
400
+ try {
401
+ const res = await _http_post('https://api.builtwith.com/agent-auth/start', {}, {}, 30000);
402
+ if (res.status < 200 || res.status >= 300) {
403
+ return _err(new BuiltWithError('HTTP_ERROR', `HTTP ${res.status}: ${res.body.substring(0, 200)}`, res.status), 'agent-auth-start');
404
+ }
405
+ let data;
406
+ try { data = JSON.parse(res.body); } catch (_) {
407
+ return _err(new BuiltWithError('PARSE_ERROR', 'Failed to parse agent-auth-start response.', res.status), 'agent-auth-start');
408
+ }
409
+ return _ok(data, data, 'agent-auth-start');
410
+ } catch (err) {
411
+ return _err(new BuiltWithError('NETWORK_ERROR', err.message, 0, null, 'Check network connectivity.'), 'agent-auth-start');
412
+ }
413
+ }
414
+
415
+ static async agent_auth_token(device_code) {
416
+ _validate_string('device_code', device_code);
417
+ try {
418
+ const res = await _http_post('https://api.builtwith.com/agent-auth/token', { device_code }, {}, 30000);
419
+ if (res.status < 200 || res.status >= 300) {
420
+ return _err(new BuiltWithError('HTTP_ERROR', `HTTP ${res.status}: ${res.body.substring(0, 200)}`, res.status), 'agent-auth-token');
421
+ }
422
+ let data;
423
+ try { data = JSON.parse(res.body); } catch (_) {
424
+ return _err(new BuiltWithError('PARSE_ERROR', 'Failed to parse agent-auth-token response.', res.status), 'agent-auth-token');
425
+ }
426
+ return _ok(data, data, 'agent-auth-token');
427
+ } catch (err) {
428
+ return _err(new BuiltWithError('NETWORK_ERROR', err.message, 0, null, 'Check network connectivity.'), 'agent-auth-token');
429
+ }
430
+ }
451
431
  }
452
432
 
453
433
  module.exports = { BuiltWithClient, BuiltWithError };