shipmail 0.1.32 → 0.2.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 CHANGED
@@ -87,6 +87,7 @@ const shipmail = new ShipMailClient({
87
87
  timeout: 30_000,
88
88
  fetch: customFetch,
89
89
  defaultHeaders: { "x-app-name": "my-app" },
90
+ organizationId: "00000000-0000-4000-8000-000000000123",
90
91
  });
91
92
  ```
92
93
 
@@ -98,6 +99,7 @@ const shipmail = new ShipMailClient({
98
99
  | `timeout` | `number` | `30_000` | Per-request timeout in ms. |
99
100
  | `fetch` | `typeof fetch` | `globalThis.fetch` | Custom fetch implementation. |
100
101
  | `defaultHeaders` | `Record<string, string>` | `{}` | Headers added to every request. |
102
+ | `organizationId` | `string` | none | Delegated child organization for approved infrastructure calls. |
101
103
 
102
104
  ## Domains
103
105
 
@@ -142,6 +144,12 @@ const forwarding = await shipmail.mailboxes.createForwarding("mbx_...", {
142
144
  });
143
145
  const forwardingList = await shipmail.mailboxes.listForwarding("mbx_...");
144
146
  await shipmail.mailboxes.deleteForwarding("mbx_...", forwarding.id);
147
+ const appPassword = await shipmail.mailboxes.createAppPassword("mbx_...", {
148
+ name: "Desktop mail",
149
+ expires_at: "2026-10-01T00:00:00Z",
150
+ });
151
+ const appPasswords = await shipmail.mailboxes.listAppPasswords("mbx_...");
152
+ await shipmail.mailboxes.revokeAppPassword("mbx_...", appPassword.id);
145
153
  const folders = await shipmail.mailboxes.listFolders("mbx_...");
146
154
  const folder = await shipmail.mailboxes.createFolder("mbx_...", {
147
155
  name: "VIP",
@@ -349,6 +357,50 @@ URLs, and video thumbnails contribute to deliverability checks.
349
357
  Block prose fields are plain text in API requests. Use newlines for paragraph
350
358
  breaks, and use `body_html` or `custom_html` only when you need raw HTML.
351
359
 
360
+ ## Partner beta
361
+
362
+ Approved partner accounts can create isolated operator-owned organizations and read consolidated
363
+ usage:
364
+
365
+ ```ts
366
+ const child = await shipmail.partner.createOrganization(
367
+ {
368
+ name: "Operator",
369
+ external_reference: "operator_123",
370
+ owner_email: "owner@example.com",
371
+ mailbox_limit: 3,
372
+ data_classification: "internal_test",
373
+ },
374
+ { idempotencyKey: "operator-123" },
375
+ );
376
+
377
+ const delegated = new ShipMailClient({
378
+ apiKey: process.env.SHIPMAIL_API_KEY!,
379
+ organizationId: child.organization_id,
380
+ });
381
+
382
+ await delegated.domains.list();
383
+ await delegated.mailboxes.create({
384
+ domain_id: "dom_...",
385
+ address: "support",
386
+ generate_password: true,
387
+ });
388
+ const grants = await shipmail.partner.listMailboxCredentialGrants();
389
+ const credential = await shipmail.partner.consumeMailboxCredentialGrant(grants.data[0]!.id, {
390
+ name: "Embedded webmail",
391
+ });
392
+ await shipmail.partner.usage();
393
+ ```
394
+
395
+ Use a separate client for delegated infrastructure. Partner target context is not accepted by
396
+ message, thread, calendar, contacts, export, suppression, billing, or password endpoints. The beta
397
+ requires Shipmail approval and externally owned domains. Delegated mailbox creation must use
398
+ `generate_password: true`; the generated primary password is never returned to the partner.
399
+ The operator creates a one-time credential grant. Consuming it requires the exact
400
+ `partner:mailbox_credentials:issue` scope and returns the app-password secret once. App-password
401
+ creation and grant consumption do not accept idempotency keys because their plaintext response must
402
+ never be cached.
403
+
352
404
  ## Status
353
405
 
354
406
  ```ts
