diff --git a/tools/clis/airops.js b/tools/clis/airops.js index cd97a0d..9a99ad1 100755 --- a/tools/clis/airops.js +++ b/tools/clis/airops.js @@ -2,7 +2,7 @@ const API_KEY = process.env.AIROPS_API_KEY const WORKSPACE_ID = process.env.AIROPS_WORKSPACE_ID -const BASE_URL = 'https://api.airops.com/v1' +const BASE_URL = 'https://api.airops.com/public_api/v1' if (!API_KEY) { console.error(JSON.stringify({ error: 'AIROPS_API_KEY environment variable required' })) diff --git a/tools/clis/clay.js b/tools/clis/clay.js index 88160f8..5cfb3c9 100755 --- a/tools/clis/clay.js +++ b/tools/clis/clay.js @@ -104,8 +104,9 @@ async function main() { if (args.linkedin) body.linkedin_url = args.linkedin if (args['first-name']) body.first_name = args['first-name'] if (args['last-name']) body.last_name = args['last-name'] - if (!args.email && !args.linkedin) { - result = { error: '--email or --linkedin required' } + if (args['first-name'] && args['last-name'] && args.domain) body.domain = args.domain + if (!args.email && !args.linkedin && !(args['first-name'] && args['last-name'] && args.domain)) { + result = { error: '--email or --linkedin required (or --first-name + --last-name + --domain)' } break } result = await api('POST', '/people/enrich', body) @@ -140,7 +141,7 @@ async function main() { 'add-row': 'tables add-row --id --data ', }, people: { - enrich: 'people enrich --email | --linkedin ', + enrich: 'people enrich --email | --linkedin | --first-name --last-name --domain ', }, companies: { enrich: 'companies enrich --domain ', diff --git a/tools/clis/coupler.js b/tools/clis/coupler.js index d9a7740..0772e8e 100755 --- a/tools/clis/coupler.js +++ b/tools/clis/coupler.js @@ -10,7 +10,7 @@ if (!API_KEY) { async function api(method, path, body) { if (args['dry-run']) { - return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { 'Authorization': '***', 'Content-Type': 'application/json' }, body: body || undefined } + return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { 'Authorization': 'Bearer ***', 'Content-Type': 'application/json' }, body: body || undefined } } const res = await fetch(`${BASE_URL}${path}`, { method, diff --git a/tools/clis/outreach.js b/tools/clis/outreach.js index 0c0cb4f..daa7953 100755 --- a/tools/clis/outreach.js +++ b/tools/clis/outreach.js @@ -116,8 +116,8 @@ async function main() { data: { type: 'sequenceState', relationships: { - prospect: { data: { type: 'prospect', id: parseInt(prospectId) } }, - sequence: { data: { type: 'sequence', id: parseInt(sequenceId) } }, + prospect: { data: { type: 'prospect', id: prospectId } }, + sequence: { data: { type: 'sequence', id: sequenceId } }, }, }, } diff --git a/tools/clis/similarweb.js b/tools/clis/similarweb.js index ceb935f..66ffac6 100755 --- a/tools/clis/similarweb.js +++ b/tools/clis/similarweb.js @@ -67,7 +67,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.granularity) params.set('granularity', args.granularity) - result = await api('GET', `/website/${domain}/total-traffic-and-engagement/visits?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/total-traffic-and-engagement/visits?${params.toString()}`) break } case 'pages-per-visit': { @@ -78,7 +78,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.granularity) params.set('granularity', args.granularity) - result = await api('GET', `/website/${domain}/total-traffic-and-engagement/pages-per-visit?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/total-traffic-and-engagement/pages-per-visit?${params.toString()}`) break } case 'avg-duration': { @@ -89,7 +89,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.granularity) params.set('granularity', args.granularity) - result = await api('GET', `/website/${domain}/total-traffic-and-engagement/average-visit-duration?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/total-traffic-and-engagement/average-visit-duration?${params.toString()}`) break } case 'bounce-rate': { @@ -100,7 +100,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.granularity) params.set('granularity', args.granularity) - result = await api('GET', `/website/${domain}/total-traffic-and-engagement/bounce-rate?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/total-traffic-and-engagement/bounce-rate?${params.toString()}`) break } case 'sources': { @@ -110,7 +110,7 @@ async function main() { if (!args.end) { result = { error: '--end required (YYYY-MM)' }; break } const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) - result = await api('GET', `/website/${domain}/traffic-sources/overview?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/traffic-sources/overview?${params.toString()}`) break } default: @@ -125,7 +125,7 @@ async function main() { if (!args.end) { result = { error: '--end required (YYYY-MM)' }; break } const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) - result = await api('GET', `/website/${domain}/traffic-sources/referrals?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/traffic-sources/referrals?${params.toString()}`) break } @@ -139,7 +139,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.limit) params.set('limit', args.limit) - result = await api('GET', `/website/${domain}/search/organic-search-keywords?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/search/organic-search-keywords?${params.toString()}`) break } case 'keywords-paid': { @@ -150,7 +150,7 @@ async function main() { const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) if (args.country) params.set('country', args.country) if (args.limit) params.set('limit', args.limit) - result = await api('GET', `/website/${domain}/search/paid-search-keywords?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/search/paid-search-keywords?${params.toString()}`) break } default: @@ -161,14 +161,14 @@ async function main() { case 'competitors': { const domain = args.domain if (!domain) { result = { error: '--domain required' }; break } - result = await api('GET', `/website/${domain}/similar-sites/similarsites`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/similar-sites/similarsites`) break } case 'category-rank': { const domain = args.domain if (!domain) { result = { error: '--domain required' }; break } - result = await api('GET', `/website/${domain}/category-rank/category-rank`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/category-rank/category-rank`) break } @@ -178,7 +178,7 @@ async function main() { if (!args.start) { result = { error: '--start required (YYYY-MM)' }; break } if (!args.end) { result = { error: '--end required (YYYY-MM)' }; break } const params = new URLSearchParams({ start_date: args.start, end_date: args.end }) - result = await api('GET', `/website/${domain}/geo/traffic-by-country?${params.toString()}`) + result = await api('GET', `/website/${encodeURIComponent(domain)}/geo/traffic-by-country?${params.toString()}`) break } diff --git a/tools/clis/supermetrics.js b/tools/clis/supermetrics.js index 694c09d..26b4165 100755 --- a/tools/clis/supermetrics.js +++ b/tools/clis/supermetrics.js @@ -76,7 +76,7 @@ async function main() { if (args['max-rows']) body.max_rows = parseInt(args['max-rows'], 10) if (args['start-date']) body.start_date = args['start-date'] if (args['end-date']) body.end_date = args['end-date'] - result = await api('POST', '/query', body) + result = await api('POST', '/query/data/json', body) break } diff --git a/tools/clis/zoominfo.js b/tools/clis/zoominfo.js index 05a1a5c..6ab1aaf 100755 --- a/tools/clis/zoominfo.js +++ b/tools/clis/zoominfo.js @@ -22,11 +22,16 @@ async function authenticate() { body: JSON.stringify({ username, password }), }) const text = await res.text() + if (!res.ok) { + throw new Error(`Authentication failed (${res.status}): ${text}`) + } try { const data = JSON.parse(text) + if (!data.jwt) throw new Error('No JWT in response') ACCESS_TOKEN = data.jwt return ACCESS_TOKEN - } catch { + } catch (e) { + if (e.message === 'No JWT in response') throw e throw new Error(`Authentication failed: ${text}`) } } @@ -82,6 +87,10 @@ async function main() { switch (cmd) { case 'auth': { + if (args['dry-run']) { + result = { _dry_run: true, action: 'authenticate', url: `${BASE_URL}/authenticate`, jwt: '***' } + break + } const token = await authenticate() result = { jwt: token } break diff --git a/tools/integrations/airops.md b/tools/integrations/airops.md index f1c056b..f003bc6 100644 --- a/tools/integrations/airops.md +++ b/tools/integrations/airops.md @@ -23,19 +23,19 @@ AI content platform for crafting content that wins AI search. Build and execute ### List Flows ```bash -GET https://api.airops.com/v1/workspaces/{workspace_id}/flows +GET https://api.airops.com/public_api/v1/workspaces/{workspace_id}/flows ``` ### Get Flow Details ```bash -GET https://api.airops.com/v1/workspaces/{workspace_id}/flows/{flow_id} +GET https://api.airops.com/public_api/v1/workspaces/{workspace_id}/flows/{flow_id} ``` ### Execute a Flow ```bash -POST https://api.airops.com/v1/workspaces/{workspace_id}/flows/{flow_id}/execute +POST https://api.airops.com/public_api/v1/workspaces/{workspace_id}/flows/{flow_id}/execute { "inputs": { @@ -48,25 +48,25 @@ POST https://api.airops.com/v1/workspaces/{workspace_id}/flows/{flow_id}/execute ### List Runs for a Flow ```bash -GET https://api.airops.com/v1/workspaces/{workspace_id}/flows/{flow_id}/runs +GET https://api.airops.com/public_api/v1/workspaces/{workspace_id}/flows/{flow_id}/runs ``` ### Get Run Status ```bash -GET https://api.airops.com/v1/workspaces/{workspace_id}/runs/{run_id} +GET https://api.airops.com/public_api/v1/workspaces/{workspace_id}/runs/{run_id} ``` ### List Workflows ```bash -GET https://api.airops.com/v1/workspaces/{workspace_id}/workflows +GET https://api.airops.com/public_api/v1/workspaces/{workspace_id}/workflows ``` ### Execute a Workflow ```bash -POST https://api.airops.com/v1/workspaces/{workspace_id}/workflows/{workflow_id}/execute +POST https://api.airops.com/public_api/v1/workspaces/{workspace_id}/workflows/{workflow_id}/execute { "inputs": { diff --git a/tools/integrations/close.md b/tools/integrations/close.md index a623d46..b32c386 100644 --- a/tools/integrations/close.md +++ b/tools/integrations/close.md @@ -181,7 +181,7 @@ POST https://api.close.com/api/v1/task/ - Rate limits based on organization plan - Standard: ~100 requests/minute -- Responses include `X-Rate-Limit-Limit` and `X-Rate-Limit-Remaining` headers +- Responses include `ratelimit-limit` and `ratelimit-remaining` headers - 429 responses include `Retry-After` header ## Relevant Skills diff --git a/tools/integrations/pendo.md b/tools/integrations/pendo.md index 083839d..a50d953 100644 --- a/tools/integrations/pendo.md +++ b/tools/integrations/pendo.md @@ -46,7 +46,7 @@ GET https://app.pendo.io/api/v1/page/{pageId} ### List Guides ```bash -GET https://app.pendo.io/api/v1/guide?state=published +GET https://app.pendo.io/api/v1/guide?state=public ``` ### Get Guide Details diff --git a/tools/integrations/supermetrics.md b/tools/integrations/supermetrics.md index 9c301e1..25aa25f 100644 --- a/tools/integrations/supermetrics.md +++ b/tools/integrations/supermetrics.md @@ -22,7 +22,7 @@ Marketing data pipeline that connects 200+ marketing platforms. Pulls data from ### Query a Data Source ```bash -POST https://api.supermetrics.com/enterprise/v2/query +POST https://api.supermetrics.com/enterprise/v2/query/data/json { "ds_id": "GA4", @@ -39,7 +39,7 @@ POST https://api.supermetrics.com/enterprise/v2/query ### Query with Filters ```bash -POST https://api.supermetrics.com/enterprise/v2/query +POST https://api.supermetrics.com/enterprise/v2/query/data/json { "ds_id": "AW",