@clawpro/node 0.1.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.
package/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # @clawpro/node
2
+
3
+ Official Node.js / TypeScript SDK for the **ClawPro** Instagram outbound API — connect sending accounts, run competitor-audience campaigns, score leads, manage webhooks, and read usage.
4
+
5
+ ```bash
6
+ npm install @clawpro/node
7
+ ```
8
+
9
+ Requires Node 18+ (uses the global `fetch`). Get an API key from the [developer portal](https://tryclawpro.com) → **API & Developers → API Keys**.
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { ClawPro } from '@clawpro/node';
15
+
16
+ const clawpro = new ClawPro({ apiKey: process.env.CLAWPRO_API_KEY! });
17
+
18
+ // Connect a sending account (geo-matched mobile proxy assigned automatically)
19
+ const account = await clawpro.accounts.create({ username: 'burner_account', country: 'gb' });
20
+
21
+ // Launch a campaign against your competitors' engagers
22
+ const campaign = await clawpro.campaigns.create({
23
+ accountId: account.id,
24
+ name: 'Founders engaging with X',
25
+ targets: ['@influencer1', '@influencer2'],
26
+ offer: 'We help B2B founders book demos via Instagram outbound.',
27
+ icpCriteria: 'B2B SaaS founders or growth leads, 1–50 employees, US/UK.',
28
+ dailyDmTarget: 20,
29
+ });
30
+
31
+ await clawpro.campaigns.run(campaign.id);
32
+
33
+ // Read warm replies, then mark a lead booked (fires the `lead.booked` webhook)
34
+ const inbox = await clawpro.campaigns.inbox(campaign.id);
35
+ if (inbox[0]) await clawpro.leads.update(inbox[0].id, { status: 'booked' });
36
+ ```
37
+
38
+ ## Authentication
39
+
40
+ Every request sends your key as the `X-API-Key` header. Keys carry a scope:
41
+ `full`, `read` (GET only), or `write` (mutations only). The API is rate-limited
42
+ per key (see the `X-RateLimit-*` response headers).
43
+
44
+ ## Resources
45
+
46
+ | Resource | Methods |
47
+ |---|---|
48
+ | `accounts` | `list()`, `create()`, `delete(id)` |
49
+ | `campaigns` | `list()`, `create()`, `update(id, patch)`, `run(id)`, `leads(id, {status?})`, `inbox(id)` |
50
+ | `leads` | `update(id, { status })` |
51
+ | `webhooks` | `events()`, `list()`, `create()`, `delete(id)`, `test(id)`, `deliveries(id)` |
52
+ | `keys` | `list()`, `create()`, `revoke(id)` |
53
+ | `usage` | `summary()`, `logs(filter)` |
54
+
55
+ ## Errors
56
+
57
+ Non-2xx responses throw a typed `ClawProError`:
58
+
59
+ ```ts
60
+ import { ClawPro, ClawProError } from '@clawpro/node';
61
+
62
+ try {
63
+ await clawpro.accounts.create({ username: 'taken_handle' });
64
+ } catch (err) {
65
+ if (err instanceof ClawProError) {
66
+ console.error(err.status, err.message, err.requestId); // e.g. 409 "@taken_handle is already connected"
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ ```ts
74
+ new ClawPro({
75
+ apiKey: '...',
76
+ baseUrl: 'https://api.tryclawpro.com', // override for self-hosted / staging
77
+ timeoutMs: 30_000,
78
+ fetch: customFetch, // optional fetch override
79
+ });
80
+ ```
81
+
82
+ ## License
83
+
84
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ClawPro: () => ClawPro,
24
+ ClawProError: () => ClawProError
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var ClawProError = class extends Error {
28
+ status;
29
+ code;
30
+ requestId;
31
+ constructor(message, opts) {
32
+ super(message);
33
+ this.name = "ClawProError";
34
+ this.status = opts.status;
35
+ this.code = opts.code ?? "error";
36
+ this.requestId = opts.requestId;
37
+ }
38
+ };
39
+ var ClawPro = class {
40
+ accounts;
41
+ campaigns;
42
+ leads;
43
+ webhooks;
44
+ keys;
45
+ usage;
46
+ apiKey;
47
+ base;
48
+ fetchImpl;
49
+ timeoutMs;
50
+ constructor(opts) {
51
+ if (!opts?.apiKey) throw new Error("ClawPro: `apiKey` is required");
52
+ this.apiKey = opts.apiKey;
53
+ const origin = (opts.baseUrl ?? "https://api.tryclawpro.com").replace(/\/$/, "");
54
+ this.base = `${origin}/api/instagram`;
55
+ this.fetchImpl = opts.fetch ?? globalThis.fetch;
56
+ if (!this.fetchImpl) throw new Error("ClawPro: no fetch available \u2014 pass `fetch` (Node <18)");
57
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
58
+ this.accounts = new AccountsResource(this);
59
+ this.campaigns = new CampaignsResource(this);
60
+ this.leads = new LeadsResource(this);
61
+ this.webhooks = new WebhooksResource(this);
62
+ this.keys = new ApiKeysResource(this);
63
+ this.usage = new UsageResource(this);
64
+ }
65
+ /** @internal */
66
+ async request(method, path, opts = {}) {
67
+ const url = new URL(this.base + path);
68
+ if (opts.query) {
69
+ for (const [k, v] of Object.entries(opts.query)) {
70
+ if (v !== void 0 && v !== null && v !== "") url.searchParams.set(k, String(v));
71
+ }
72
+ }
73
+ const ctrl = new AbortController();
74
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
75
+ let res;
76
+ try {
77
+ res = await this.fetchImpl(url.toString(), {
78
+ method,
79
+ headers: {
80
+ "X-API-Key": this.apiKey,
81
+ Accept: "application/json",
82
+ ...opts.body !== void 0 ? { "Content-Type": "application/json" } : {}
83
+ },
84
+ body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
85
+ signal: ctrl.signal
86
+ });
87
+ } catch (err) {
88
+ clearTimeout(timer);
89
+ throw new ClawProError(`Network error: ${err.message}`, { status: 0, code: "network_error" });
90
+ }
91
+ clearTimeout(timer);
92
+ const requestId = res.headers.get("x-request-id") ?? void 0;
93
+ const text = await res.text();
94
+ const data = text ? safeJson(text) : void 0;
95
+ if (!res.ok) {
96
+ const message = data && (data.message || data.error) || `HTTP ${res.status}`;
97
+ throw new ClawProError(message, { status: res.status, code: data && data.error || "error", requestId });
98
+ }
99
+ return data;
100
+ }
101
+ };
102
+ function safeJson(text) {
103
+ try {
104
+ return JSON.parse(text);
105
+ } catch {
106
+ return { raw: text };
107
+ }
108
+ }
109
+ var AccountsResource = class {
110
+ constructor(c) {
111
+ this.c = c;
112
+ }
113
+ c;
114
+ /** List connected sending accounts. */
115
+ list() {
116
+ return this.c.request("GET", "/accounts").then((r) => r.accounts);
117
+ }
118
+ /** Connect a new sending account (a geo-matched mobile proxy is assigned). */
119
+ create(input) {
120
+ return this.c.request("POST", "/accounts", { body: input }).then((r) => r.account);
121
+ }
122
+ /** Remove an account (cascades to its campaigns/leads/messages). */
123
+ delete(id) {
124
+ return this.c.request("DELETE", `/accounts/${id}`);
125
+ }
126
+ };
127
+ var CampaignsResource = class {
128
+ constructor(c) {
129
+ this.c = c;
130
+ }
131
+ c;
132
+ list() {
133
+ return this.c.request("GET", "/campaigns").then((r) => r.campaigns);
134
+ }
135
+ create(input) {
136
+ return this.c.request("POST", "/campaigns", { body: input }).then((r) => r.campaign);
137
+ }
138
+ update(id, patch) {
139
+ return this.c.request("PATCH", `/campaigns/${id}`, { body: patch }).then((r) => r.campaign);
140
+ }
141
+ /** Kick a discovery/scoring/queue run for a campaign. */
142
+ run(id) {
143
+ return this.c.request("POST", `/campaigns/${id}/run`);
144
+ }
145
+ /** Leads for a campaign, optionally filtered by status. */
146
+ leads(id, opts = {}) {
147
+ return this.c.request("GET", `/campaigns/${id}/leads`, { query: { status: opts.status } }).then((r) => r.leads);
148
+ }
149
+ /** Threads with at least one message (the unified inbox). */
150
+ inbox(id) {
151
+ return this.c.request("GET", `/campaigns/${id}/inbox`).then((r) => r.threads);
152
+ }
153
+ };
154
+ var LeadsResource = class {
155
+ constructor(c) {
156
+ this.c = c;
157
+ }
158
+ c;
159
+ /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */
160
+ update(id, patch) {
161
+ return this.c.request("PATCH", `/leads/${id}`, { body: patch }).then((r) => r.lead);
162
+ }
163
+ };
164
+ var WebhooksResource = class {
165
+ constructor(c) {
166
+ this.c = c;
167
+ }
168
+ c;
169
+ /** The catalog of subscribable event types. */
170
+ events() {
171
+ return this.c.request("GET", "/webhooks/events").then((r) => r.events);
172
+ }
173
+ list() {
174
+ return this.c.request("GET", "/webhooks").then((r) => r.webhooks);
175
+ }
176
+ /** Create an endpoint. The generic HMAC `secret` is returned once, here. */
177
+ create(input) {
178
+ return this.c.request("POST", "/webhooks", { body: { type: "generic", events: ["*"], ...input } }).then((r) => r.webhook);
179
+ }
180
+ delete(id) {
181
+ return this.c.request("DELETE", `/webhooks/${id}`);
182
+ }
183
+ /** Send a `webhook.test` delivery. */
184
+ test(id) {
185
+ return this.c.request("POST", `/webhooks/${id}/test`);
186
+ }
187
+ deliveries(id) {
188
+ return this.c.request("GET", `/webhooks/${id}/deliveries`).then((r) => r.deliveries);
189
+ }
190
+ };
191
+ var ApiKeysResource = class {
192
+ constructor(c) {
193
+ this.c = c;
194
+ }
195
+ c;
196
+ list() {
197
+ return this.c.request("GET", "/keys").then((r) => r.keys);
198
+ }
199
+ /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */
200
+ create(input) {
201
+ return this.c.request("POST", "/keys", { body: input });
202
+ }
203
+ revoke(id) {
204
+ return this.c.request("DELETE", `/keys/${id}`);
205
+ }
206
+ };
207
+ var UsageResource = class {
208
+ constructor(c) {
209
+ this.c = c;
210
+ }
211
+ c;
212
+ /** Calls this month / 24h / errors / avg latency. */
213
+ summary() {
214
+ return this.c.request("GET", "/usage");
215
+ }
216
+ /** Filterable request log for the developer API. */
217
+ logs(filter = {}) {
218
+ return this.c.request("GET", "/logs", { query: filter }).then((r) => r.logs);
219
+ }
220
+ };
221
+ // Annotate the CommonJS export names for ESM import in node:
222
+ 0 && (module.exports = {
223
+ ClawPro,
224
+ ClawProError
225
+ });
226
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @clawpro/node — official SDK for the ClawPro Instagram outbound API.\n *\n * ```ts\n * import { ClawPro } from '@clawpro/node'\n * const clawpro = new ClawPro({ apiKey: process.env.CLAWPRO_API_KEY! })\n * const { accounts } = await clawpro.accounts.list()\n * ```\n */\n\n// ─────────────────────────────── Types ───────────────────────────────────────\n\nexport type AccountStatus = 'new' | 'warming' | 'active' | 'challenged' | 'banned' | 'disconnected';\nexport type ProxyType = 'mobile' | 'isp' | 'residential' | 'none';\n\nexport interface Account {\n id: string;\n username: string;\n status: AccountStatus;\n warmupTier?: number;\n dailyDmCap?: number;\n}\n\nexport type CampaignStatus = 'draft' | 'active' | 'paused';\n\nexport interface CampaignTarget {\n username: string;\n lastCheckedPostId: string | null;\n}\n\nexport interface Campaign {\n id: string;\n accountId: string;\n name: string;\n status: CampaignStatus;\n targets: CampaignTarget[];\n offer: string;\n icpCriteria: string;\n dailyDmTarget: number;\n}\n\nexport type LeadStatus =\n | 'discovered' | 'enriched' | 'scored' | 'qualified' | 'rejected'\n | 'queued' | 'dmed' | 'replied' | 'booked';\n\nexport interface Message {\n id: string;\n direction: 'out' | 'in';\n body: string;\n status: string;\n sentAt: string | null;\n createdAt: string;\n}\n\nexport interface Lead {\n id: string;\n igUsername: string;\n fullName: string | null;\n sourceTargetUsername: string;\n engagementType: 'like' | 'comment';\n commentText: string | null;\n score: number | null;\n scoreReason: string | null;\n status: LeadStatus;\n messages?: Message[];\n}\n\nexport type WebhookType = 'generic' | 'slack';\nexport type WebhookEvent =\n | 'reply.received' | 'dm.sent' | 'dm.failed'\n | 'lead.qualified' | 'lead.booked'\n | 'account.active' | 'account.challenged' | 'account.banned';\n\nexport interface Webhook {\n id: string;\n label: string;\n url: string;\n type: WebhookType;\n events: (WebhookEvent | '*')[];\n active: boolean;\n lastStatus: number | null;\n lastDeliveryAt: string | null;\n lastError: string | null;\n /** Present only on the create response (generic HMAC secret). */\n secret?: string;\n}\n\nexport interface WebhookDelivery {\n id: string;\n event: string;\n status: 'pending' | 'delivered' | 'dead';\n attempts: number;\n lastStatusCode: number | null;\n lastError: string | null;\n nextRetryAt: string | null;\n deliveredAt: string | null;\n createdAt: string;\n}\n\nexport type ApiKeyEnv = 'production' | 'development';\nexport type ApiKeyAccess = 'full' | 'read' | 'write';\n\nexport interface ApiKey {\n id: string;\n name: string;\n environment: ApiKeyEnv;\n access: ApiKeyAccess;\n keyPrefix: string;\n createdAt: string;\n expiresAt: string | null;\n lastUsedAt: string | null;\n}\n\nexport interface UsageSummary {\n callsThisMonth: number;\n calls24h: number;\n errors: number;\n avgLatencyMs: number;\n}\n\nexport interface RequestLog {\n id: string;\n requestId: string;\n method: string;\n path: string;\n status: number;\n latencyMs: number;\n error: string | null;\n createdAt: string;\n keyName: string | null;\n keyPrefix: string | null;\n}\n\n// ─────────────────────────────── Errors ──────────────────────────────────────\n\n/** Thrown for any non-2xx API response. Inspect `status` / `requestId`. */\nexport class ClawProError extends Error {\n readonly status: number;\n readonly code: string;\n readonly requestId?: string;\n constructor(message: string, opts: { status: number; code?: string; requestId?: string }) {\n super(message);\n this.name = 'ClawProError';\n this.status = opts.status;\n this.code = opts.code ?? 'error';\n this.requestId = opts.requestId;\n }\n}\n\n// ─────────────────────────────── Client ──────────────────────────────────────\n\nexport interface ClawProOptions {\n /** A `sk_live_…` / `sk_test_…` key from the developer portal. Sent as `X-API-Key`. */\n apiKey: string;\n /** API origin (no trailing slash). Defaults to https://api.tryclawpro.com */\n baseUrl?: string;\n /** Override the fetch implementation (defaults to global fetch). */\n fetch?: typeof fetch;\n /** Per-request timeout in ms (default 30000). */\n timeoutMs?: number;\n}\n\ntype Query = Record<string, string | number | boolean | undefined | null>;\n\nexport class ClawPro {\n readonly accounts: AccountsResource;\n readonly campaigns: CampaignsResource;\n readonly leads: LeadsResource;\n readonly webhooks: WebhooksResource;\n readonly keys: ApiKeysResource;\n readonly usage: UsageResource;\n\n private readonly apiKey: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: ClawProOptions) {\n if (!opts?.apiKey) throw new Error('ClawPro: `apiKey` is required');\n this.apiKey = opts.apiKey;\n const origin = (opts.baseUrl ?? 'https://api.tryclawpro.com').replace(/\\/$/, '');\n this.base = `${origin}/api/instagram`;\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!this.fetchImpl) throw new Error('ClawPro: no fetch available — pass `fetch` (Node <18)');\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n\n this.accounts = new AccountsResource(this);\n this.campaigns = new CampaignsResource(this);\n this.leads = new LeadsResource(this);\n this.webhooks = new WebhooksResource(this);\n this.keys = new ApiKeysResource(this);\n this.usage = new UsageResource(this);\n }\n\n /** @internal */\n async request<T>(method: string, path: string, opts: { body?: unknown; query?: Query } = {}): Promise<T> {\n const url = new URL(this.base + path);\n if (opts.query) {\n for (const [k, v] of Object.entries(opts.query)) {\n if (v !== undefined && v !== null && v !== '') url.searchParams.set(k, String(v));\n }\n }\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers: {\n 'X-API-Key': this.apiKey,\n Accept: 'application/json',\n ...(opts.body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: ctrl.signal,\n });\n } catch (err) {\n clearTimeout(timer);\n throw new ClawProError(`Network error: ${(err as Error).message}`, { status: 0, code: 'network_error' });\n }\n clearTimeout(timer);\n\n const requestId = res.headers.get('x-request-id') ?? undefined;\n const text = await res.text();\n const data = text ? safeJson(text) : undefined;\n if (!res.ok) {\n const message = (data && (data.message || data.error)) || `HTTP ${res.status}`;\n throw new ClawProError(message, { status: res.status, code: (data && data.error) || 'error', requestId });\n }\n return data as T;\n }\n}\n\nfunction safeJson(text: string): any {\n try { return JSON.parse(text); } catch { return { raw: text }; }\n}\n\n// ───────────────────────────── Resources ─────────────────────────────────────\n\nclass AccountsResource {\n constructor(private c: ClawPro) {}\n /** List connected sending accounts. */\n list() { return this.c.request<{ accounts: Account[] }>('GET', '/accounts').then((r) => r.accounts); }\n /** Connect a new sending account (a geo-matched mobile proxy is assigned). */\n create(input: { username: string; country?: string; proxyType?: ProxyType; proxyUrl?: string; timezone?: string }) {\n return this.c.request<{ account: Account }>('POST', '/accounts', { body: input }).then((r) => r.account);\n }\n /** Remove an account (cascades to its campaigns/leads/messages). */\n delete(id: string) { return this.c.request<{ ok: true }>('DELETE', `/accounts/${id}`); }\n}\n\nclass CampaignsResource {\n constructor(private c: ClawPro) {}\n list() { return this.c.request<{ campaigns: Campaign[] }>('GET', '/campaigns').then((r) => r.campaigns); }\n create(input: { accountId: string; name: string; targets: string[]; offer?: string; icpCriteria?: string; dailyDmTarget?: number }) {\n return this.c.request<{ campaign: Campaign }>('POST', '/campaigns', { body: input }).then((r) => r.campaign);\n }\n update(id: string, patch: Partial<{ status: CampaignStatus; targets: string[]; offer: string; icpCriteria: string; dailyDmTarget: number; name: string }>) {\n return this.c.request<{ campaign: Campaign }>('PATCH', `/campaigns/${id}`, { body: patch }).then((r) => r.campaign);\n }\n /** Kick a discovery/scoring/queue run for a campaign. */\n run(id: string) { return this.c.request<{ discovered: number; scored: number; queued: number }>('POST', `/campaigns/${id}/run`); }\n /** Leads for a campaign, optionally filtered by status. */\n leads(id: string, opts: { status?: LeadStatus } = {}) {\n return this.c.request<{ leads: Lead[] }>('GET', `/campaigns/${id}/leads`, { query: { status: opts.status } }).then((r) => r.leads);\n }\n /** Threads with at least one message (the unified inbox). */\n inbox(id: string) { return this.c.request<{ threads: Lead[] }>('GET', `/campaigns/${id}/inbox`).then((r) => r.threads); }\n}\n\nclass LeadsResource {\n constructor(private c: ClawPro) {}\n /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */\n update(id: string, patch: { status: 'qualified' | 'rejected' | 'booked' }) {\n return this.c.request<{ lead: Lead }>('PATCH', `/leads/${id}`, { body: patch }).then((r) => r.lead);\n }\n}\n\nclass WebhooksResource {\n constructor(private c: ClawPro) {}\n /** The catalog of subscribable event types. */\n events() { return this.c.request<{ events: WebhookEvent[] }>('GET', '/webhooks/events').then((r) => r.events); }\n list() { return this.c.request<{ webhooks: Webhook[] }>('GET', '/webhooks').then((r) => r.webhooks); }\n /** Create an endpoint. The generic HMAC `secret` is returned once, here. */\n create(input: { url: string; type?: WebhookType; events?: (WebhookEvent | '*')[]; label?: string }) {\n return this.c.request<{ webhook: Webhook }>('POST', '/webhooks', { body: { type: 'generic', events: ['*'], ...input } }).then((r) => r.webhook);\n }\n delete(id: string) { return this.c.request<{ ok: true }>('DELETE', `/webhooks/${id}`); }\n /** Send a `webhook.test` delivery. */\n test(id: string) { return this.c.request<unknown>('POST', `/webhooks/${id}/test`); }\n deliveries(id: string) { return this.c.request<{ deliveries: WebhookDelivery[] }>('GET', `/webhooks/${id}/deliveries`).then((r) => r.deliveries); }\n}\n\nclass ApiKeysResource {\n constructor(private c: ClawPro) {}\n list() { return this.c.request<{ keys: ApiKey[] }>('GET', '/keys').then((r) => r.keys); }\n /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */\n create(input: { name: string; environment?: ApiKeyEnv; access?: ApiKeyAccess; expiresAt?: string | null }) {\n return this.c.request<{ secret: string; key: ApiKey }>('POST', '/keys', { body: input });\n }\n revoke(id: string) { return this.c.request<{ ok: true }>('DELETE', `/keys/${id}`); }\n}\n\nexport interface LogFilter {\n key?: string; method?: string; status?: '2xx' | '4xx' | '5xx';\n from?: string; to?: string; endpoint?: string; requestId?: string; search?: string; limit?: number;\n}\n\nclass UsageResource {\n constructor(private c: ClawPro) {}\n /** Calls this month / 24h / errors / avg latency. */\n summary() { return this.c.request<UsageSummary>('GET', '/usage'); }\n /** Filterable request log for the developer API. */\n logs(filter: LogFilter = {}) {\n return this.c.request<{ logs: RequestLog[] }>('GET', '/logs', { query: filter as Query }).then((r) => r.logs);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,268 @@
1
+ /**
2
+ * @clawpro/node — official SDK for the ClawPro Instagram outbound API.
3
+ *
4
+ * ```ts
5
+ * import { ClawPro } from '@clawpro/node'
6
+ * const clawpro = new ClawPro({ apiKey: process.env.CLAWPRO_API_KEY! })
7
+ * const { accounts } = await clawpro.accounts.list()
8
+ * ```
9
+ */
10
+ type AccountStatus = 'new' | 'warming' | 'active' | 'challenged' | 'banned' | 'disconnected';
11
+ type ProxyType = 'mobile' | 'isp' | 'residential' | 'none';
12
+ interface Account {
13
+ id: string;
14
+ username: string;
15
+ status: AccountStatus;
16
+ warmupTier?: number;
17
+ dailyDmCap?: number;
18
+ }
19
+ type CampaignStatus = 'draft' | 'active' | 'paused';
20
+ interface CampaignTarget {
21
+ username: string;
22
+ lastCheckedPostId: string | null;
23
+ }
24
+ interface Campaign {
25
+ id: string;
26
+ accountId: string;
27
+ name: string;
28
+ status: CampaignStatus;
29
+ targets: CampaignTarget[];
30
+ offer: string;
31
+ icpCriteria: string;
32
+ dailyDmTarget: number;
33
+ }
34
+ type LeadStatus = 'discovered' | 'enriched' | 'scored' | 'qualified' | 'rejected' | 'queued' | 'dmed' | 'replied' | 'booked';
35
+ interface Message {
36
+ id: string;
37
+ direction: 'out' | 'in';
38
+ body: string;
39
+ status: string;
40
+ sentAt: string | null;
41
+ createdAt: string;
42
+ }
43
+ interface Lead {
44
+ id: string;
45
+ igUsername: string;
46
+ fullName: string | null;
47
+ sourceTargetUsername: string;
48
+ engagementType: 'like' | 'comment';
49
+ commentText: string | null;
50
+ score: number | null;
51
+ scoreReason: string | null;
52
+ status: LeadStatus;
53
+ messages?: Message[];
54
+ }
55
+ type WebhookType = 'generic' | 'slack';
56
+ type WebhookEvent = 'reply.received' | 'dm.sent' | 'dm.failed' | 'lead.qualified' | 'lead.booked' | 'account.active' | 'account.challenged' | 'account.banned';
57
+ interface Webhook {
58
+ id: string;
59
+ label: string;
60
+ url: string;
61
+ type: WebhookType;
62
+ events: (WebhookEvent | '*')[];
63
+ active: boolean;
64
+ lastStatus: number | null;
65
+ lastDeliveryAt: string | null;
66
+ lastError: string | null;
67
+ /** Present only on the create response (generic HMAC secret). */
68
+ secret?: string;
69
+ }
70
+ interface WebhookDelivery {
71
+ id: string;
72
+ event: string;
73
+ status: 'pending' | 'delivered' | 'dead';
74
+ attempts: number;
75
+ lastStatusCode: number | null;
76
+ lastError: string | null;
77
+ nextRetryAt: string | null;
78
+ deliveredAt: string | null;
79
+ createdAt: string;
80
+ }
81
+ type ApiKeyEnv = 'production' | 'development';
82
+ type ApiKeyAccess = 'full' | 'read' | 'write';
83
+ interface ApiKey {
84
+ id: string;
85
+ name: string;
86
+ environment: ApiKeyEnv;
87
+ access: ApiKeyAccess;
88
+ keyPrefix: string;
89
+ createdAt: string;
90
+ expiresAt: string | null;
91
+ lastUsedAt: string | null;
92
+ }
93
+ interface UsageSummary {
94
+ callsThisMonth: number;
95
+ calls24h: number;
96
+ errors: number;
97
+ avgLatencyMs: number;
98
+ }
99
+ interface RequestLog {
100
+ id: string;
101
+ requestId: string;
102
+ method: string;
103
+ path: string;
104
+ status: number;
105
+ latencyMs: number;
106
+ error: string | null;
107
+ createdAt: string;
108
+ keyName: string | null;
109
+ keyPrefix: string | null;
110
+ }
111
+ /** Thrown for any non-2xx API response. Inspect `status` / `requestId`. */
112
+ declare class ClawProError extends Error {
113
+ readonly status: number;
114
+ readonly code: string;
115
+ readonly requestId?: string;
116
+ constructor(message: string, opts: {
117
+ status: number;
118
+ code?: string;
119
+ requestId?: string;
120
+ });
121
+ }
122
+ interface ClawProOptions {
123
+ /** A `sk_live_…` / `sk_test_…` key from the developer portal. Sent as `X-API-Key`. */
124
+ apiKey: string;
125
+ /** API origin (no trailing slash). Defaults to https://api.tryclawpro.com */
126
+ baseUrl?: string;
127
+ /** Override the fetch implementation (defaults to global fetch). */
128
+ fetch?: typeof fetch;
129
+ /** Per-request timeout in ms (default 30000). */
130
+ timeoutMs?: number;
131
+ }
132
+ type Query = Record<string, string | number | boolean | undefined | null>;
133
+ declare class ClawPro {
134
+ readonly accounts: AccountsResource;
135
+ readonly campaigns: CampaignsResource;
136
+ readonly leads: LeadsResource;
137
+ readonly webhooks: WebhooksResource;
138
+ readonly keys: ApiKeysResource;
139
+ readonly usage: UsageResource;
140
+ private readonly apiKey;
141
+ private readonly base;
142
+ private readonly fetchImpl;
143
+ private readonly timeoutMs;
144
+ constructor(opts: ClawProOptions);
145
+ /** @internal */
146
+ request<T>(method: string, path: string, opts?: {
147
+ body?: unknown;
148
+ query?: Query;
149
+ }): Promise<T>;
150
+ }
151
+ declare class AccountsResource {
152
+ private c;
153
+ constructor(c: ClawPro);
154
+ /** List connected sending accounts. */
155
+ list(): Promise<Account[]>;
156
+ /** Connect a new sending account (a geo-matched mobile proxy is assigned). */
157
+ create(input: {
158
+ username: string;
159
+ country?: string;
160
+ proxyType?: ProxyType;
161
+ proxyUrl?: string;
162
+ timezone?: string;
163
+ }): Promise<Account>;
164
+ /** Remove an account (cascades to its campaigns/leads/messages). */
165
+ delete(id: string): Promise<{
166
+ ok: true;
167
+ }>;
168
+ }
169
+ declare class CampaignsResource {
170
+ private c;
171
+ constructor(c: ClawPro);
172
+ list(): Promise<Campaign[]>;
173
+ create(input: {
174
+ accountId: string;
175
+ name: string;
176
+ targets: string[];
177
+ offer?: string;
178
+ icpCriteria?: string;
179
+ dailyDmTarget?: number;
180
+ }): Promise<Campaign>;
181
+ update(id: string, patch: Partial<{
182
+ status: CampaignStatus;
183
+ targets: string[];
184
+ offer: string;
185
+ icpCriteria: string;
186
+ dailyDmTarget: number;
187
+ name: string;
188
+ }>): Promise<Campaign>;
189
+ /** Kick a discovery/scoring/queue run for a campaign. */
190
+ run(id: string): Promise<{
191
+ discovered: number;
192
+ scored: number;
193
+ queued: number;
194
+ }>;
195
+ /** Leads for a campaign, optionally filtered by status. */
196
+ leads(id: string, opts?: {
197
+ status?: LeadStatus;
198
+ }): Promise<Lead[]>;
199
+ /** Threads with at least one message (the unified inbox). */
200
+ inbox(id: string): Promise<Lead[]>;
201
+ }
202
+ declare class LeadsResource {
203
+ private c;
204
+ constructor(c: ClawPro);
205
+ /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */
206
+ update(id: string, patch: {
207
+ status: 'qualified' | 'rejected' | 'booked';
208
+ }): Promise<Lead>;
209
+ }
210
+ declare class WebhooksResource {
211
+ private c;
212
+ constructor(c: ClawPro);
213
+ /** The catalog of subscribable event types. */
214
+ events(): Promise<WebhookEvent[]>;
215
+ list(): Promise<Webhook[]>;
216
+ /** Create an endpoint. The generic HMAC `secret` is returned once, here. */
217
+ create(input: {
218
+ url: string;
219
+ type?: WebhookType;
220
+ events?: (WebhookEvent | '*')[];
221
+ label?: string;
222
+ }): Promise<Webhook>;
223
+ delete(id: string): Promise<{
224
+ ok: true;
225
+ }>;
226
+ /** Send a `webhook.test` delivery. */
227
+ test(id: string): Promise<unknown>;
228
+ deliveries(id: string): Promise<WebhookDelivery[]>;
229
+ }
230
+ declare class ApiKeysResource {
231
+ private c;
232
+ constructor(c: ClawPro);
233
+ list(): Promise<ApiKey[]>;
234
+ /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */
235
+ create(input: {
236
+ name: string;
237
+ environment?: ApiKeyEnv;
238
+ access?: ApiKeyAccess;
239
+ expiresAt?: string | null;
240
+ }): Promise<{
241
+ secret: string;
242
+ key: ApiKey;
243
+ }>;
244
+ revoke(id: string): Promise<{
245
+ ok: true;
246
+ }>;
247
+ }
248
+ interface LogFilter {
249
+ key?: string;
250
+ method?: string;
251
+ status?: '2xx' | '4xx' | '5xx';
252
+ from?: string;
253
+ to?: string;
254
+ endpoint?: string;
255
+ requestId?: string;
256
+ search?: string;
257
+ limit?: number;
258
+ }
259
+ declare class UsageResource {
260
+ private c;
261
+ constructor(c: ClawPro);
262
+ /** Calls this month / 24h / errors / avg latency. */
263
+ summary(): Promise<UsageSummary>;
264
+ /** Filterable request log for the developer API. */
265
+ logs(filter?: LogFilter): Promise<RequestLog[]>;
266
+ }
267
+
268
+ export { type Account, type AccountStatus, type ApiKey, type ApiKeyAccess, type ApiKeyEnv, type Campaign, type CampaignStatus, type CampaignTarget, ClawPro, ClawProError, type ClawProOptions, type Lead, type LeadStatus, type LogFilter, type Message, type ProxyType, type RequestLog, type UsageSummary, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookType };
@@ -0,0 +1,268 @@
1
+ /**
2
+ * @clawpro/node — official SDK for the ClawPro Instagram outbound API.
3
+ *
4
+ * ```ts
5
+ * import { ClawPro } from '@clawpro/node'
6
+ * const clawpro = new ClawPro({ apiKey: process.env.CLAWPRO_API_KEY! })
7
+ * const { accounts } = await clawpro.accounts.list()
8
+ * ```
9
+ */
10
+ type AccountStatus = 'new' | 'warming' | 'active' | 'challenged' | 'banned' | 'disconnected';
11
+ type ProxyType = 'mobile' | 'isp' | 'residential' | 'none';
12
+ interface Account {
13
+ id: string;
14
+ username: string;
15
+ status: AccountStatus;
16
+ warmupTier?: number;
17
+ dailyDmCap?: number;
18
+ }
19
+ type CampaignStatus = 'draft' | 'active' | 'paused';
20
+ interface CampaignTarget {
21
+ username: string;
22
+ lastCheckedPostId: string | null;
23
+ }
24
+ interface Campaign {
25
+ id: string;
26
+ accountId: string;
27
+ name: string;
28
+ status: CampaignStatus;
29
+ targets: CampaignTarget[];
30
+ offer: string;
31
+ icpCriteria: string;
32
+ dailyDmTarget: number;
33
+ }
34
+ type LeadStatus = 'discovered' | 'enriched' | 'scored' | 'qualified' | 'rejected' | 'queued' | 'dmed' | 'replied' | 'booked';
35
+ interface Message {
36
+ id: string;
37
+ direction: 'out' | 'in';
38
+ body: string;
39
+ status: string;
40
+ sentAt: string | null;
41
+ createdAt: string;
42
+ }
43
+ interface Lead {
44
+ id: string;
45
+ igUsername: string;
46
+ fullName: string | null;
47
+ sourceTargetUsername: string;
48
+ engagementType: 'like' | 'comment';
49
+ commentText: string | null;
50
+ score: number | null;
51
+ scoreReason: string | null;
52
+ status: LeadStatus;
53
+ messages?: Message[];
54
+ }
55
+ type WebhookType = 'generic' | 'slack';
56
+ type WebhookEvent = 'reply.received' | 'dm.sent' | 'dm.failed' | 'lead.qualified' | 'lead.booked' | 'account.active' | 'account.challenged' | 'account.banned';
57
+ interface Webhook {
58
+ id: string;
59
+ label: string;
60
+ url: string;
61
+ type: WebhookType;
62
+ events: (WebhookEvent | '*')[];
63
+ active: boolean;
64
+ lastStatus: number | null;
65
+ lastDeliveryAt: string | null;
66
+ lastError: string | null;
67
+ /** Present only on the create response (generic HMAC secret). */
68
+ secret?: string;
69
+ }
70
+ interface WebhookDelivery {
71
+ id: string;
72
+ event: string;
73
+ status: 'pending' | 'delivered' | 'dead';
74
+ attempts: number;
75
+ lastStatusCode: number | null;
76
+ lastError: string | null;
77
+ nextRetryAt: string | null;
78
+ deliveredAt: string | null;
79
+ createdAt: string;
80
+ }
81
+ type ApiKeyEnv = 'production' | 'development';
82
+ type ApiKeyAccess = 'full' | 'read' | 'write';
83
+ interface ApiKey {
84
+ id: string;
85
+ name: string;
86
+ environment: ApiKeyEnv;
87
+ access: ApiKeyAccess;
88
+ keyPrefix: string;
89
+ createdAt: string;
90
+ expiresAt: string | null;
91
+ lastUsedAt: string | null;
92
+ }
93
+ interface UsageSummary {
94
+ callsThisMonth: number;
95
+ calls24h: number;
96
+ errors: number;
97
+ avgLatencyMs: number;
98
+ }
99
+ interface RequestLog {
100
+ id: string;
101
+ requestId: string;
102
+ method: string;
103
+ path: string;
104
+ status: number;
105
+ latencyMs: number;
106
+ error: string | null;
107
+ createdAt: string;
108
+ keyName: string | null;
109
+ keyPrefix: string | null;
110
+ }
111
+ /** Thrown for any non-2xx API response. Inspect `status` / `requestId`. */
112
+ declare class ClawProError extends Error {
113
+ readonly status: number;
114
+ readonly code: string;
115
+ readonly requestId?: string;
116
+ constructor(message: string, opts: {
117
+ status: number;
118
+ code?: string;
119
+ requestId?: string;
120
+ });
121
+ }
122
+ interface ClawProOptions {
123
+ /** A `sk_live_…` / `sk_test_…` key from the developer portal. Sent as `X-API-Key`. */
124
+ apiKey: string;
125
+ /** API origin (no trailing slash). Defaults to https://api.tryclawpro.com */
126
+ baseUrl?: string;
127
+ /** Override the fetch implementation (defaults to global fetch). */
128
+ fetch?: typeof fetch;
129
+ /** Per-request timeout in ms (default 30000). */
130
+ timeoutMs?: number;
131
+ }
132
+ type Query = Record<string, string | number | boolean | undefined | null>;
133
+ declare class ClawPro {
134
+ readonly accounts: AccountsResource;
135
+ readonly campaigns: CampaignsResource;
136
+ readonly leads: LeadsResource;
137
+ readonly webhooks: WebhooksResource;
138
+ readonly keys: ApiKeysResource;
139
+ readonly usage: UsageResource;
140
+ private readonly apiKey;
141
+ private readonly base;
142
+ private readonly fetchImpl;
143
+ private readonly timeoutMs;
144
+ constructor(opts: ClawProOptions);
145
+ /** @internal */
146
+ request<T>(method: string, path: string, opts?: {
147
+ body?: unknown;
148
+ query?: Query;
149
+ }): Promise<T>;
150
+ }
151
+ declare class AccountsResource {
152
+ private c;
153
+ constructor(c: ClawPro);
154
+ /** List connected sending accounts. */
155
+ list(): Promise<Account[]>;
156
+ /** Connect a new sending account (a geo-matched mobile proxy is assigned). */
157
+ create(input: {
158
+ username: string;
159
+ country?: string;
160
+ proxyType?: ProxyType;
161
+ proxyUrl?: string;
162
+ timezone?: string;
163
+ }): Promise<Account>;
164
+ /** Remove an account (cascades to its campaigns/leads/messages). */
165
+ delete(id: string): Promise<{
166
+ ok: true;
167
+ }>;
168
+ }
169
+ declare class CampaignsResource {
170
+ private c;
171
+ constructor(c: ClawPro);
172
+ list(): Promise<Campaign[]>;
173
+ create(input: {
174
+ accountId: string;
175
+ name: string;
176
+ targets: string[];
177
+ offer?: string;
178
+ icpCriteria?: string;
179
+ dailyDmTarget?: number;
180
+ }): Promise<Campaign>;
181
+ update(id: string, patch: Partial<{
182
+ status: CampaignStatus;
183
+ targets: string[];
184
+ offer: string;
185
+ icpCriteria: string;
186
+ dailyDmTarget: number;
187
+ name: string;
188
+ }>): Promise<Campaign>;
189
+ /** Kick a discovery/scoring/queue run for a campaign. */
190
+ run(id: string): Promise<{
191
+ discovered: number;
192
+ scored: number;
193
+ queued: number;
194
+ }>;
195
+ /** Leads for a campaign, optionally filtered by status. */
196
+ leads(id: string, opts?: {
197
+ status?: LeadStatus;
198
+ }): Promise<Lead[]>;
199
+ /** Threads with at least one message (the unified inbox). */
200
+ inbox(id: string): Promise<Lead[]>;
201
+ }
202
+ declare class LeadsResource {
203
+ private c;
204
+ constructor(c: ClawPro);
205
+ /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */
206
+ update(id: string, patch: {
207
+ status: 'qualified' | 'rejected' | 'booked';
208
+ }): Promise<Lead>;
209
+ }
210
+ declare class WebhooksResource {
211
+ private c;
212
+ constructor(c: ClawPro);
213
+ /** The catalog of subscribable event types. */
214
+ events(): Promise<WebhookEvent[]>;
215
+ list(): Promise<Webhook[]>;
216
+ /** Create an endpoint. The generic HMAC `secret` is returned once, here. */
217
+ create(input: {
218
+ url: string;
219
+ type?: WebhookType;
220
+ events?: (WebhookEvent | '*')[];
221
+ label?: string;
222
+ }): Promise<Webhook>;
223
+ delete(id: string): Promise<{
224
+ ok: true;
225
+ }>;
226
+ /** Send a `webhook.test` delivery. */
227
+ test(id: string): Promise<unknown>;
228
+ deliveries(id: string): Promise<WebhookDelivery[]>;
229
+ }
230
+ declare class ApiKeysResource {
231
+ private c;
232
+ constructor(c: ClawPro);
233
+ list(): Promise<ApiKey[]>;
234
+ /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */
235
+ create(input: {
236
+ name: string;
237
+ environment?: ApiKeyEnv;
238
+ access?: ApiKeyAccess;
239
+ expiresAt?: string | null;
240
+ }): Promise<{
241
+ secret: string;
242
+ key: ApiKey;
243
+ }>;
244
+ revoke(id: string): Promise<{
245
+ ok: true;
246
+ }>;
247
+ }
248
+ interface LogFilter {
249
+ key?: string;
250
+ method?: string;
251
+ status?: '2xx' | '4xx' | '5xx';
252
+ from?: string;
253
+ to?: string;
254
+ endpoint?: string;
255
+ requestId?: string;
256
+ search?: string;
257
+ limit?: number;
258
+ }
259
+ declare class UsageResource {
260
+ private c;
261
+ constructor(c: ClawPro);
262
+ /** Calls this month / 24h / errors / avg latency. */
263
+ summary(): Promise<UsageSummary>;
264
+ /** Filterable request log for the developer API. */
265
+ logs(filter?: LogFilter): Promise<RequestLog[]>;
266
+ }
267
+
268
+ export { type Account, type AccountStatus, type ApiKey, type ApiKeyAccess, type ApiKeyEnv, type Campaign, type CampaignStatus, type CampaignTarget, ClawPro, ClawProError, type ClawProOptions, type Lead, type LeadStatus, type LogFilter, type Message, type ProxyType, type RequestLog, type UsageSummary, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookType };
package/dist/index.js ADDED
@@ -0,0 +1,200 @@
1
+ // src/index.ts
2
+ var ClawProError = class extends Error {
3
+ status;
4
+ code;
5
+ requestId;
6
+ constructor(message, opts) {
7
+ super(message);
8
+ this.name = "ClawProError";
9
+ this.status = opts.status;
10
+ this.code = opts.code ?? "error";
11
+ this.requestId = opts.requestId;
12
+ }
13
+ };
14
+ var ClawPro = class {
15
+ accounts;
16
+ campaigns;
17
+ leads;
18
+ webhooks;
19
+ keys;
20
+ usage;
21
+ apiKey;
22
+ base;
23
+ fetchImpl;
24
+ timeoutMs;
25
+ constructor(opts) {
26
+ if (!opts?.apiKey) throw new Error("ClawPro: `apiKey` is required");
27
+ this.apiKey = opts.apiKey;
28
+ const origin = (opts.baseUrl ?? "https://api.tryclawpro.com").replace(/\/$/, "");
29
+ this.base = `${origin}/api/instagram`;
30
+ this.fetchImpl = opts.fetch ?? globalThis.fetch;
31
+ if (!this.fetchImpl) throw new Error("ClawPro: no fetch available \u2014 pass `fetch` (Node <18)");
32
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
33
+ this.accounts = new AccountsResource(this);
34
+ this.campaigns = new CampaignsResource(this);
35
+ this.leads = new LeadsResource(this);
36
+ this.webhooks = new WebhooksResource(this);
37
+ this.keys = new ApiKeysResource(this);
38
+ this.usage = new UsageResource(this);
39
+ }
40
+ /** @internal */
41
+ async request(method, path, opts = {}) {
42
+ const url = new URL(this.base + path);
43
+ if (opts.query) {
44
+ for (const [k, v] of Object.entries(opts.query)) {
45
+ if (v !== void 0 && v !== null && v !== "") url.searchParams.set(k, String(v));
46
+ }
47
+ }
48
+ const ctrl = new AbortController();
49
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
50
+ let res;
51
+ try {
52
+ res = await this.fetchImpl(url.toString(), {
53
+ method,
54
+ headers: {
55
+ "X-API-Key": this.apiKey,
56
+ Accept: "application/json",
57
+ ...opts.body !== void 0 ? { "Content-Type": "application/json" } : {}
58
+ },
59
+ body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
60
+ signal: ctrl.signal
61
+ });
62
+ } catch (err) {
63
+ clearTimeout(timer);
64
+ throw new ClawProError(`Network error: ${err.message}`, { status: 0, code: "network_error" });
65
+ }
66
+ clearTimeout(timer);
67
+ const requestId = res.headers.get("x-request-id") ?? void 0;
68
+ const text = await res.text();
69
+ const data = text ? safeJson(text) : void 0;
70
+ if (!res.ok) {
71
+ const message = data && (data.message || data.error) || `HTTP ${res.status}`;
72
+ throw new ClawProError(message, { status: res.status, code: data && data.error || "error", requestId });
73
+ }
74
+ return data;
75
+ }
76
+ };
77
+ function safeJson(text) {
78
+ try {
79
+ return JSON.parse(text);
80
+ } catch {
81
+ return { raw: text };
82
+ }
83
+ }
84
+ var AccountsResource = class {
85
+ constructor(c) {
86
+ this.c = c;
87
+ }
88
+ c;
89
+ /** List connected sending accounts. */
90
+ list() {
91
+ return this.c.request("GET", "/accounts").then((r) => r.accounts);
92
+ }
93
+ /** Connect a new sending account (a geo-matched mobile proxy is assigned). */
94
+ create(input) {
95
+ return this.c.request("POST", "/accounts", { body: input }).then((r) => r.account);
96
+ }
97
+ /** Remove an account (cascades to its campaigns/leads/messages). */
98
+ delete(id) {
99
+ return this.c.request("DELETE", `/accounts/${id}`);
100
+ }
101
+ };
102
+ var CampaignsResource = class {
103
+ constructor(c) {
104
+ this.c = c;
105
+ }
106
+ c;
107
+ list() {
108
+ return this.c.request("GET", "/campaigns").then((r) => r.campaigns);
109
+ }
110
+ create(input) {
111
+ return this.c.request("POST", "/campaigns", { body: input }).then((r) => r.campaign);
112
+ }
113
+ update(id, patch) {
114
+ return this.c.request("PATCH", `/campaigns/${id}`, { body: patch }).then((r) => r.campaign);
115
+ }
116
+ /** Kick a discovery/scoring/queue run for a campaign. */
117
+ run(id) {
118
+ return this.c.request("POST", `/campaigns/${id}/run`);
119
+ }
120
+ /** Leads for a campaign, optionally filtered by status. */
121
+ leads(id, opts = {}) {
122
+ return this.c.request("GET", `/campaigns/${id}/leads`, { query: { status: opts.status } }).then((r) => r.leads);
123
+ }
124
+ /** Threads with at least one message (the unified inbox). */
125
+ inbox(id) {
126
+ return this.c.request("GET", `/campaigns/${id}/inbox`).then((r) => r.threads);
127
+ }
128
+ };
129
+ var LeadsResource = class {
130
+ constructor(c) {
131
+ this.c = c;
132
+ }
133
+ c;
134
+ /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */
135
+ update(id, patch) {
136
+ return this.c.request("PATCH", `/leads/${id}`, { body: patch }).then((r) => r.lead);
137
+ }
138
+ };
139
+ var WebhooksResource = class {
140
+ constructor(c) {
141
+ this.c = c;
142
+ }
143
+ c;
144
+ /** The catalog of subscribable event types. */
145
+ events() {
146
+ return this.c.request("GET", "/webhooks/events").then((r) => r.events);
147
+ }
148
+ list() {
149
+ return this.c.request("GET", "/webhooks").then((r) => r.webhooks);
150
+ }
151
+ /** Create an endpoint. The generic HMAC `secret` is returned once, here. */
152
+ create(input) {
153
+ return this.c.request("POST", "/webhooks", { body: { type: "generic", events: ["*"], ...input } }).then((r) => r.webhook);
154
+ }
155
+ delete(id) {
156
+ return this.c.request("DELETE", `/webhooks/${id}`);
157
+ }
158
+ /** Send a `webhook.test` delivery. */
159
+ test(id) {
160
+ return this.c.request("POST", `/webhooks/${id}/test`);
161
+ }
162
+ deliveries(id) {
163
+ return this.c.request("GET", `/webhooks/${id}/deliveries`).then((r) => r.deliveries);
164
+ }
165
+ };
166
+ var ApiKeysResource = class {
167
+ constructor(c) {
168
+ this.c = c;
169
+ }
170
+ c;
171
+ list() {
172
+ return this.c.request("GET", "/keys").then((r) => r.keys);
173
+ }
174
+ /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */
175
+ create(input) {
176
+ return this.c.request("POST", "/keys", { body: input });
177
+ }
178
+ revoke(id) {
179
+ return this.c.request("DELETE", `/keys/${id}`);
180
+ }
181
+ };
182
+ var UsageResource = class {
183
+ constructor(c) {
184
+ this.c = c;
185
+ }
186
+ c;
187
+ /** Calls this month / 24h / errors / avg latency. */
188
+ summary() {
189
+ return this.c.request("GET", "/usage");
190
+ }
191
+ /** Filterable request log for the developer API. */
192
+ logs(filter = {}) {
193
+ return this.c.request("GET", "/logs", { query: filter }).then((r) => r.logs);
194
+ }
195
+ };
196
+ export {
197
+ ClawPro,
198
+ ClawProError
199
+ };
200
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @clawpro/node — official SDK for the ClawPro Instagram outbound API.\n *\n * ```ts\n * import { ClawPro } from '@clawpro/node'\n * const clawpro = new ClawPro({ apiKey: process.env.CLAWPRO_API_KEY! })\n * const { accounts } = await clawpro.accounts.list()\n * ```\n */\n\n// ─────────────────────────────── Types ───────────────────────────────────────\n\nexport type AccountStatus = 'new' | 'warming' | 'active' | 'challenged' | 'banned' | 'disconnected';\nexport type ProxyType = 'mobile' | 'isp' | 'residential' | 'none';\n\nexport interface Account {\n id: string;\n username: string;\n status: AccountStatus;\n warmupTier?: number;\n dailyDmCap?: number;\n}\n\nexport type CampaignStatus = 'draft' | 'active' | 'paused';\n\nexport interface CampaignTarget {\n username: string;\n lastCheckedPostId: string | null;\n}\n\nexport interface Campaign {\n id: string;\n accountId: string;\n name: string;\n status: CampaignStatus;\n targets: CampaignTarget[];\n offer: string;\n icpCriteria: string;\n dailyDmTarget: number;\n}\n\nexport type LeadStatus =\n | 'discovered' | 'enriched' | 'scored' | 'qualified' | 'rejected'\n | 'queued' | 'dmed' | 'replied' | 'booked';\n\nexport interface Message {\n id: string;\n direction: 'out' | 'in';\n body: string;\n status: string;\n sentAt: string | null;\n createdAt: string;\n}\n\nexport interface Lead {\n id: string;\n igUsername: string;\n fullName: string | null;\n sourceTargetUsername: string;\n engagementType: 'like' | 'comment';\n commentText: string | null;\n score: number | null;\n scoreReason: string | null;\n status: LeadStatus;\n messages?: Message[];\n}\n\nexport type WebhookType = 'generic' | 'slack';\nexport type WebhookEvent =\n | 'reply.received' | 'dm.sent' | 'dm.failed'\n | 'lead.qualified' | 'lead.booked'\n | 'account.active' | 'account.challenged' | 'account.banned';\n\nexport interface Webhook {\n id: string;\n label: string;\n url: string;\n type: WebhookType;\n events: (WebhookEvent | '*')[];\n active: boolean;\n lastStatus: number | null;\n lastDeliveryAt: string | null;\n lastError: string | null;\n /** Present only on the create response (generic HMAC secret). */\n secret?: string;\n}\n\nexport interface WebhookDelivery {\n id: string;\n event: string;\n status: 'pending' | 'delivered' | 'dead';\n attempts: number;\n lastStatusCode: number | null;\n lastError: string | null;\n nextRetryAt: string | null;\n deliveredAt: string | null;\n createdAt: string;\n}\n\nexport type ApiKeyEnv = 'production' | 'development';\nexport type ApiKeyAccess = 'full' | 'read' | 'write';\n\nexport interface ApiKey {\n id: string;\n name: string;\n environment: ApiKeyEnv;\n access: ApiKeyAccess;\n keyPrefix: string;\n createdAt: string;\n expiresAt: string | null;\n lastUsedAt: string | null;\n}\n\nexport interface UsageSummary {\n callsThisMonth: number;\n calls24h: number;\n errors: number;\n avgLatencyMs: number;\n}\n\nexport interface RequestLog {\n id: string;\n requestId: string;\n method: string;\n path: string;\n status: number;\n latencyMs: number;\n error: string | null;\n createdAt: string;\n keyName: string | null;\n keyPrefix: string | null;\n}\n\n// ─────────────────────────────── Errors ──────────────────────────────────────\n\n/** Thrown for any non-2xx API response. Inspect `status` / `requestId`. */\nexport class ClawProError extends Error {\n readonly status: number;\n readonly code: string;\n readonly requestId?: string;\n constructor(message: string, opts: { status: number; code?: string; requestId?: string }) {\n super(message);\n this.name = 'ClawProError';\n this.status = opts.status;\n this.code = opts.code ?? 'error';\n this.requestId = opts.requestId;\n }\n}\n\n// ─────────────────────────────── Client ──────────────────────────────────────\n\nexport interface ClawProOptions {\n /** A `sk_live_…` / `sk_test_…` key from the developer portal. Sent as `X-API-Key`. */\n apiKey: string;\n /** API origin (no trailing slash). Defaults to https://api.tryclawpro.com */\n baseUrl?: string;\n /** Override the fetch implementation (defaults to global fetch). */\n fetch?: typeof fetch;\n /** Per-request timeout in ms (default 30000). */\n timeoutMs?: number;\n}\n\ntype Query = Record<string, string | number | boolean | undefined | null>;\n\nexport class ClawPro {\n readonly accounts: AccountsResource;\n readonly campaigns: CampaignsResource;\n readonly leads: LeadsResource;\n readonly webhooks: WebhooksResource;\n readonly keys: ApiKeysResource;\n readonly usage: UsageResource;\n\n private readonly apiKey: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: ClawProOptions) {\n if (!opts?.apiKey) throw new Error('ClawPro: `apiKey` is required');\n this.apiKey = opts.apiKey;\n const origin = (opts.baseUrl ?? 'https://api.tryclawpro.com').replace(/\\/$/, '');\n this.base = `${origin}/api/instagram`;\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!this.fetchImpl) throw new Error('ClawPro: no fetch available — pass `fetch` (Node <18)');\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n\n this.accounts = new AccountsResource(this);\n this.campaigns = new CampaignsResource(this);\n this.leads = new LeadsResource(this);\n this.webhooks = new WebhooksResource(this);\n this.keys = new ApiKeysResource(this);\n this.usage = new UsageResource(this);\n }\n\n /** @internal */\n async request<T>(method: string, path: string, opts: { body?: unknown; query?: Query } = {}): Promise<T> {\n const url = new URL(this.base + path);\n if (opts.query) {\n for (const [k, v] of Object.entries(opts.query)) {\n if (v !== undefined && v !== null && v !== '') url.searchParams.set(k, String(v));\n }\n }\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers: {\n 'X-API-Key': this.apiKey,\n Accept: 'application/json',\n ...(opts.body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: ctrl.signal,\n });\n } catch (err) {\n clearTimeout(timer);\n throw new ClawProError(`Network error: ${(err as Error).message}`, { status: 0, code: 'network_error' });\n }\n clearTimeout(timer);\n\n const requestId = res.headers.get('x-request-id') ?? undefined;\n const text = await res.text();\n const data = text ? safeJson(text) : undefined;\n if (!res.ok) {\n const message = (data && (data.message || data.error)) || `HTTP ${res.status}`;\n throw new ClawProError(message, { status: res.status, code: (data && data.error) || 'error', requestId });\n }\n return data as T;\n }\n}\n\nfunction safeJson(text: string): any {\n try { return JSON.parse(text); } catch { return { raw: text }; }\n}\n\n// ───────────────────────────── Resources ─────────────────────────────────────\n\nclass AccountsResource {\n constructor(private c: ClawPro) {}\n /** List connected sending accounts. */\n list() { return this.c.request<{ accounts: Account[] }>('GET', '/accounts').then((r) => r.accounts); }\n /** Connect a new sending account (a geo-matched mobile proxy is assigned). */\n create(input: { username: string; country?: string; proxyType?: ProxyType; proxyUrl?: string; timezone?: string }) {\n return this.c.request<{ account: Account }>('POST', '/accounts', { body: input }).then((r) => r.account);\n }\n /** Remove an account (cascades to its campaigns/leads/messages). */\n delete(id: string) { return this.c.request<{ ok: true }>('DELETE', `/accounts/${id}`); }\n}\n\nclass CampaignsResource {\n constructor(private c: ClawPro) {}\n list() { return this.c.request<{ campaigns: Campaign[] }>('GET', '/campaigns').then((r) => r.campaigns); }\n create(input: { accountId: string; name: string; targets: string[]; offer?: string; icpCriteria?: string; dailyDmTarget?: number }) {\n return this.c.request<{ campaign: Campaign }>('POST', '/campaigns', { body: input }).then((r) => r.campaign);\n }\n update(id: string, patch: Partial<{ status: CampaignStatus; targets: string[]; offer: string; icpCriteria: string; dailyDmTarget: number; name: string }>) {\n return this.c.request<{ campaign: Campaign }>('PATCH', `/campaigns/${id}`, { body: patch }).then((r) => r.campaign);\n }\n /** Kick a discovery/scoring/queue run for a campaign. */\n run(id: string) { return this.c.request<{ discovered: number; scored: number; queued: number }>('POST', `/campaigns/${id}/run`); }\n /** Leads for a campaign, optionally filtered by status. */\n leads(id: string, opts: { status?: LeadStatus } = {}) {\n return this.c.request<{ leads: Lead[] }>('GET', `/campaigns/${id}/leads`, { query: { status: opts.status } }).then((r) => r.leads);\n }\n /** Threads with at least one message (the unified inbox). */\n inbox(id: string) { return this.c.request<{ threads: Lead[] }>('GET', `/campaigns/${id}/inbox`).then((r) => r.threads); }\n}\n\nclass LeadsResource {\n constructor(private c: ClawPro) {}\n /** Advance a lead — e.g. `{ status: 'booked' }` once a call is set (fires `lead.booked`). */\n update(id: string, patch: { status: 'qualified' | 'rejected' | 'booked' }) {\n return this.c.request<{ lead: Lead }>('PATCH', `/leads/${id}`, { body: patch }).then((r) => r.lead);\n }\n}\n\nclass WebhooksResource {\n constructor(private c: ClawPro) {}\n /** The catalog of subscribable event types. */\n events() { return this.c.request<{ events: WebhookEvent[] }>('GET', '/webhooks/events').then((r) => r.events); }\n list() { return this.c.request<{ webhooks: Webhook[] }>('GET', '/webhooks').then((r) => r.webhooks); }\n /** Create an endpoint. The generic HMAC `secret` is returned once, here. */\n create(input: { url: string; type?: WebhookType; events?: (WebhookEvent | '*')[]; label?: string }) {\n return this.c.request<{ webhook: Webhook }>('POST', '/webhooks', { body: { type: 'generic', events: ['*'], ...input } }).then((r) => r.webhook);\n }\n delete(id: string) { return this.c.request<{ ok: true }>('DELETE', `/webhooks/${id}`); }\n /** Send a `webhook.test` delivery. */\n test(id: string) { return this.c.request<unknown>('POST', `/webhooks/${id}/test`); }\n deliveries(id: string) { return this.c.request<{ deliveries: WebhookDelivery[] }>('GET', `/webhooks/${id}/deliveries`).then((r) => r.deliveries); }\n}\n\nclass ApiKeysResource {\n constructor(private c: ClawPro) {}\n list() { return this.c.request<{ keys: ApiKey[] }>('GET', '/keys').then((r) => r.keys); }\n /** Returns `{ secret, key }` — the plaintext `secret` is shown only here. */\n create(input: { name: string; environment?: ApiKeyEnv; access?: ApiKeyAccess; expiresAt?: string | null }) {\n return this.c.request<{ secret: string; key: ApiKey }>('POST', '/keys', { body: input });\n }\n revoke(id: string) { return this.c.request<{ ok: true }>('DELETE', `/keys/${id}`); }\n}\n\nexport interface LogFilter {\n key?: string; method?: string; status?: '2xx' | '4xx' | '5xx';\n from?: string; to?: string; endpoint?: string; requestId?: string; search?: string; limit?: number;\n}\n\nclass UsageResource {\n constructor(private c: ClawPro) {}\n /** Calls this month / 24h / errors / avg latency. */\n summary() { return this.c.request<UsageSummary>('GET', '/usage'); }\n /** Filterable request log for the developer API. */\n logs(filter: LogFilter = {}) {\n return this.c.request<{ logs: RequestLog[] }>('GET', '/logs', { query: filter as Query }).then((r) => r.logs);\n }\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@clawpro/node",
3
+ "version": "0.1.0",
4
+ "description": "Official Node.js / TypeScript SDK for the ClawPro Instagram outbound API.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": ["dist", "README.md"],
17
+ "sideEffects": false,
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "typecheck": "tsc --noEmit",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "keywords": ["clawpro", "instagram", "outbound", "dm", "sdk", "api", "tryclawpro"],
24
+ "author": "ClawPro",
25
+ "license": "MIT",
26
+ "homepage": "https://tryclawpro.com",
27
+ "repository": { "type": "git", "url": "git+https://github.com/AyoAlfonso/clawpro-node.git" },
28
+ "bugs": { "url": "https://github.com/AyoAlfonso/clawpro-node/issues" },
29
+ "engines": { "node": ">=18" },
30
+ "devDependencies": {
31
+ "tsup": "^8.3.0",
32
+ "typescript": "^5.6.0"
33
+ }
34
+ }