@@ -435,6 +487,7 @@ type MethodOptions = {
435
487
  signal?: AbortSignal;
436
488
  headers?: Record<string, string>;
437
489
  idempotencyKey?: string;
490
+ organizationId?: string;
438
491
  };
439
492
  ```
440
493
 
package/dist/index.cjs CHANGED
@@ -681,6 +681,28 @@ var Mailboxes = class extends ApiResource {
681
681
  methodOptions: options
682
682
  });
683
683
  }
684
+ listAppPasswords(id, options) {
685
+ return this.client.request({
686
+ method: "GET",
687
+ path: `/mailboxes/${encodeURIComponent(id)}/app-passwords`,
688
+ methodOptions: options
689
+ });
690
+ }
691
+ createAppPassword(id, params, options) {
692
+ return this.client.request({
693
+ method: "POST",
694
+ path: `/mailboxes/${encodeURIComponent(id)}/app-passwords`,
695
+ body: params,
696
+ methodOptions: options
697
+ });
698
+ }
699
+ revokeAppPassword(id, appPasswordId, options) {
700
+ return this.client.request({
701
+ method: "DELETE",
702
+ path: `/mailboxes/${encodeURIComponent(id)}/app-passwords/${encodeURIComponent(appPasswordId)}`,
703
+ methodOptions: options
704
+ });
705
+ }
684
706
  getRules(id, options) {
685
707
  return this.client.request({
686
708
  method: "GET",
@@ -978,6 +1000,87 @@ var Newsletters = class extends ApiResource {
978
1000
  }
979
1001
  };
980
1002
 
1003
+ // src/resources/partner.ts
1004
+ var Partner = class extends ApiResource {
1005
+ listOrganizations(options) {
1006
+ return this.client.request({
1007
+ method: "GET",
1008
+ path: "/partner/organizations",
1009
+ methodOptions: options
1010
+ });
1011
+ }
1012
+ createOrganization(params, options) {
1013
+ return this.client.request({
1014
+ method: "POST",
1015
+ path: "/partner/organizations",
1016
+ body: params,
1017
+ methodOptions: options
1018
+ });
1019
+ }
1020
+ getOrganization(id, options) {
1021
+ return this.client.request({
1022
+ method: "GET",
1023
+ path: `/partner/organizations/${encodeURIComponent(id)}`,
1024
+ methodOptions: options
1025
+ });
1026
+ }
1027
+ updateOrganization(id, params, options) {
1028
+ return this.client.request({
1029
+ method: "PATCH",
1030
+ path: `/partner/organizations/${encodeURIComponent(id)}`,
1031
+ body: params,
1032
+ methodOptions: options
1033
+ });
1034
+ }
1035
+ resendOwnershipInvitation(id, params = {}, options) {
1036
+ return this.client.request({
1037
+ method: "POST",
1038
+ path: `/partner/organizations/${encodeURIComponent(id)}/ownership-invitations`,
1039
+ body: params,
1040
+ methodOptions: options
1041
+ });
1042
+ }
1043
+ suspendOrganization(id, options) {
1044
+ return this.client.request({
1045
+ method: "POST",
1046
+ path: `/partner/organizations/${encodeURIComponent(id)}/suspend`,
1047
+ methodOptions: options
1048
+ });
1049
+ }
1050
+ resumeOrganization(id, options) {
1051
+ return this.client.request({
1052
+ method: "POST",
1053
+ path: `/partner/organizations/${encodeURIComponent(id)}/resume`,
1054
+ methodOptions: options
1055
+ });
1056
+ }
1057
+ offboardOrganization(id, options) {
1058
+ return this.client.request({
1059
+ method: "DELETE",
1060
+ path: `/partner/organizations/${encodeURIComponent(id)}`,
1061
+ methodOptions: options
1062
+ });
1063
+ }
1064
+ listMailboxCredentialGrants(options) {
1065
+ return this.client.request({
1066
+ method: "GET",
1067
+ path: "/partner/mailbox-credential-grants",
1068
+ methodOptions: options
1069
+ });
1070
+ }
1071
+ consumeMailboxCredentialGrant(grantId, params = {}, options) {
1072
+ return this.client.request({
1073
+ method: "POST",
1074
+ path: `/partner/mailbox-credential-grants/${encodeURIComponent(grantId)}/consume`,
1075
+ body: params,
1076
+ methodOptions: options
1077
+ });
1078
+ }
1079
+ usage(options) {
1080
+ return this.client.request({ method: "GET", path: "/partner/usage", methodOptions: options });
1081
+ }
1082
+ };
1083
+
981
1084
  // src/resources/status.ts
982
1085
  var Status = class extends ApiResource {
983
1086
  get(options) {
@@ -1160,7 +1263,7 @@ var Webhooks = class extends ApiResource {
1160
1263
  };
1161
1264
 
1162
1265
  // src/version.ts
1163
- var VERSION = "0.1.32";
1266
+ var VERSION = "0.2.0";
1164
1267
 
1165
1268
  // src/client.ts
1166
1269
  var DEFAULT_BASE_URL = "https://shipmail.to/api/v1";
@@ -1203,6 +1306,7 @@ var ShipMailClient = class {
1203
1306
  this.timeout = DEFAULT_TIMEOUT;
1204
1307
  this.fetchFn = globalThis.fetch;
1205
1308
  this.defaultHeaders = {};
1309
+ this.organizationId = void 0;
1206
1310
  } else {
1207
1311
  this.apiKey = config.apiKey;
1208
1312
  this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
@@ -1210,6 +1314,7 @@ var ShipMailClient = class {
1210
1314
  this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
1211
1315
  this.fetchFn = config.fetch ?? globalThis.fetch;
1212
1316
  this.defaultHeaders = config.defaultHeaders ? { ...config.defaultHeaders } : {};
1317
+ this.organizationId = config.organizationId;
1213
1318
  }
1214
1319
  this.audiences = new Audiences(this);
1215
1320
  this.bookingPages = new BookingPages(this);
@@ -1218,6 +1323,7 @@ var ShipMailClient = class {
1218
1323
  this.mailboxes = new Mailboxes(this);
1219
1324
  this.messages = new Messages(this);
1220
1325
  this.newsletters = new Newsletters(this);
1326
+ this.partner = new Partner(this);
1221
1327
  this.suppressions = new Suppressions(this);
1222
1328
  this.threads = new Threads(this);
1223
1329
  this.webhooks = new Webhooks(this);
@@ -1258,6 +1364,10 @@ var ShipMailClient = class {
1258
1364
  if (methodOpts?.idempotencyKey) {
1259
1365
  headers["Idempotency-Key"] = methodOpts.idempotencyKey;
1260
1366
  }
1367
+ const targetOrganizationId = methodOpts?.organizationId ?? this.organizationId;
1368
+ if (targetOrganizationId) {
1369
+ headers["X-ShipMail-Organization-Id"] = targetOrganizationId;
1370
+ }
1261
1371
  let body = null;
1262
1372
  if (options.rawBody !== void 0) {
1263
1373
  headers["Content-Type"] = options.contentType ?? "application/octet-stream";
@@ -1314,6 +1424,9 @@ var ShipMailClient = class {
1314
1424
  }
1315
1425
  };
1316
1426
 
1427
+ // src/types/booking-page.ts
1428
+ var CONFERENCING_PROVIDER_IDS = ["zoom", "google_meet"];
1429
+
1317
1430
  // src/types/common.ts
1318
1431
  var WEBHOOK_EVENT_TYPES = [
1319
1432
  "message.received",
@@ -1396,6 +1509,7 @@ async function verifyWebhook(body, headers, secret, options) {
1396
1509
 
1397
1510
  exports.AuthenticationError = AuthenticationError;
1398
1511
  exports.AuthorizationError = AuthorizationError;
1512
+ exports.CONFERENCING_PROVIDER_IDS = CONFERENCING_PROVIDER_IDS;
1399
1513
  exports.ConflictError = ConflictError;
1400
1514
  exports.ConnectionError = ConnectionError;
1401
1515
  exports.DOMAIN_STATUSES = DOMAIN_STATUSES;