@myapihq/sdk 2.21.0 → 2.22.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/dist/email.d.ts CHANGED
@@ -155,3 +155,77 @@ export declare function sendTestEmail(apiKey: string, orgId: string, templateId:
155
155
  }>;
156
156
  export declare function listTemplates(apiKey: string, orgId: string): Promise<EmailTemplate[]>;
157
157
  export declare function deleteTemplate(apiKey: string, orgId: string, templateId: string): Promise<void>;
158
+ export type CampaignSourceKind = 'crm_query' | 'list';
159
+ /** A CRM contact filter, mirroring `crm contacts search`. */
160
+ export interface CampaignCRMQuery {
161
+ stage?: string;
162
+ origin?: string;
163
+ company_id?: string;
164
+ /** Engaged MORE than N days ago — includes contacts never engaged at all. */
165
+ max_last_engagement_days?: number;
166
+ /** Engaged within the last N days. */
167
+ min_last_engagement_days?: number;
168
+ }
169
+ export interface CampaignListSource {
170
+ addresses: string[];
171
+ }
172
+ export interface CreateCampaignInput {
173
+ name: string;
174
+ template_id: string;
175
+ from_address: string;
176
+ source_kind: CampaignSourceKind;
177
+ source_ref?: CampaignCRMQuery | CampaignListSource;
178
+ }
179
+ export interface Campaign {
180
+ id: string;
181
+ org_id: string;
182
+ name: string;
183
+ template_id: string;
184
+ from_address: string;
185
+ source_kind: CampaignSourceKind;
186
+ source_ref: unknown;
187
+ /** draft | ready | active | paused | paused_insufficient_funds | completed | cancelled */
188
+ status: string;
189
+ resolved_at: string | null;
190
+ recipient_count: number | null;
191
+ estimated_cost_cents: number | null;
192
+ created_at: string;
193
+ updated_at: string;
194
+ }
195
+ export interface CampaignResolution {
196
+ status: string;
197
+ recipients: number;
198
+ /** Counts by reason: suppressed, duplicate, invalid. */
199
+ excluded: Record<string, number>;
200
+ source_rows: number;
201
+ estimated_cost_cents: number;
202
+ note: string;
203
+ }
204
+ export interface CampaignRecipient {
205
+ id: string;
206
+ address: string;
207
+ contact_id: string | null;
208
+ state: string;
209
+ excluded_reason: string | null;
210
+ message_id: string | null;
211
+ error: string | null;
212
+ sent_at: string | null;
213
+ }
214
+ export interface CampaignStats {
215
+ status: string;
216
+ by_state: Record<string, number>;
217
+ sent_today: number;
218
+ per_day_limit: number;
219
+ }
220
+ export declare function createCampaign(apiKey: string, orgId: string, input: CreateCampaignInput): Promise<Campaign>;
221
+ export declare function listCampaigns(apiKey: string, orgId: string): Promise<Campaign[]>;
222
+ export declare function getCampaign(apiKey: string, orgId: string, id: string): Promise<Campaign>;
223
+ export declare function updateCampaign(apiKey: string, orgId: string, id: string, patch: Partial<CreateCampaignInput>): Promise<Campaign>;
224
+ /** Freezes the recipient set and reports who it reaches and what it would cost. Sends nothing. */
225
+ export declare function resolveCampaign(apiKey: string, orgId: string, id: string): Promise<CampaignResolution>;
226
+ export declare function startCampaign(apiKey: string, orgId: string, id: string): Promise<Campaign>;
227
+ export declare function pauseCampaign(apiKey: string, orgId: string, id: string): Promise<Campaign>;
228
+ export declare function resumeCampaign(apiKey: string, orgId: string, id: string): Promise<Campaign>;
229
+ export declare function cancelCampaign(apiKey: string, orgId: string, id: string): Promise<Campaign>;
230
+ export declare function listCampaignRecipients(apiKey: string, orgId: string, id: string, state?: string): Promise<CampaignRecipient[]>;
231
+ export declare function getCampaignStats(apiKey: string, orgId: string, id: string): Promise<CampaignStats>;
package/dist/email.js CHANGED
@@ -30,6 +30,17 @@ exports.editTemplate = editTemplate;
30
30
  exports.sendTestEmail = sendTestEmail;
31
31
  exports.listTemplates = listTemplates;
32
32
  exports.deleteTemplate = deleteTemplate;
33
+ exports.createCampaign = createCampaign;
34
+ exports.listCampaigns = listCampaigns;
35
+ exports.getCampaign = getCampaign;
36
+ exports.updateCampaign = updateCampaign;
37
+ exports.resolveCampaign = resolveCampaign;
38
+ exports.startCampaign = startCampaign;
39
+ exports.pauseCampaign = pauseCampaign;
40
+ exports.resumeCampaign = resumeCampaign;
41
+ exports.cancelCampaign = cancelCampaign;
42
+ exports.listCampaignRecipients = listCampaignRecipients;
43
+ exports.getCampaignStats = getCampaignStats;
33
44
  const client_1 = require("./client");
34
45
  const config_1 = require("./config");
35
46
  exports.EXPOSES = [
@@ -67,6 +78,18 @@ exports.EXPOSES = [
67
78
  'POST /email/orgs/{org_id}/verify',
68
79
  'POST /email/orgs/{org_id}/verify-bulk',
69
80
  'GET /email/orgs/{org_id}/verify-jobs/{id}',
81
+ // Campaigns — scheduling on top of send
82
+ 'POST /email/orgs/{org_id}/campaigns',
83
+ 'GET /email/orgs/{org_id}/campaigns',
84
+ 'GET /email/orgs/{org_id}/campaigns/{campaign_id}',
85
+ 'PATCH /email/orgs/{org_id}/campaigns/{campaign_id}',
86
+ 'POST /email/orgs/{org_id}/campaigns/{campaign_id}/resolve',
87
+ 'POST /email/orgs/{org_id}/campaigns/{campaign_id}/start',
88
+ 'POST /email/orgs/{org_id}/campaigns/{campaign_id}/pause',
89
+ 'POST /email/orgs/{org_id}/campaigns/{campaign_id}/resume',
90
+ 'POST /email/orgs/{org_id}/campaigns/{campaign_id}/cancel',
91
+ 'GET /email/orgs/{org_id}/campaigns/{campaign_id}/recipients',
92
+ 'GET /email/orgs/{org_id}/campaigns/{campaign_id}/stats',
70
93
  ];
71
94
  async function verifyEmail(apiKey, orgId, email) {
72
95
  return (0, client_1.request)('POST', `${config_1.EMAIL_BASE}/email/orgs/${encodeURIComponent(orgId)}/verify`, apiKey, { email });
@@ -197,3 +220,47 @@ async function listTemplates(apiKey, orgId) {
197
220
  async function deleteTemplate(apiKey, orgId, templateId) {
198
221
  return (0, client_1.request)('DELETE', `${config_1.EMAIL_BASE}/email/orgs/${encodeURIComponent(orgId)}/templates/${encodeURIComponent(templateId)}`, apiKey);
199
222
  }
223
+ function campaignsUrl(orgId) {
224
+ return `${config_1.EMAIL_BASE}/email/orgs/${encodeURIComponent(orgId)}/campaigns`;
225
+ }
226
+ function campaignUrl(orgId, id) {
227
+ return `${campaignsUrl(orgId)}/${encodeURIComponent(id)}`;
228
+ }
229
+ async function createCampaign(apiKey, orgId, input) {
230
+ return (0, client_1.request)('POST', campaignsUrl(orgId), apiKey, input);
231
+ }
232
+ // Walks the cursor: one page is not the whole list.
233
+ async function listCampaigns(apiKey, orgId) {
234
+ return (0, client_1.requestAll)(campaignsUrl(orgId), apiKey);
235
+ }
236
+ async function getCampaign(apiKey, orgId, id) {
237
+ return (0, client_1.request)('GET', campaignUrl(orgId, id), apiKey);
238
+ }
239
+ async function updateCampaign(apiKey, orgId, id, patch) {
240
+ return (0, client_1.request)('PATCH', campaignUrl(orgId, id), apiKey, patch);
241
+ }
242
+ /** Freezes the recipient set and reports who it reaches and what it would cost. Sends nothing. */
243
+ async function resolveCampaign(apiKey, orgId, id) {
244
+ return (0, client_1.request)('POST', `${campaignUrl(orgId, id)}/resolve`, apiKey);
245
+ }
246
+ async function startCampaign(apiKey, orgId, id) {
247
+ return (0, client_1.request)('POST', `${campaignUrl(orgId, id)}/start`, apiKey);
248
+ }
249
+ async function pauseCampaign(apiKey, orgId, id) {
250
+ return (0, client_1.request)('POST', `${campaignUrl(orgId, id)}/pause`, apiKey);
251
+ }
252
+ async function resumeCampaign(apiKey, orgId, id) {
253
+ return (0, client_1.request)('POST', `${campaignUrl(orgId, id)}/resume`, apiKey);
254
+ }
255
+ async function cancelCampaign(apiKey, orgId, id) {
256
+ return (0, client_1.request)('POST', `${campaignUrl(orgId, id)}/cancel`, apiKey);
257
+ }
258
+ async function listCampaignRecipients(apiKey, orgId, id, state) {
259
+ const url = state
260
+ ? `${campaignUrl(orgId, id)}/recipients?state=${encodeURIComponent(state)}`
261
+ : `${campaignUrl(orgId, id)}/recipients`;
262
+ return (0, client_1.requestAll)(url, apiKey);
263
+ }
264
+ async function getCampaignStats(apiKey, orgId, id) {
265
+ return (0, client_1.request)('GET', `${campaignUrl(orgId, id)}/stats`, apiKey);
266
+ }
package/dist/hq.d.ts CHANGED
@@ -76,6 +76,30 @@ export type FreeTierEntry = {
76
76
  reset_at?: string;
77
77
  };
78
78
  export declare function getFreeTier(apiKey: string): Promise<FreeTierEntry[] | null>;
79
+ export interface SendingStatus {
80
+ sending_paused: boolean;
81
+ sends_24h: number;
82
+ bounces_24h: number;
83
+ complaints_24h: number;
84
+ bounce_threshold: number;
85
+ complaint_threshold: number;
86
+ within_limits: boolean;
87
+ /** Why it was paused, as recorded THEN — not whether it would pause now. */
88
+ paused_reason_when_paused?: string;
89
+ /** Present only while paused: whether a resume would be accepted today. */
90
+ can_resume_now?: boolean;
91
+ /** Set when under 100 sends in 24h, where the ratios are not judged. */
92
+ note?: string;
93
+ }
94
+ export interface ResumeSendingResult {
95
+ sending_paused: boolean;
96
+ resumed: boolean;
97
+ sends: number;
98
+ bounces: number;
99
+ message: string;
100
+ }
101
+ export declare function getSendingStatus(apiKey: string): Promise<SendingStatus>;
102
+ export declare function resumeSending(apiKey: string): Promise<ResumeSendingResult>;
79
103
  export declare function getAccount(apiKey: string): Promise<AccountInfo>;
80
104
  export declare function getMailingAddress(apiKey: string): Promise<{
81
105
  mailing_address: string | null;
package/dist/hq.js CHANGED
@@ -6,6 +6,8 @@ exports.sendCode = sendCode;
6
6
  exports.verifyCode = verifyCode;
7
7
  exports.upgradeAccount = upgradeAccount;
8
8
  exports.getFreeTier = getFreeTier;
9
+ exports.getSendingStatus = getSendingStatus;
10
+ exports.resumeSending = resumeSending;
9
11
  exports.getAccount = getAccount;
10
12
  exports.getMailingAddress = getMailingAddress;
11
13
  exports.setMailingAddress = setMailingAddress;
@@ -42,6 +44,8 @@ exports.EXPOSES = [
42
44
  'PATCH /hq/account/upgrade',
43
45
  'GET /hq/account/me',
44
46
  'GET /hq/account/free-tier',
47
+ 'GET /hq/account/sending',
48
+ 'POST /hq/account/resume-sending',
45
49
  'POST /hq/account/create/key',
46
50
  'GET /hq/account/keys',
47
51
  'POST /hq/account/keys/revoke-all',
@@ -92,6 +96,13 @@ async function upgradeAccount(apiKey, email) {
92
96
  async function getFreeTier(apiKey) {
93
97
  return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/account/free-tier`, apiKey);
94
98
  }
99
+ async function getSendingStatus(apiKey) {
100
+ return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/account/sending`, apiKey);
101
+ }
102
+ // Rejected with STILL_OVER_THRESHOLD while the last 24h remain over the limit.
103
+ async function resumeSending(apiKey) {
104
+ return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/account/resume-sending`, apiKey);
105
+ }
95
106
  async function getAccount(apiKey) {
96
107
  return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/account/me`, apiKey);
97
108
  }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "2.21.0";
1
+ export declare const SDK_VERSION = "2.22.0";
package/dist/version.js CHANGED
@@ -8,4 +8,4 @@ exports.SDK_VERSION = void 0;
8
8
  // Why a constant and not a package.json read: the SDK runs inside edge
9
9
  // functions (Cloudflare Workers), so it must not import node:fs. A literal
10
10
  // is the only version source that works in every runtime we ship to.
11
- exports.SDK_VERSION = '2.21.0';
11
+ exports.SDK_VERSION = '2.22.0';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@myapihq/sdk",
3
3
  "license": "Apache-2.0",
4
- "version": "2.21.0",
4
+ "version": "2.22.0",
5
5
  "description": "TypeScript SDK for the MyAPI ecosystem",
6
6
  "repository": {
7
7
  "type": "git",