@primitivedotdev/sdk 0.15.0 → 0.17.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.
@@ -1,2 +1,2 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
- export { addDomain, createEndpoint, createFilter, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain } from './sdk.gen.js';
2
+ export { addDomain, createEndpoint, createFilter, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, discardEmailContent, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain } from './sdk.gen.js';
@@ -31,8 +31,25 @@ export const getStorageStats = (options) => (options?.client ?? client).get({
31
31
  /**
32
32
  * Get webhook signing secret
33
33
  *
34
- * Returns the webhook signing secret for your account. If no secret
35
- * exists yet, one is generated automatically on first access.
34
+ * Returns the webhook signing secret for your account. If no
35
+ * secret exists yet, one is generated automatically on first
36
+ * access.
37
+ *
38
+ * Signing is account-scoped, not per-endpoint. Every webhook
39
+ * delivery from any of your registered endpoints is signed
40
+ * with this single secret. Rotate via
41
+ * `POST /account/webhook-secret/rotate`.
42
+ *
43
+ * **Secret format**: the returned string looks base64-shaped
44
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
45
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
46
+ * delivery body. Base64-decoding before HMAC will silently
47
+ * produce mismatched signatures.
48
+ *
49
+ * See the API-level "Webhook signing" section for the full
50
+ * wire format (header name, signed string shape, hash algo,
51
+ * tolerance) including a language-agnostic verification
52
+ * recipe.
36
53
  *
37
54
  */
38
55
  export const getWebhookSecret = (options) => (options?.client ?? client).get({
@@ -125,12 +142,20 @@ export const verifyDomain = (options) => (options.client ?? client).post({
125
142
  * List inbound emails
126
143
  *
127
144
  * Returns a paginated list of INBOUND emails received at your
128
- * verified domains. Outbound messages sent via /send-mail are not
129
- * included; this endpoint is the inbox view, not a unified
130
- * send/receive history.
145
+ * verified domains. Outbound messages sent via /send-mail are
146
+ * not included; this endpoint is the inbox view, not a
147
+ * unified send/receive history.
131
148
  *
132
- * Supports filtering by domain, status, date range, and free-text
133
- * search across subject, sender, and recipient fields.
149
+ * Supports filtering by domain, status, date range, and
150
+ * free-text search across subject, sender, and recipient
151
+ * fields.
152
+ *
153
+ * For a compact text-table summary of the most recent N
154
+ * inbounds (no filters, no cursor pagination), the CLI ships
155
+ * `primitive emails:latest` as a one-line-per-email shortcut.
156
+ * It's TTY-aware so id columns are full UUIDs when piped, and
157
+ * a `--json` flag returns the same envelope this endpoint
158
+ * does. Use whichever fits the call site.
134
159
  *
135
160
  */
136
161
  export const listEmails = (options) => (options?.client ?? client).get({
@@ -252,6 +277,29 @@ export const replayEmailWebhooks = (options) => (options.client ?? client).post(
252
277
  url: '/emails/{id}/replay',
253
278
  ...options
254
279
  });
280
+ /**
281
+ * Discard email content
282
+ *
283
+ * Permanently deletes the email's raw bytes, parsed body (text + HTML),
284
+ * and attachments while preserving metadata (sender, recipient,
285
+ * subject, timestamps, hashes, attachment manifest) for audit logs.
286
+ * Idempotent: a second call returns success with
287
+ * `already_discarded: true` and does no work.
288
+ *
289
+ * **Gated** on the customer's discard-content opt-in (managed in the
290
+ * dashboard at Settings > Webhooks). When the toggle is off, this
291
+ * endpoint returns `403` with code `discard_not_enabled` and a
292
+ * message pointing the human at the dashboard. There is intentionally
293
+ * no API to flip this toggle — opting in to a destructive,
294
+ * non-reversible operation must be a deliberate human click in the
295
+ * UI.
296
+ *
297
+ */
298
+ export const discardEmailContent = (options) => (options.client ?? client).post({
299
+ security: [{ scheme: 'bearer', type: 'http' }],
300
+ url: '/emails/{id}/discard-content',
301
+ ...options
302
+ });
255
303
  /**
256
304
  * List webhook endpoints
257
305
  *
@@ -265,9 +313,22 @@ export const listEndpoints = (options) => (options?.client ?? client).get({
265
313
  /**
266
314
  * Create a webhook endpoint
267
315
  *
268
- * Creates a new webhook endpoint. If a deactivated endpoint with the
269
- * same URL and domain exists, it is reactivated instead.
270
- * Subject to plan limits on the number of active endpoints.
316
+ * Creates a new webhook endpoint. If a deactivated endpoint
317
+ * with the same URL and domain exists, it is reactivated
318
+ * instead. Subject to plan limits on the number of active
319
+ * endpoints.
320
+ *
321
+ * **Signing is account-scoped, not per-endpoint.** This call
322
+ * does not return any signing material; every endpoint on the
323
+ * account uses the same webhook secret, fetched via
324
+ * `GET /account/webhook-secret`. See the API-level "Webhook
325
+ * signing" section for the full wire format (header name,
326
+ * signed string, hash algo, secret format, tolerance) and a
327
+ * language-agnostic verification recipe.
328
+ *
329
+ * After creating the endpoint, fire a test delivery against
330
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
331
+ * accepts the signature.
271
332
  *
272
333
  */
273
334
  export const createEndpoint = (options) => (options.client ?? client).post({
@@ -1,2 +1,2 @@
1
- import { $ as AddDomainError, $n as ListEmailsResponses, $r as SentEmailStatus, $t as EmailDetailReply, A as getSentEmail, Ai as UpdateFilterErrors, An as GetStorageStatsErrors, Ar as ReplyToEmailErrors, At as DeleteEndpointErrors, B as replayEmailWebhooks, Bi as WebhookSecret, Bn as ListDeliveriesError, Br as SendEmailError, Bt as Domain, C as deleteEndpoint, Ci as UpdateEndpointError, Cn as GetSentEmailData, Cr as ReplayEmailWebhooksError, Ct as DeleteEmailData, D as getAccount, Di as UpdateEndpointResponses, Dn as GetSentEmailResponses, Dr as ReplayResult, Dt as DeleteEmailResponses, E as downloadRawEmail, Ei as UpdateEndpointResponse, En as GetSentEmailResponse, Er as ReplayEmailWebhooksResponses, Et as DeleteEmailResponse, F as listEmails, Fi as VerifyDomainData, Fn as GetWebhookSecretErrors, Fr as RotateWebhookSecretError, Ft as DeleteFilterErrors, G as updateAccount, Gi as Options$1, Gn as ListDomainsError, Gr as SendMailResult, Gt as DownloadAttachmentsResponse, H as rotateWebhookSecret, Hi as ClientOptions$1, Hn as ListDeliveriesResponse, Hr as SendEmailResponse, Ht as DownloadAttachmentsData, I as listEndpoints, Ii as VerifyDomainError, In as GetWebhookSecretResponse, Ir as RotateWebhookSecretErrors, It as DeleteFilterResponse, J as updateFilter, Ji as ResponseStyle, Jn as ListDomainsResponses, Jr as SendPermissionManagedZone, Jt as DownloadRawEmailError, K as updateDomain, Ki as RequestOptions, Kn as ListDomainsErrors, Kr as SendPermissionAddress, Kt as DownloadAttachmentsResponses, L as listFilters, Li as VerifyDomainErrors, Ln as GetWebhookSecretResponses, Lr as RotateWebhookSecretResponse, Lt as DeleteFilterResponses, M as getWebhookSecret, Mi as UpdateFilterResponse, Mn as GetStorageStatsResponses, Mr as ReplyToEmailResponses, Mt as DeleteEndpointResponses, N as listDeliveries, Ni as UpdateFilterResponses, Nn as GetWebhookSecretData, Nr as ResourceId, Nt as DeleteFilterData, O as getEmail, Oi as UpdateFilterData, On as GetStorageStatsData, Or as ReplyToEmailData, Ot as DeleteEndpointData, P as listDomains, Pi as VerifiedDomain, Pn as GetWebhookSecretError, Pr as RotateWebhookSecretData, Pt as DeleteFilterError, Q as AddDomainData, Qn as ListEmailsResponse, Qr as SentEmailDetail, Qt as EmailDetail, R as listSentEmails, Ri as VerifyDomainResponse, Rn as Limit, Rr as RotateWebhookSecretResponses, Rt as DeliveryStatus, S as deleteEmail, Si as UpdateEndpointData, Sn as GetSendPermissionsResponses, Sr as ReplayEmailWebhooksData, St as DeleteDomainResponses, T as downloadAttachments, Ti as UpdateEndpointInput, Tn as GetSentEmailErrors, Tr as ReplayEmailWebhooksResponse, Tt as DeleteEmailErrors, U as sendEmail, Ui as Config, Un as ListDeliveriesResponses, Ur as SendEmailResponses, Ut as DownloadAttachmentsError, V as replyToEmail, Vi as Client, Vn as ListDeliveriesErrors, Vr as SendEmailErrors, Vt as DomainVerifyResult, W as testEndpoint, Wi as CreateClientConfig, Wn as ListDomainsData, Wr as SendMailInput, Wt as DownloadAttachmentsErrors, X as Account, Xn as ListEmailsError, Xr as SendPermissionYourDomain, Xt as DownloadRawEmailResponse, Y as verifyDomain, Yi as Auth, Yn as ListEmailsData, Yr as SendPermissionRule, Yt as DownloadRawEmailErrors, Z as AccountUpdated, Zn as ListEmailsErrors, Zr as SendPermissionsMeta, Zt as DownloadRawEmailResponses, _ as Options, _i as UpdateDomainError, _n as GetEmailResponses, _r as ReplayDeliveryData, _t as Cursor, a as PrimitiveApiError, ai as TestEndpointErrors, an as Filter, ar as ListEnvelope, at as CreateEndpointData, b as createFilter, bi as UpdateDomainResponse, bn as GetSendPermissionsErrors, br as ReplayDeliveryResponse, bt as DeleteDomainErrors, c as PrimitiveClientOptions, ci as TestResult, cn as GetAccountData, cr as ListFiltersErrors, ct as CreateEndpointInput, d as SendResult, di as UpdateAccountError, dn as GetAccountResponse, dr as ListSentEmailsData, dt as CreateFilterData, ei as SentEmailSummary, en as EmailStatus, er as ListEndpointsData, et as AddDomainErrors, f as SendThreadInput, fi as UpdateAccountErrors, fn as GetAccountResponses, fr as ListSentEmailsError, ft as CreateFilterError, g as operations, gi as UpdateDomainData, gn as GetEmailResponse, gr as PaginationMeta, gt as CreateFilterResponses, h as createPrimitiveClient, hi as UpdateAccountResponses, hn as GetEmailErrors, hr as ListSentEmailsResponses, ht as CreateFilterResponse, i as PrimitiveApiClientOptions, ii as TestEndpointError, in as ErrorResponse, ir as ListEndpointsResponses, it as ClientOptions, j as getStorageStats, ji as UpdateFilterInput, jn as GetStorageStatsResponse, jr as ReplyToEmailResponse, jt as DeleteEndpointResponse, k as getSendPermissions, ki as UpdateFilterError, kn as GetStorageStatsError, kr as ReplyToEmailError, kt as DeleteEndpointError, l as ReplyInput, li as UnverifiedDomain, ln as GetAccountError, lr as ListFiltersResponse, lt as CreateEndpointResponse, m as createPrimitiveApiClient, mi as UpdateAccountResponse, mn as GetEmailError, mr as ListSentEmailsResponse, mt as CreateFilterInput, n as ForwardInput, ni as SuccessEnvelope, nn as EmailWebhookStatus, nr as ListEndpointsErrors, nt as AddDomainResponse, o as PrimitiveApiErrorDetails, oi as TestEndpointResponse, on as GateDenial, or as ListFiltersData, ot as CreateEndpointError, p as client, pi as UpdateAccountInput, pn as GetEmailData, pr as ListSentEmailsErrors, pt as CreateFilterErrors, q as updateEndpoint, qi as RequestResult, qn as ListDomainsResponse, qr as SendPermissionAnyRecipient, qt as DownloadRawEmailData, r as PrimitiveApiClient, ri as TestEndpointData, rn as Endpoint, rr as ListEndpointsResponse, rt as AddDomainResponses, s as PrimitiveClient, si as TestEndpointResponses, sn as GateFix, sr as ListFiltersError, st as CreateEndpointErrors, t as DEFAULT_BASE_URL, ti as StorageStats, tn as EmailSummary, tr as ListEndpointsError, tt as AddDomainInput, u as SendInput, ui as UpdateAccountData, un as GetAccountErrors, ur as ListFiltersResponses, ut as CreateEndpointResponses, v as addDomain, vi as UpdateDomainErrors, vn as GetSendPermissionsData, vr as ReplayDeliveryError, vt as DeleteDomainData, w as deleteFilter, wi as UpdateEndpointErrors, wn as GetSentEmailError, wr as ReplayEmailWebhooksErrors, wt as DeleteEmailError, x as deleteDomain, xi as UpdateDomainResponses, xn as GetSendPermissionsResponse, xr as ReplayDeliveryResponses, xt as DeleteDomainResponse, y as createEndpoint, yi as UpdateDomainInput, yn as GetSendPermissionsError, yr as ReplayDeliveryErrors, yt as DeleteDomainError, z as replayDelivery, zi as VerifyDomainResponses, zn as ListDeliveriesData, zr as SendEmailData, zt as DeliverySummary } from "../index-DEY4h3MZ.js";
2
- export { Account, AccountUpdated, AddDomainData, AddDomainError, AddDomainErrors, AddDomainInput, AddDomainResponse, AddDomainResponses, Auth, ClientOptions, CreateClientConfig, CreateEndpointData, CreateEndpointError, CreateEndpointErrors, CreateEndpointInput, CreateEndpointResponse, CreateEndpointResponses, CreateFilterData, CreateFilterError, CreateFilterErrors, CreateFilterInput, CreateFilterResponse, CreateFilterResponses, Cursor, DEFAULT_BASE_URL, DeleteDomainData, DeleteDomainError, DeleteDomainErrors, DeleteDomainResponse, DeleteDomainResponses, DeleteEmailData, DeleteEmailError, DeleteEmailErrors, DeleteEmailResponse, DeleteEmailResponses, DeleteEndpointData, DeleteEndpointError, DeleteEndpointErrors, DeleteEndpointResponse, DeleteEndpointResponses, DeleteFilterData, DeleteFilterError, DeleteFilterErrors, DeleteFilterResponse, DeleteFilterResponses, DeliveryStatus, DeliverySummary, Domain, DomainVerifyResult, DownloadAttachmentsData, DownloadAttachmentsError, DownloadAttachmentsErrors, DownloadAttachmentsResponse, DownloadAttachmentsResponses, DownloadRawEmailData, DownloadRawEmailError, DownloadRawEmailErrors, DownloadRawEmailResponse, DownloadRawEmailResponses, EmailDetail, EmailDetailReply, EmailStatus, EmailSummary, EmailWebhookStatus, Endpoint, ErrorResponse, Filter, ForwardInput, GateDenial, GateFix, GetAccountData, GetAccountError, GetAccountErrors, GetAccountResponse, GetAccountResponses, GetEmailData, GetEmailError, GetEmailErrors, GetEmailResponse, GetEmailResponses, GetSendPermissionsData, GetSendPermissionsError, GetSendPermissionsErrors, GetSendPermissionsResponse, GetSendPermissionsResponses, GetSentEmailData, GetSentEmailError, GetSentEmailErrors, GetSentEmailResponse, GetSentEmailResponses, GetStorageStatsData, GetStorageStatsError, GetStorageStatsErrors, GetStorageStatsResponse, GetStorageStatsResponses, GetWebhookSecretData, GetWebhookSecretError, GetWebhookSecretErrors, GetWebhookSecretResponse, GetWebhookSecretResponses, Limit, ListDeliveriesData, ListDeliveriesError, ListDeliveriesErrors, ListDeliveriesResponse, ListDeliveriesResponses, ListDomainsData, ListDomainsError, ListDomainsErrors, ListDomainsResponse, ListDomainsResponses, ListEmailsData, ListEmailsError, ListEmailsErrors, ListEmailsResponse, ListEmailsResponses, ListEndpointsData, ListEndpointsError, ListEndpointsErrors, ListEndpointsResponse, ListEndpointsResponses, ListEnvelope, ListFiltersData, ListFiltersError, ListFiltersErrors, ListFiltersResponse, ListFiltersResponses, ListSentEmailsData, ListSentEmailsError, ListSentEmailsErrors, ListSentEmailsResponse, ListSentEmailsResponses, Options, PaginationMeta, PrimitiveApiClient, PrimitiveApiClientOptions, PrimitiveApiError, PrimitiveApiErrorDetails, PrimitiveClient, PrimitiveClientOptions, Client as PrimitiveGeneratedApiClient, ClientOptions$1 as PrimitiveGeneratedApiClientOptions, Config as PrimitiveGeneratedApiConfig, Options$1 as PrimitiveGeneratedApiOptions, RequestOptions as PrimitiveGeneratedApiRequestOptions, RequestResult as PrimitiveGeneratedApiRequestResult, ReplayDeliveryData, ReplayDeliveryError, ReplayDeliveryErrors, ReplayDeliveryResponse, ReplayDeliveryResponses, ReplayEmailWebhooksData, ReplayEmailWebhooksError, ReplayEmailWebhooksErrors, ReplayEmailWebhooksResponse, ReplayEmailWebhooksResponses, ReplayResult, ReplyInput, ReplyToEmailData, ReplyToEmailError, ReplyToEmailErrors, ReplyToEmailResponse, ReplyToEmailResponses, ResourceId, ResponseStyle, RotateWebhookSecretData, RotateWebhookSecretError, RotateWebhookSecretErrors, RotateWebhookSecretResponse, RotateWebhookSecretResponses, SendEmailData, SendEmailError, SendEmailErrors, SendEmailResponse, SendEmailResponses, SendInput, SendMailInput, SendMailResult, SendPermissionAddress, SendPermissionAnyRecipient, SendPermissionManagedZone, SendPermissionRule, SendPermissionYourDomain, SendPermissionsMeta, SendResult, SendThreadInput, SentEmailDetail, SentEmailStatus, SentEmailSummary, StorageStats, SuccessEnvelope, TestEndpointData, TestEndpointError, TestEndpointErrors, TestEndpointResponse, TestEndpointResponses, TestResult, UnverifiedDomain, UpdateAccountData, UpdateAccountError, UpdateAccountErrors, UpdateAccountInput, UpdateAccountResponse, UpdateAccountResponses, UpdateDomainData, UpdateDomainError, UpdateDomainErrors, UpdateDomainInput, UpdateDomainResponse, UpdateDomainResponses, UpdateEndpointData, UpdateEndpointError, UpdateEndpointErrors, UpdateEndpointInput, UpdateEndpointResponse, UpdateEndpointResponses, UpdateFilterData, UpdateFilterError, UpdateFilterErrors, UpdateFilterInput, UpdateFilterResponse, UpdateFilterResponses, VerifiedDomain, VerifyDomainData, VerifyDomainError, VerifyDomainErrors, VerifyDomainResponse, VerifyDomainResponses, WebhookSecret, addDomain, client, createEndpoint, createFilter, createPrimitiveApiClient, createPrimitiveClient, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, operations, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain };
1
+ import { $ as AddDomainData, $i as RequestOptions, $n as ListDomainsErrors, $r as SendPermissionAddress, $t as DownloadAttachmentsResponses, A as getSendPermissions, Ai as UpdateEndpointError, An as GetSentEmailData, Ar as ReplayEmailWebhooksError, At as DeleteEndpointError, B as replayDelivery, Bi as UpdateFilterResponses, Bn as GetWebhookSecretData, Br as ResourceId, Bt as DeliverySummary, C as deleteEndpoint, Ci as UpdateDomainData, Cn as GetEmailResponse, Cr as PaginationMeta, Ct as DeleteDomainResponses, D as downloadRawEmail, Di as UpdateDomainResponse, Dn as GetSendPermissionsErrors, Dr as ReplayDeliveryResponse, Dt as DeleteEmailResponse, E as downloadAttachments, Ei as UpdateDomainInput, En as GetSendPermissionsError, Er as ReplayDeliveryErrors, Et as DeleteEmailErrors, F as listDomains, Fi as UpdateFilterData, Fn as GetStorageStatsData, Fr as ReplyToEmailData, Ft as DeleteFilterError, G as testEndpoint, Gi as VerifyDomainResponse, Gn as Limit, Gr as RotateWebhookSecretResponses, Gt as DiscardEmailContentResponse, H as replyToEmail, Hi as VerifyDomainData, Hn as GetWebhookSecretErrors, Hr as RotateWebhookSecretError, Ht as DiscardEmailContentData, I as listEmails, Ii as UpdateFilterError, In as GetStorageStatsError, Ir as ReplyToEmailError, It as DeleteFilterErrors, J as updateEndpoint, Ji as Client, Jn as ListDeliveriesErrors, Jr as SendEmailErrors, Jt as DomainVerifyResult, K as updateAccount, Ki as VerifyDomainResponses, Kn as ListDeliveriesData, Kr as SendEmailData, Kt as DiscardEmailContentResponses, L as listEndpoints, Li as UpdateFilterErrors, Ln as GetStorageStatsErrors, Lr as ReplyToEmailErrors, Lt as DeleteFilterResponse, M as getStorageStats, Mi as UpdateEndpointInput, Mn as GetSentEmailErrors, Mr as ReplayEmailWebhooksResponse, Mt as DeleteEndpointResponse, N as getWebhookSecret, Ni as UpdateEndpointResponse, Nn as GetSentEmailResponse, Nr as ReplayEmailWebhooksResponses, Nt as DeleteEndpointResponses, O as getAccount, Oi as UpdateDomainResponses, On as GetSendPermissionsResponse, Or as ReplayDeliveryResponses, Ot as DeleteEmailResponses, P as listDeliveries, Pi as UpdateEndpointResponses, Pn as GetSentEmailResponses, Pr as ReplayResult, Pt as DeleteFilterData, Q as AccountUpdated, Qi as Options$1, Qn as ListDomainsError, Qr as SendMailResult, Qt as DownloadAttachmentsResponse, R as listFilters, Ri as UpdateFilterInput, Rn as GetStorageStatsResponse, Rr as ReplyToEmailResponse, Rt as DeleteFilterResponses, S as deleteEmail, Si as UpdateAccountResponses, Sn as GetEmailErrors, Sr as ListSentEmailsResponses, St as DeleteDomainResponse, T as discardEmailContent, Ti as UpdateDomainErrors, Tn as GetSendPermissionsData, Tr as ReplayDeliveryError, Tt as DeleteEmailError, U as rotateWebhookSecret, Ui as VerifyDomainError, Un as GetWebhookSecretResponse, Ur as RotateWebhookSecretErrors, Ut as DiscardEmailContentError, V as replayEmailWebhooks, Vi as VerifiedDomain, Vn as GetWebhookSecretError, Vr as RotateWebhookSecretData, Vt as DiscardContentResult, W as sendEmail, Wi as VerifyDomainErrors, Wn as GetWebhookSecretResponses, Wr as RotateWebhookSecretResponse, Wt as DiscardEmailContentErrors, X as verifyDomain, Xi as Config, Xn as ListDeliveriesResponses, Xr as SendEmailResponses, Xt as DownloadAttachmentsError, Y as updateFilter, Yi as ClientOptions$1, Yn as ListDeliveriesResponse, Yr as SendEmailResponse, Yt as DownloadAttachmentsData, Z as Account, Zi as CreateClientConfig, Zn as ListDomainsData, Zr as SendMailInput, Zt as DownloadAttachmentsErrors, _ as Options, _i as UpdateAccountData, _n as GetAccountErrors, _r as ListFiltersResponses, _t as CreateFilterResponses, a as PrimitiveApiError, ai as SentEmailDetail, an as EmailDetail, ar as ListEmailsResponse, at as ClientOptions, b as createFilter, bi as UpdateAccountInput, bn as GetEmailData, br as ListSentEmailsErrors, bt as DeleteDomainError, c as PrimitiveClientOptions, ci as StorageStats, cn as EmailSummary, cr as ListEndpointsError, ct as CreateEndpointErrors, d as SendResult, di as TestEndpointError, dn as ErrorResponse, dr as ListEndpointsResponses, dt as CreateEndpointResponses, ea as RequestResult, ei as SendPermissionAnyRecipient, en as DownloadRawEmailData, er as ListDomainsResponse, et as AddDomainError, f as SendThreadInput, fi as TestEndpointErrors, fn as Filter, fr as ListEnvelope, ft as CreateFilterData, g as operations, gi as UnverifiedDomain, gn as GetAccountError, gr as ListFiltersResponse, gt as CreateFilterResponse, h as createPrimitiveClient, hi as TestResult, hn as GetAccountData, hr as ListFiltersErrors, ht as CreateFilterInput, i as PrimitiveApiClientOptions, ii as SendPermissionsMeta, in as DownloadRawEmailResponses, ir as ListEmailsErrors, it as AddDomainResponses, j as getSentEmail, ji as UpdateEndpointErrors, jn as GetSentEmailError, jr as ReplayEmailWebhooksErrors, jt as DeleteEndpointErrors, k as getEmail, ki as UpdateEndpointData, kn as GetSendPermissionsResponses, kr as ReplayEmailWebhooksData, kt as DeleteEndpointData, l as ReplyInput, li as SuccessEnvelope, ln as EmailWebhookStatus, lr as ListEndpointsErrors, lt as CreateEndpointInput, m as createPrimitiveApiClient, mi as TestEndpointResponses, mn as GateFix, mr as ListFiltersError, mt as CreateFilterErrors, n as ForwardInput, na as Auth, ni as SendPermissionRule, nn as DownloadRawEmailErrors, nr as ListEmailsData, nt as AddDomainInput, o as PrimitiveApiErrorDetails, oi as SentEmailStatus, on as EmailDetailReply, or as ListEmailsResponses, ot as CreateEndpointData, p as client, pi as TestEndpointResponse, pn as GateDenial, pr as ListFiltersData, pt as CreateFilterError, q as updateDomain, qi as WebhookSecret, qn as ListDeliveriesError, qr as SendEmailError, qt as Domain, r as PrimitiveApiClient, ri as SendPermissionYourDomain, rn as DownloadRawEmailResponse, rr as ListEmailsError, rt as AddDomainResponse, s as PrimitiveClient, si as SentEmailSummary, sn as EmailStatus, sr as ListEndpointsData, st as CreateEndpointError, t as DEFAULT_BASE_URL, ta as ResponseStyle, ti as SendPermissionManagedZone, tn as DownloadRawEmailError, tr as ListDomainsResponses, tt as AddDomainErrors, u as SendInput, ui as TestEndpointData, un as Endpoint, ur as ListEndpointsResponse, ut as CreateEndpointResponse, v as addDomain, vi as UpdateAccountError, vn as GetAccountResponse, vr as ListSentEmailsData, vt as Cursor, w as deleteFilter, wi as UpdateDomainError, wn as GetEmailResponses, wr as ReplayDeliveryData, wt as DeleteEmailData, x as deleteDomain, xi as UpdateAccountResponse, xn as GetEmailError, xr as ListSentEmailsResponse, xt as DeleteDomainErrors, y as createEndpoint, yi as UpdateAccountErrors, yn as GetAccountResponses, yr as ListSentEmailsError, yt as DeleteDomainData, z as listSentEmails, zi as UpdateFilterResponse, zn as GetStorageStatsResponses, zr as ReplyToEmailResponses, zt as DeliveryStatus } from "../index-CHWqMBs6.js";
2
+ export { Account, AccountUpdated, AddDomainData, AddDomainError, AddDomainErrors, AddDomainInput, AddDomainResponse, AddDomainResponses, Auth, ClientOptions, CreateClientConfig, CreateEndpointData, CreateEndpointError, CreateEndpointErrors, CreateEndpointInput, CreateEndpointResponse, CreateEndpointResponses, CreateFilterData, CreateFilterError, CreateFilterErrors, CreateFilterInput, CreateFilterResponse, CreateFilterResponses, Cursor, DEFAULT_BASE_URL, DeleteDomainData, DeleteDomainError, DeleteDomainErrors, DeleteDomainResponse, DeleteDomainResponses, DeleteEmailData, DeleteEmailError, DeleteEmailErrors, DeleteEmailResponse, DeleteEmailResponses, DeleteEndpointData, DeleteEndpointError, DeleteEndpointErrors, DeleteEndpointResponse, DeleteEndpointResponses, DeleteFilterData, DeleteFilterError, DeleteFilterErrors, DeleteFilterResponse, DeleteFilterResponses, DeliveryStatus, DeliverySummary, DiscardContentResult, DiscardEmailContentData, DiscardEmailContentError, DiscardEmailContentErrors, DiscardEmailContentResponse, DiscardEmailContentResponses, Domain, DomainVerifyResult, DownloadAttachmentsData, DownloadAttachmentsError, DownloadAttachmentsErrors, DownloadAttachmentsResponse, DownloadAttachmentsResponses, DownloadRawEmailData, DownloadRawEmailError, DownloadRawEmailErrors, DownloadRawEmailResponse, DownloadRawEmailResponses, EmailDetail, EmailDetailReply, EmailStatus, EmailSummary, EmailWebhookStatus, Endpoint, ErrorResponse, Filter, ForwardInput, GateDenial, GateFix, GetAccountData, GetAccountError, GetAccountErrors, GetAccountResponse, GetAccountResponses, GetEmailData, GetEmailError, GetEmailErrors, GetEmailResponse, GetEmailResponses, GetSendPermissionsData, GetSendPermissionsError, GetSendPermissionsErrors, GetSendPermissionsResponse, GetSendPermissionsResponses, GetSentEmailData, GetSentEmailError, GetSentEmailErrors, GetSentEmailResponse, GetSentEmailResponses, GetStorageStatsData, GetStorageStatsError, GetStorageStatsErrors, GetStorageStatsResponse, GetStorageStatsResponses, GetWebhookSecretData, GetWebhookSecretError, GetWebhookSecretErrors, GetWebhookSecretResponse, GetWebhookSecretResponses, Limit, ListDeliveriesData, ListDeliveriesError, ListDeliveriesErrors, ListDeliveriesResponse, ListDeliveriesResponses, ListDomainsData, ListDomainsError, ListDomainsErrors, ListDomainsResponse, ListDomainsResponses, ListEmailsData, ListEmailsError, ListEmailsErrors, ListEmailsResponse, ListEmailsResponses, ListEndpointsData, ListEndpointsError, ListEndpointsErrors, ListEndpointsResponse, ListEndpointsResponses, ListEnvelope, ListFiltersData, ListFiltersError, ListFiltersErrors, ListFiltersResponse, ListFiltersResponses, ListSentEmailsData, ListSentEmailsError, ListSentEmailsErrors, ListSentEmailsResponse, ListSentEmailsResponses, Options, PaginationMeta, PrimitiveApiClient, PrimitiveApiClientOptions, PrimitiveApiError, PrimitiveApiErrorDetails, PrimitiveClient, PrimitiveClientOptions, Client as PrimitiveGeneratedApiClient, ClientOptions$1 as PrimitiveGeneratedApiClientOptions, Config as PrimitiveGeneratedApiConfig, Options$1 as PrimitiveGeneratedApiOptions, RequestOptions as PrimitiveGeneratedApiRequestOptions, RequestResult as PrimitiveGeneratedApiRequestResult, ReplayDeliveryData, ReplayDeliveryError, ReplayDeliveryErrors, ReplayDeliveryResponse, ReplayDeliveryResponses, ReplayEmailWebhooksData, ReplayEmailWebhooksError, ReplayEmailWebhooksErrors, ReplayEmailWebhooksResponse, ReplayEmailWebhooksResponses, ReplayResult, ReplyInput, ReplyToEmailData, ReplyToEmailError, ReplyToEmailErrors, ReplyToEmailResponse, ReplyToEmailResponses, ResourceId, ResponseStyle, RotateWebhookSecretData, RotateWebhookSecretError, RotateWebhookSecretErrors, RotateWebhookSecretResponse, RotateWebhookSecretResponses, SendEmailData, SendEmailError, SendEmailErrors, SendEmailResponse, SendEmailResponses, SendInput, SendMailInput, SendMailResult, SendPermissionAddress, SendPermissionAnyRecipient, SendPermissionManagedZone, SendPermissionRule, SendPermissionYourDomain, SendPermissionsMeta, SendResult, SendThreadInput, SentEmailDetail, SentEmailStatus, SentEmailSummary, StorageStats, SuccessEnvelope, TestEndpointData, TestEndpointError, TestEndpointErrors, TestEndpointResponse, TestEndpointResponses, TestResult, UnverifiedDomain, UpdateAccountData, UpdateAccountError, UpdateAccountErrors, UpdateAccountInput, UpdateAccountResponse, UpdateAccountResponses, UpdateDomainData, UpdateDomainError, UpdateDomainErrors, UpdateDomainInput, UpdateDomainResponse, UpdateDomainResponses, UpdateEndpointData, UpdateEndpointError, UpdateEndpointErrors, UpdateEndpointInput, UpdateEndpointResponse, UpdateEndpointResponses, UpdateFilterData, UpdateFilterError, UpdateFilterErrors, UpdateFilterInput, UpdateFilterResponse, UpdateFilterResponses, VerifiedDomain, VerifyDomainData, VerifyDomainError, VerifyDomainErrors, VerifyDomainResponse, VerifyDomainResponses, WebhookSecret, addDomain, client, createEndpoint, createFilter, createPrimitiveApiClient, createPrimitiveClient, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, discardEmailContent, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, operations, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain };
@@ -620,6 +620,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
620
620
  deleteEmail: () => deleteEmail,
621
621
  deleteEndpoint: () => deleteEndpoint,
622
622
  deleteFilter: () => deleteFilter,
623
+ discardEmailContent: () => discardEmailContent,
623
624
  downloadAttachments: () => downloadAttachments,
624
625
  downloadRawEmail: () => downloadRawEmail,
625
626
  getAccount: () => getAccount,
@@ -686,8 +687,25 @@ const getStorageStats = (options) => (options?.client ?? client$1).get({
686
687
  /**
687
688
  * Get webhook signing secret
688
689
  *
689
- * Returns the webhook signing secret for your account. If no secret
690
- * exists yet, one is generated automatically on first access.
690
+ * Returns the webhook signing secret for your account. If no
691
+ * secret exists yet, one is generated automatically on first
692
+ * access.
693
+ *
694
+ * Signing is account-scoped, not per-endpoint. Every webhook
695
+ * delivery from any of your registered endpoints is signed
696
+ * with this single secret. Rotate via
697
+ * `POST /account/webhook-secret/rotate`.
698
+ *
699
+ * **Secret format**: the returned string looks base64-shaped
700
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
701
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
702
+ * delivery body. Base64-decoding before HMAC will silently
703
+ * produce mismatched signatures.
704
+ *
705
+ * See the API-level "Webhook signing" section for the full
706
+ * wire format (header name, signed string shape, hash algo,
707
+ * tolerance) including a language-agnostic verification
708
+ * recipe.
691
709
  *
692
710
  */
693
711
  const getWebhookSecret = (options) => (options?.client ?? client$1).get({
@@ -801,12 +819,20 @@ const verifyDomain = (options) => (options.client ?? client$1).post({
801
819
  * List inbound emails
802
820
  *
803
821
  * Returns a paginated list of INBOUND emails received at your
804
- * verified domains. Outbound messages sent via /send-mail are not
805
- * included; this endpoint is the inbox view, not a unified
806
- * send/receive history.
822
+ * verified domains. Outbound messages sent via /send-mail are
823
+ * not included; this endpoint is the inbox view, not a
824
+ * unified send/receive history.
807
825
  *
808
- * Supports filtering by domain, status, date range, and free-text
809
- * search across subject, sender, and recipient fields.
826
+ * Supports filtering by domain, status, date range, and
827
+ * free-text search across subject, sender, and recipient
828
+ * fields.
829
+ *
830
+ * For a compact text-table summary of the most recent N
831
+ * inbounds (no filters, no cursor pagination), the CLI ships
832
+ * `primitive emails:latest` as a one-line-per-email shortcut.
833
+ * It's TTY-aware so id columns are full UUIDs when piped, and
834
+ * a `--json` flag returns the same envelope this endpoint
835
+ * does. Use whichever fits the call site.
810
836
  *
811
837
  */
812
838
  const listEmails = (options) => (options?.client ?? client$1).get({
@@ -950,6 +976,32 @@ const replayEmailWebhooks = (options) => (options.client ?? client$1).post({
950
976
  ...options
951
977
  });
952
978
  /**
979
+ * Discard email content
980
+ *
981
+ * Permanently deletes the email's raw bytes, parsed body (text + HTML),
982
+ * and attachments while preserving metadata (sender, recipient,
983
+ * subject, timestamps, hashes, attachment manifest) for audit logs.
984
+ * Idempotent: a second call returns success with
985
+ * `already_discarded: true` and does no work.
986
+ *
987
+ * **Gated** on the customer's discard-content opt-in (managed in the
988
+ * dashboard at Settings > Webhooks). When the toggle is off, this
989
+ * endpoint returns `403` with code `discard_not_enabled` and a
990
+ * message pointing the human at the dashboard. There is intentionally
991
+ * no API to flip this toggle — opting in to a destructive,
992
+ * non-reversible operation must be a deliberate human click in the
993
+ * UI.
994
+ *
995
+ */
996
+ const discardEmailContent = (options) => (options.client ?? client$1).post({
997
+ security: [{
998
+ scheme: "bearer",
999
+ type: "http"
1000
+ }],
1001
+ url: "/emails/{id}/discard-content",
1002
+ ...options
1003
+ });
1004
+ /**
953
1005
  * List webhook endpoints
954
1006
  *
955
1007
  * Returns all active (non-deleted) webhook endpoints.
@@ -965,9 +1017,22 @@ const listEndpoints = (options) => (options?.client ?? client$1).get({
965
1017
  /**
966
1018
  * Create a webhook endpoint
967
1019
  *
968
- * Creates a new webhook endpoint. If a deactivated endpoint with the
969
- * same URL and domain exists, it is reactivated instead.
970
- * Subject to plan limits on the number of active endpoints.
1020
+ * Creates a new webhook endpoint. If a deactivated endpoint
1021
+ * with the same URL and domain exists, it is reactivated
1022
+ * instead. Subject to plan limits on the number of active
1023
+ * endpoints.
1024
+ *
1025
+ * **Signing is account-scoped, not per-endpoint.** This call
1026
+ * does not return any signing material; every endpoint on the
1027
+ * account uses the same webhook secret, fetched via
1028
+ * `GET /account/webhook-secret`. See the API-level "Webhook
1029
+ * signing" section for the full wire format (header name,
1030
+ * signed string, hash algo, secret format, tolerance) and a
1031
+ * language-agnostic verification recipe.
1032
+ *
1033
+ * After creating the endpoint, fire a test delivery against
1034
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
1035
+ * accepts the signature.
971
1036
  *
972
1037
  */
973
1038
  const createEndpoint = (options) => (options.client ?? client$1).post({
@@ -1486,4 +1551,4 @@ function client(options = {}) {
1486
1551
  }
1487
1552
  const operations = sdk_gen_exports;
1488
1553
  //#endregion
1489
- export { replayDelivery as A, verifyDomain as B, getWebhookSecret as C, listEndpoints as D, listEmails as E, testEndpoint as F, updateAccount as I, updateDomain as L, replyToEmail as M, rotateWebhookSecret as N, listFilters as O, sendEmail as P, updateEndpoint as R, getStorageStats as S, listDomains as T, downloadRawEmail as _, client as a, getSendPermissions as b, operations as c, createFilter as d, deleteDomain as f, downloadAttachments as g, deleteFilter as h, PrimitiveClient as i, replayEmailWebhooks as j, listSentEmails as k, addDomain as l, deleteEndpoint as m, PrimitiveApiClient as n, createPrimitiveApiClient as o, deleteEmail as p, PrimitiveApiError as r, createPrimitiveClient as s, DEFAULT_BASE_URL as t, createEndpoint as u, getAccount as v, listDeliveries as w, getSentEmail as x, getEmail as y, updateFilter as z };
1554
+ export { listSentEmails as A, updateFilter as B, getStorageStats as C, listEmails as D, listDomains as E, sendEmail as F, testEndpoint as I, updateAccount as L, replayEmailWebhooks as M, replyToEmail as N, listEndpoints as O, rotateWebhookSecret as P, updateDomain as R, getSentEmail as S, listDeliveries as T, verifyDomain as V, downloadAttachments as _, client as a, getEmail as b, operations as c, createFilter as d, deleteDomain as f, discardEmailContent as g, deleteFilter as h, PrimitiveClient as i, replayDelivery as j, listFilters as k, addDomain as l, deleteEndpoint as m, PrimitiveApiClient as n, createPrimitiveApiClient as o, deleteEmail as p, PrimitiveApiError as r, createPrimitiveClient as s, DEFAULT_BASE_URL as t, createEndpoint as u, downloadRawEmail as v, getWebhookSecret as w, getSendPermissions as x, getAccount as y, updateEndpoint as z };
@@ -347,7 +347,7 @@ type PaginationMeta = {
347
347
  type ErrorResponse = {
348
348
  success: boolean;
349
349
  error: {
350
- code: 'unauthorized' | 'forbidden' | 'not_found' | 'validation_error' | 'rate_limit_exceeded' | 'internal_error' | 'conflict' | 'mx_conflict' | 'outbound_disabled' | 'cannot_send_from_domain' | 'recipient_not_allowed' | 'outbound_key_missing' | 'outbound_unreachable' | 'outbound_key_invalid' | 'outbound_capacity_exhausted' | 'outbound_response_malformed' | 'outbound_relay_failed' | 'inbound_not_repliable';
350
+ code: 'unauthorized' | 'forbidden' | 'not_found' | 'validation_error' | 'rate_limit_exceeded' | 'internal_error' | 'conflict' | 'mx_conflict' | 'outbound_disabled' | 'cannot_send_from_domain' | 'recipient_not_allowed' | 'outbound_key_missing' | 'outbound_unreachable' | 'outbound_key_invalid' | 'outbound_capacity_exhausted' | 'outbound_response_malformed' | 'outbound_relay_failed' | 'discard_not_enabled' | 'inbound_not_repliable';
351
351
  message: string;
352
352
  /**
353
353
  * Optional structured data that callers can inspect to recover
@@ -824,6 +824,25 @@ type EmailWebhookStatus = 'pending' | 'in_flight' | 'fired' | 'failed' | 'exhaus
824
824
  *
825
825
  */
826
826
  type SentEmailStatus = 'queued' | 'submitted_to_agent' | 'agent_failed' | 'gate_denied' | 'unknown' | 'delivered' | 'bounced' | 'deferred' | 'wait_timeout';
827
+ /**
828
+ * Narrower enum covering only the four terminal delivery
829
+ * outcomes returned to a synchronous `wait: true` send.
830
+ *
831
+ * On the SendMailResult shape, `delivery_status` is always
832
+ * equal to `status` whenever both are present (i.e. on
833
+ * terminal-state replays and live wait=true responses).
834
+ * The two fields exist so callers that want to type-narrow
835
+ * on "this is a delivery outcome" can pattern-match against
836
+ * the four-value enum without handling the broader
837
+ * SentEmailStatus value set (which also covers `queued`,
838
+ * `submitted_to_agent`, `agent_failed`, `gate_denied`,
839
+ * `unknown`).
840
+ *
841
+ * On async-mode and pre-terminal responses, `delivery_status`
842
+ * is absent and only `status` is populated. Use `status` if
843
+ * you want a single field that's always present.
844
+ *
845
+ */
827
846
  type DeliveryStatus = 'delivered' | 'bounced' | 'deferred' | 'wait_timeout';
828
847
  /**
829
848
  * List-row projection of a sent-email record. Drops
@@ -1077,7 +1096,20 @@ type SendMailResult = {
1077
1096
  */
1078
1097
  from: string;
1079
1098
  /**
1080
- * Message identifier assigned by Primitive's outbound relay, when available.
1099
+ * Message identifier assigned by Primitive's OUTBOUND relay
1100
+ * (the box that signs your mail and submits it to the
1101
+ * receiving MTA). NOT the receiver's queue id.
1102
+ *
1103
+ * The receiver may also report its own queue id in
1104
+ * `smtp_response_text` (e.g. `"250 2.0.0 Ok: queued as
1105
+ * 99D111927CDA"` from a Postfix receiver). Those two ids
1106
+ * refer to different mail systems and are NOT comparable.
1107
+ * Treat `queue_id` as Primitive-internal and the
1108
+ * receiver's id as remote-system-internal.
1109
+ *
1110
+ * Null on rows that never reached the relay (queued,
1111
+ * gate_denied, agent_failed before signing).
1112
+ *
1081
1113
  */
1082
1114
  queue_id: string | null;
1083
1115
  /**
@@ -1391,6 +1423,22 @@ type ReplayResult = {
1391
1423
  */
1392
1424
  failed: number;
1393
1425
  };
1426
+ type DiscardContentResult = {
1427
+ /**
1428
+ * Always `true` on a 2xx response. The content is either now
1429
+ * discarded as a result of this call, or was already discarded
1430
+ * before this call ran.
1431
+ *
1432
+ */
1433
+ discarded: boolean;
1434
+ /**
1435
+ * `true` if the email's content was already discarded before
1436
+ * this call ran (no work was done). `false` if this call was
1437
+ * the one that performed the discard.
1438
+ *
1439
+ */
1440
+ already_discarded: boolean;
1441
+ };
1394
1442
  /**
1395
1443
  * Resource UUID
1396
1444
  */
@@ -2025,6 +2073,53 @@ type ReplayEmailWebhooksResponses = {
2025
2073
  };
2026
2074
  };
2027
2075
  type ReplayEmailWebhooksResponse = ReplayEmailWebhooksResponses[keyof ReplayEmailWebhooksResponses];
2076
+ type DiscardEmailContentData = {
2077
+ body?: never;
2078
+ path: {
2079
+ /**
2080
+ * Resource UUID
2081
+ */
2082
+ id: string;
2083
+ };
2084
+ query?: never;
2085
+ url: '/emails/{id}/discard-content';
2086
+ };
2087
+ type DiscardEmailContentErrors = {
2088
+ /**
2089
+ * Invalid request parameters
2090
+ */
2091
+ 400: ErrorResponse;
2092
+ /**
2093
+ * Invalid or missing API key
2094
+ */
2095
+ 401: ErrorResponse;
2096
+ /**
2097
+ * Authenticated caller lacks permission for the operation
2098
+ */
2099
+ 403: ErrorResponse;
2100
+ /**
2101
+ * Resource not found
2102
+ */
2103
+ 404: ErrorResponse;
2104
+ /**
2105
+ * Rate limit exceeded
2106
+ */
2107
+ 429: ErrorResponse;
2108
+ /**
2109
+ * Primitive encountered an internal error
2110
+ */
2111
+ 500: ErrorResponse;
2112
+ };
2113
+ type DiscardEmailContentError = DiscardEmailContentErrors[keyof DiscardEmailContentErrors];
2114
+ type DiscardEmailContentResponses = {
2115
+ /**
2116
+ * Discard result
2117
+ */
2118
+ 200: SuccessEnvelope & {
2119
+ data: DiscardContentResult;
2120
+ };
2121
+ };
2122
+ type DiscardEmailContentResponse = DiscardEmailContentResponses[keyof DiscardEmailContentResponses];
2028
2123
  type ListEndpointsData = {
2029
2124
  body?: never;
2030
2125
  path?: never;
@@ -2586,7 +2681,7 @@ type GetSentEmailResponses = {
2586
2681
  };
2587
2682
  type GetSentEmailResponse = GetSentEmailResponses[keyof GetSentEmailResponses];
2588
2683
  declare namespace sdk_gen_d_exports {
2589
- export { Options, addDomain, createEndpoint, createFilter, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain };
2684
+ export { Options, addDomain, createEndpoint, createFilter, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, discardEmailContent, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain };
2590
2685
  }
2591
2686
  type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options$1<TData, ThrowOnError, TResponse> & {
2592
2687
  /**
@@ -2616,8 +2711,25 @@ declare const getStorageStats: <ThrowOnError extends boolean = false>(options?:
2616
2711
  /**
2617
2712
  * Get webhook signing secret
2618
2713
  *
2619
- * Returns the webhook signing secret for your account. If no secret
2620
- * exists yet, one is generated automatically on first access.
2714
+ * Returns the webhook signing secret for your account. If no
2715
+ * secret exists yet, one is generated automatically on first
2716
+ * access.
2717
+ *
2718
+ * Signing is account-scoped, not per-endpoint. Every webhook
2719
+ * delivery from any of your registered endpoints is signed
2720
+ * with this single secret. Rotate via
2721
+ * `POST /account/webhook-secret/rotate`.
2722
+ *
2723
+ * **Secret format**: the returned string looks base64-shaped
2724
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
2725
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
2726
+ * delivery body. Base64-decoding before HMAC will silently
2727
+ * produce mismatched signatures.
2728
+ *
2729
+ * See the API-level "Webhook signing" section for the full
2730
+ * wire format (header name, signed string shape, hash algo,
2731
+ * tolerance) including a language-agnostic verification
2732
+ * recipe.
2621
2733
  *
2622
2734
  */
2623
2735
  declare const getWebhookSecret: <ThrowOnError extends boolean = false>(options?: Options<GetWebhookSecretData, ThrowOnError>) => RequestResult<GetWebhookSecretResponses, GetWebhookSecretErrors, ThrowOnError, "fields">;
@@ -2674,12 +2786,20 @@ declare const verifyDomain: <ThrowOnError extends boolean = false>(options: Opti
2674
2786
  * List inbound emails
2675
2787
  *
2676
2788
  * Returns a paginated list of INBOUND emails received at your
2677
- * verified domains. Outbound messages sent via /send-mail are not
2678
- * included; this endpoint is the inbox view, not a unified
2679
- * send/receive history.
2789
+ * verified domains. Outbound messages sent via /send-mail are
2790
+ * not included; this endpoint is the inbox view, not a
2791
+ * unified send/receive history.
2792
+ *
2793
+ * Supports filtering by domain, status, date range, and
2794
+ * free-text search across subject, sender, and recipient
2795
+ * fields.
2680
2796
  *
2681
- * Supports filtering by domain, status, date range, and free-text
2682
- * search across subject, sender, and recipient fields.
2797
+ * For a compact text-table summary of the most recent N
2798
+ * inbounds (no filters, no cursor pagination), the CLI ships
2799
+ * `primitive emails:latest` as a one-line-per-email shortcut.
2800
+ * It's TTY-aware so id columns are full UUIDs when piped, and
2801
+ * a `--json` flag returns the same envelope this endpoint
2802
+ * does. Use whichever fits the call site.
2683
2803
  *
2684
2804
  */
2685
2805
  declare const listEmails: <ThrowOnError extends boolean = false>(options?: Options<ListEmailsData, ThrowOnError>) => RequestResult<ListEmailsResponses, ListEmailsErrors, ThrowOnError, "fields">;
@@ -2761,6 +2881,25 @@ declare const replyToEmail: <ThrowOnError extends boolean = false>(options: Opti
2761
2881
  *
2762
2882
  */
2763
2883
  declare const replayEmailWebhooks: <ThrowOnError extends boolean = false>(options: Options<ReplayEmailWebhooksData, ThrowOnError>) => RequestResult<ReplayEmailWebhooksResponses, ReplayEmailWebhooksErrors, ThrowOnError, "fields">;
2884
+ /**
2885
+ * Discard email content
2886
+ *
2887
+ * Permanently deletes the email's raw bytes, parsed body (text + HTML),
2888
+ * and attachments while preserving metadata (sender, recipient,
2889
+ * subject, timestamps, hashes, attachment manifest) for audit logs.
2890
+ * Idempotent: a second call returns success with
2891
+ * `already_discarded: true` and does no work.
2892
+ *
2893
+ * **Gated** on the customer's discard-content opt-in (managed in the
2894
+ * dashboard at Settings > Webhooks). When the toggle is off, this
2895
+ * endpoint returns `403` with code `discard_not_enabled` and a
2896
+ * message pointing the human at the dashboard. There is intentionally
2897
+ * no API to flip this toggle — opting in to a destructive,
2898
+ * non-reversible operation must be a deliberate human click in the
2899
+ * UI.
2900
+ *
2901
+ */
2902
+ declare const discardEmailContent: <ThrowOnError extends boolean = false>(options: Options<DiscardEmailContentData, ThrowOnError>) => RequestResult<DiscardEmailContentResponses, DiscardEmailContentErrors, ThrowOnError, "fields">;
2764
2903
  /**
2765
2904
  * List webhook endpoints
2766
2905
  *
@@ -2770,9 +2909,22 @@ declare const listEndpoints: <ThrowOnError extends boolean = false>(options?: Op
2770
2909
  /**
2771
2910
  * Create a webhook endpoint
2772
2911
  *
2773
- * Creates a new webhook endpoint. If a deactivated endpoint with the
2774
- * same URL and domain exists, it is reactivated instead.
2775
- * Subject to plan limits on the number of active endpoints.
2912
+ * Creates a new webhook endpoint. If a deactivated endpoint
2913
+ * with the same URL and domain exists, it is reactivated
2914
+ * instead. Subject to plan limits on the number of active
2915
+ * endpoints.
2916
+ *
2917
+ * **Signing is account-scoped, not per-endpoint.** This call
2918
+ * does not return any signing material; every endpoint on the
2919
+ * account uses the same webhook secret, fetched via
2920
+ * `GET /account/webhook-secret`. See the API-level "Webhook
2921
+ * signing" section for the full wire format (header name,
2922
+ * signed string, hash algo, secret format, tolerance) and a
2923
+ * language-agnostic verification recipe.
2924
+ *
2925
+ * After creating the endpoint, fire a test delivery against
2926
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
2927
+ * accepts the signature.
2776
2928
  *
2777
2929
  */
2778
2930
  declare const createEndpoint: <ThrowOnError extends boolean = false>(options: Options<CreateEndpointData, ThrowOnError>) => RequestResult<CreateEndpointResponses, CreateEndpointErrors, ThrowOnError, "fields">;
@@ -3054,4 +3206,4 @@ declare function createPrimitiveClient(options?: PrimitiveClientOptions): Primit
3054
3206
  declare function client(options?: PrimitiveClientOptions): PrimitiveClient;
3055
3207
  declare const operations: typeof sdk_gen_d_exports;
3056
3208
  //#endregion
3057
- export { AddDomainError as $, ListEmailsResponses as $n, SentEmailStatus as $r, EmailDetailReply as $t, getSentEmail as A, UpdateFilterErrors as Ai, GetStorageStatsErrors as An, ReplyToEmailErrors as Ar, DeleteEndpointErrors as At, replayEmailWebhooks as B, WebhookSecret as Bi, ListDeliveriesError as Bn, SendEmailError as Br, Domain as Bt, deleteEndpoint as C, UpdateEndpointError as Ci, GetSentEmailData as Cn, ReplayEmailWebhooksError as Cr, DeleteEmailData as Ct, getAccount as D, UpdateEndpointResponses as Di, GetSentEmailResponses as Dn, ReplayResult as Dr, DeleteEmailResponses as Dt, downloadRawEmail as E, UpdateEndpointResponse as Ei, GetSentEmailResponse as En, ReplayEmailWebhooksResponses as Er, DeleteEmailResponse as Et, listEmails as F, VerifyDomainData as Fi, GetWebhookSecretErrors as Fn, RotateWebhookSecretError as Fr, DeleteFilterErrors as Ft, updateAccount as G, Options$1 as Gi, ListDomainsError as Gn, SendMailResult as Gr, DownloadAttachmentsResponse as Gt, rotateWebhookSecret as H, ClientOptions$1 as Hi, ListDeliveriesResponse as Hn, SendEmailResponse as Hr, DownloadAttachmentsData as Ht, listEndpoints as I, VerifyDomainError as Ii, GetWebhookSecretResponse as In, RotateWebhookSecretErrors as Ir, DeleteFilterResponse as It, updateFilter as J, ResponseStyle as Ji, ListDomainsResponses as Jn, SendPermissionManagedZone as Jr, DownloadRawEmailError as Jt, updateDomain as K, RequestOptions as Ki, ListDomainsErrors as Kn, SendPermissionAddress as Kr, DownloadAttachmentsResponses as Kt, listFilters as L, VerifyDomainErrors as Li, GetWebhookSecretResponses as Ln, RotateWebhookSecretResponse as Lr, DeleteFilterResponses as Lt, getWebhookSecret as M, UpdateFilterResponse as Mi, GetStorageStatsResponses as Mn, ReplyToEmailResponses as Mr, DeleteEndpointResponses as Mt, listDeliveries as N, UpdateFilterResponses as Ni, GetWebhookSecretData as Nn, ResourceId as Nr, DeleteFilterData as Nt, getEmail as O, UpdateFilterData as Oi, GetStorageStatsData as On, ReplyToEmailData as Or, DeleteEndpointData as Ot, listDomains as P, VerifiedDomain as Pi, GetWebhookSecretError as Pn, RotateWebhookSecretData as Pr, DeleteFilterError as Pt, AddDomainData as Q, ListEmailsResponse as Qn, SentEmailDetail as Qr, EmailDetail as Qt, listSentEmails as R, VerifyDomainResponse as Ri, Limit as Rn, RotateWebhookSecretResponses as Rr, DeliveryStatus as Rt, deleteEmail as S, UpdateEndpointData as Si, GetSendPermissionsResponses as Sn, ReplayEmailWebhooksData as Sr, DeleteDomainResponses as St, downloadAttachments as T, UpdateEndpointInput as Ti, GetSentEmailErrors as Tn, ReplayEmailWebhooksResponse as Tr, DeleteEmailErrors as Tt, sendEmail as U, Config as Ui, ListDeliveriesResponses as Un, SendEmailResponses as Ur, DownloadAttachmentsError as Ut, replyToEmail as V, Client as Vi, ListDeliveriesErrors as Vn, SendEmailErrors as Vr, DomainVerifyResult as Vt, testEndpoint as W, CreateClientConfig as Wi, ListDomainsData as Wn, SendMailInput as Wr, DownloadAttachmentsErrors as Wt, Account as X, ListEmailsError as Xn, SendPermissionYourDomain as Xr, DownloadRawEmailResponse as Xt, verifyDomain as Y, Auth as Yi, ListEmailsData as Yn, SendPermissionRule as Yr, DownloadRawEmailErrors as Yt, AccountUpdated as Z, ListEmailsErrors as Zn, SendPermissionsMeta as Zr, DownloadRawEmailResponses as Zt, Options as _, UpdateDomainError as _i, GetEmailResponses as _n, ReplayDeliveryData as _r, Cursor as _t, PrimitiveApiError as a, TestEndpointErrors as ai, Filter as an, ListEnvelope as ar, CreateEndpointData as at, createFilter as b, UpdateDomainResponse as bi, GetSendPermissionsErrors as bn, ReplayDeliveryResponse as br, DeleteDomainErrors as bt, PrimitiveClientOptions as c, TestResult as ci, GetAccountData as cn, ListFiltersErrors as cr, CreateEndpointInput as ct, SendResult as d, UpdateAccountError as di, GetAccountResponse as dn, ListSentEmailsData as dr, CreateFilterData as dt, SentEmailSummary as ei, EmailStatus as en, ListEndpointsData as er, AddDomainErrors as et, SendThreadInput as f, UpdateAccountErrors as fi, GetAccountResponses as fn, ListSentEmailsError as fr, CreateFilterError as ft, operations as g, UpdateDomainData as gi, GetEmailResponse as gn, PaginationMeta as gr, CreateFilterResponses as gt, createPrimitiveClient as h, UpdateAccountResponses as hi, GetEmailErrors as hn, ListSentEmailsResponses as hr, CreateFilterResponse as ht, PrimitiveApiClientOptions as i, TestEndpointError as ii, ErrorResponse as in, ListEndpointsResponses as ir, ClientOptions as it, getStorageStats as j, UpdateFilterInput as ji, GetStorageStatsResponse as jn, ReplyToEmailResponse as jr, DeleteEndpointResponse as jt, getSendPermissions as k, UpdateFilterError as ki, GetStorageStatsError as kn, ReplyToEmailError as kr, DeleteEndpointError as kt, ReplyInput as l, UnverifiedDomain as li, GetAccountError as ln, ListFiltersResponse as lr, CreateEndpointResponse as lt, createPrimitiveApiClient as m, UpdateAccountResponse as mi, GetEmailError as mn, ListSentEmailsResponse as mr, CreateFilterInput as mt, ForwardInput as n, SuccessEnvelope as ni, EmailWebhookStatus as nn, ListEndpointsErrors as nr, AddDomainResponse as nt, PrimitiveApiErrorDetails as o, TestEndpointResponse as oi, GateDenial as on, ListFiltersData as or, CreateEndpointError as ot, client as p, UpdateAccountInput as pi, GetEmailData as pn, ListSentEmailsErrors as pr, CreateFilterErrors as pt, updateEndpoint as q, RequestResult as qi, ListDomainsResponse as qn, SendPermissionAnyRecipient as qr, DownloadRawEmailData as qt, PrimitiveApiClient as r, TestEndpointData as ri, Endpoint as rn, ListEndpointsResponse as rr, AddDomainResponses as rt, PrimitiveClient as s, TestEndpointResponses as si, GateFix as sn, ListFiltersError as sr, CreateEndpointErrors as st, DEFAULT_BASE_URL as t, StorageStats as ti, EmailSummary as tn, ListEndpointsError as tr, AddDomainInput as tt, SendInput as u, UpdateAccountData as ui, GetAccountErrors as un, ListFiltersResponses as ur, CreateEndpointResponses as ut, addDomain as v, UpdateDomainErrors as vi, GetSendPermissionsData as vn, ReplayDeliveryError as vr, DeleteDomainData as vt, deleteFilter as w, UpdateEndpointErrors as wi, GetSentEmailError as wn, ReplayEmailWebhooksErrors as wr, DeleteEmailError as wt, deleteDomain as x, UpdateDomainResponses as xi, GetSendPermissionsResponse as xn, ReplayDeliveryResponses as xr, DeleteDomainResponse as xt, createEndpoint as y, UpdateDomainInput as yi, GetSendPermissionsError as yn, ReplayDeliveryErrors as yr, DeleteDomainError as yt, replayDelivery as z, VerifyDomainResponses as zi, ListDeliveriesData as zn, SendEmailData as zr, DeliverySummary as zt };
3209
+ export { AddDomainData as $, RequestOptions as $i, ListDomainsErrors as $n, SendPermissionAddress as $r, DownloadAttachmentsResponses as $t, getSendPermissions as A, UpdateEndpointError as Ai, GetSentEmailData as An, ReplayEmailWebhooksError as Ar, DeleteEndpointError as At, replayDelivery as B, UpdateFilterResponses as Bi, GetWebhookSecretData as Bn, ResourceId as Br, DeliverySummary as Bt, deleteEndpoint as C, UpdateDomainData as Ci, GetEmailResponse as Cn, PaginationMeta as Cr, DeleteDomainResponses as Ct, downloadRawEmail as D, UpdateDomainResponse as Di, GetSendPermissionsErrors as Dn, ReplayDeliveryResponse as Dr, DeleteEmailResponse as Dt, downloadAttachments as E, UpdateDomainInput as Ei, GetSendPermissionsError as En, ReplayDeliveryErrors as Er, DeleteEmailErrors as Et, listDomains as F, UpdateFilterData as Fi, GetStorageStatsData as Fn, ReplyToEmailData as Fr, DeleteFilterError as Ft, testEndpoint as G, VerifyDomainResponse as Gi, Limit as Gn, RotateWebhookSecretResponses as Gr, DiscardEmailContentResponse as Gt, replyToEmail as H, VerifyDomainData as Hi, GetWebhookSecretErrors as Hn, RotateWebhookSecretError as Hr, DiscardEmailContentData as Ht, listEmails as I, UpdateFilterError as Ii, GetStorageStatsError as In, ReplyToEmailError as Ir, DeleteFilterErrors as It, updateEndpoint as J, Client as Ji, ListDeliveriesErrors as Jn, SendEmailErrors as Jr, DomainVerifyResult as Jt, updateAccount as K, VerifyDomainResponses as Ki, ListDeliveriesData as Kn, SendEmailData as Kr, DiscardEmailContentResponses as Kt, listEndpoints as L, UpdateFilterErrors as Li, GetStorageStatsErrors as Ln, ReplyToEmailErrors as Lr, DeleteFilterResponse as Lt, getStorageStats as M, UpdateEndpointInput as Mi, GetSentEmailErrors as Mn, ReplayEmailWebhooksResponse as Mr, DeleteEndpointResponse as Mt, getWebhookSecret as N, UpdateEndpointResponse as Ni, GetSentEmailResponse as Nn, ReplayEmailWebhooksResponses as Nr, DeleteEndpointResponses as Nt, getAccount as O, UpdateDomainResponses as Oi, GetSendPermissionsResponse as On, ReplayDeliveryResponses as Or, DeleteEmailResponses as Ot, listDeliveries as P, UpdateEndpointResponses as Pi, GetSentEmailResponses as Pn, ReplayResult as Pr, DeleteFilterData as Pt, AccountUpdated as Q, Options$1 as Qi, ListDomainsError as Qn, SendMailResult as Qr, DownloadAttachmentsResponse as Qt, listFilters as R, UpdateFilterInput as Ri, GetStorageStatsResponse as Rn, ReplyToEmailResponse as Rr, DeleteFilterResponses as Rt, deleteEmail as S, UpdateAccountResponses as Si, GetEmailErrors as Sn, ListSentEmailsResponses as Sr, DeleteDomainResponse as St, discardEmailContent as T, UpdateDomainErrors as Ti, GetSendPermissionsData as Tn, ReplayDeliveryError as Tr, DeleteEmailError as Tt, rotateWebhookSecret as U, VerifyDomainError as Ui, GetWebhookSecretResponse as Un, RotateWebhookSecretErrors as Ur, DiscardEmailContentError as Ut, replayEmailWebhooks as V, VerifiedDomain as Vi, GetWebhookSecretError as Vn, RotateWebhookSecretData as Vr, DiscardContentResult as Vt, sendEmail as W, VerifyDomainErrors as Wi, GetWebhookSecretResponses as Wn, RotateWebhookSecretResponse as Wr, DiscardEmailContentErrors as Wt, verifyDomain as X, Config as Xi, ListDeliveriesResponses as Xn, SendEmailResponses as Xr, DownloadAttachmentsError as Xt, updateFilter as Y, ClientOptions$1 as Yi, ListDeliveriesResponse as Yn, SendEmailResponse as Yr, DownloadAttachmentsData as Yt, Account as Z, CreateClientConfig as Zi, ListDomainsData as Zn, SendMailInput as Zr, DownloadAttachmentsErrors as Zt, Options as _, UpdateAccountData as _i, GetAccountErrors as _n, ListFiltersResponses as _r, CreateFilterResponses as _t, PrimitiveApiError as a, SentEmailDetail as ai, EmailDetail as an, ListEmailsResponse as ar, ClientOptions as at, createFilter as b, UpdateAccountInput as bi, GetEmailData as bn, ListSentEmailsErrors as br, DeleteDomainError as bt, PrimitiveClientOptions as c, StorageStats as ci, EmailSummary as cn, ListEndpointsError as cr, CreateEndpointErrors as ct, SendResult as d, TestEndpointError as di, ErrorResponse as dn, ListEndpointsResponses as dr, CreateEndpointResponses as dt, RequestResult as ea, SendPermissionAnyRecipient as ei, DownloadRawEmailData as en, ListDomainsResponse as er, AddDomainError as et, SendThreadInput as f, TestEndpointErrors as fi, Filter as fn, ListEnvelope as fr, CreateFilterData as ft, operations as g, UnverifiedDomain as gi, GetAccountError as gn, ListFiltersResponse as gr, CreateFilterResponse as gt, createPrimitiveClient as h, TestResult as hi, GetAccountData as hn, ListFiltersErrors as hr, CreateFilterInput as ht, PrimitiveApiClientOptions as i, SendPermissionsMeta as ii, DownloadRawEmailResponses as in, ListEmailsErrors as ir, AddDomainResponses as it, getSentEmail as j, UpdateEndpointErrors as ji, GetSentEmailError as jn, ReplayEmailWebhooksErrors as jr, DeleteEndpointErrors as jt, getEmail as k, UpdateEndpointData as ki, GetSendPermissionsResponses as kn, ReplayEmailWebhooksData as kr, DeleteEndpointData as kt, ReplyInput as l, SuccessEnvelope as li, EmailWebhookStatus as ln, ListEndpointsErrors as lr, CreateEndpointInput as lt, createPrimitiveApiClient as m, TestEndpointResponses as mi, GateFix as mn, ListFiltersError as mr, CreateFilterErrors as mt, ForwardInput as n, Auth as na, SendPermissionRule as ni, DownloadRawEmailErrors as nn, ListEmailsData as nr, AddDomainInput as nt, PrimitiveApiErrorDetails as o, SentEmailStatus as oi, EmailDetailReply as on, ListEmailsResponses as or, CreateEndpointData as ot, client as p, TestEndpointResponse as pi, GateDenial as pn, ListFiltersData as pr, CreateFilterError as pt, updateDomain as q, WebhookSecret as qi, ListDeliveriesError as qn, SendEmailError as qr, Domain as qt, PrimitiveApiClient as r, SendPermissionYourDomain as ri, DownloadRawEmailResponse as rn, ListEmailsError as rr, AddDomainResponse as rt, PrimitiveClient as s, SentEmailSummary as si, EmailStatus as sn, ListEndpointsData as sr, CreateEndpointError as st, DEFAULT_BASE_URL as t, ResponseStyle as ta, SendPermissionManagedZone as ti, DownloadRawEmailError as tn, ListDomainsResponses as tr, AddDomainErrors as tt, SendInput as u, TestEndpointData as ui, Endpoint as un, ListEndpointsResponse as ur, CreateEndpointResponse as ut, addDomain as v, UpdateAccountError as vi, GetAccountResponse as vn, ListSentEmailsData as vr, Cursor as vt, deleteFilter as w, UpdateDomainError as wi, GetEmailResponses as wn, ReplayDeliveryData as wr, DeleteEmailData as wt, deleteDomain as x, UpdateAccountResponse as xi, GetEmailError as xn, ListSentEmailsResponse as xr, DeleteDomainErrors as xt, createEndpoint as y, UpdateAccountErrors as yi, GetAccountResponses as yn, ListSentEmailsError as yr, DeleteDomainData as yt, listSentEmails as z, UpdateFilterResponse as zi, GetStorageStatsResponses as zn, ReplyToEmailResponses as zr, DeliveryStatus as zt };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { A as UnknownEvent, C as ParsedDataFailed, D as RawContentDownloadOnly, E as RawContent, M as WebhookAttachment, N as WebhookEvent, O as RawContentInline, S as ParsedDataComplete, T as ParsedStatus, _ as ForwardResultInline, a as DmarcPolicy, b as KnownWebhookEvent, c as EmailAnalysis, d as EventType, f as ForwardAnalysis, g as ForwardResultAttachmentSkipped, h as ForwardResultAttachmentAnalyzed, i as DkimSignature, j as ValidateEmailAuthResult, k as SpfResult, l as EmailAuth, m as ForwardResult, n as AuthVerdict, o as DmarcResult, p as ForwardOriginalSender, r as DkimResult, s as EmailAddress, t as AuthConfidence, u as EmailReceivedEvent, v as ForwardVerdict, w as ParsedError, x as ParsedData, y as ForwardVerification } from "./types-9vXGZjPd.js";
2
2
  import { a as buildReplySubject, c as parseHeaderAddress, i as buildForwardSubject, n as ReceivedEmailAddress, o as formatAddress, r as ReceivedEmailThread, s as normalizeReceivedEmail, t as ReceivedEmail } from "./received-email-DNjpq_Wt.js";
3
- import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendResult, f as SendThreadInput, h as createPrimitiveClient, l as ReplyInput, n as ForwardInput, p as client, s as PrimitiveClient, u as SendInput } from "./index-DEY4h3MZ.js";
3
+ import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendResult, f as SendThreadInput, h as createPrimitiveClient, l as ReplyInput, n as ForwardInput, p as client, s as PrimitiveClient, u as SendInput } from "./index-CHWqMBs6.js";
4
4
  import { A as VerifyOptions, B as PAYLOAD_ERRORS, C as signStandardWebhooksPayload, D as PRIMITIVE_CONFIRMED_HEADER, E as LEGACY_SIGNATURE_HEADER, F as VerifyDownloadTokenResult, G as VERIFICATION_ERRORS, H as RAW_EMAIL_ERRORS, I as generateDownloadToken, J as WebhookPayloadErrorCode, K as WebhookErrorCode, L as verifyDownloadToken, M as verifyWebhookSignature, N as GenerateDownloadTokenOptions, O as PRIMITIVE_SIGNATURE_HEADER, P as VerifyDownloadTokenOptions, Q as WebhookVerificationErrorCode, R as safeValidateEmailReceivedEvent, S as StandardWebhooksVerifyOptions, T as LEGACY_CONFIRMED_HEADER, U as RawEmailDecodeError, V as PrimitiveWebhookError, W as RawEmailDecodeErrorCode, X as WebhookValidationErrorCode, Y as WebhookValidationError, Z as WebhookVerificationError, _ as emailReceivedEventJsonSchema, a as confirmedHeaders, b as STANDARD_WEBHOOK_TIMESTAMP_HEADER, c as handleWebhook, d as isRawIncluded, f as parseWebhookEvent, g as validateEmailAuth, h as WEBHOOK_VERSION, i as WebhookHeaders, j as signWebhookPayload, k as SignResult, l as isDownloadExpired, m as verifyRawEmailDownload, n as HandleWebhookOptions, o as decodeRawEmail, p as receive, q as WebhookPayloadError, r as ReceiveRequestOptions, s as getDownloadTimeRemaining, t as DecodeRawEmailOptions, u as isEmailReceivedEvent, v as STANDARD_WEBHOOK_ID_HEADER, w as verifyStandardWebhooksSignature, x as StandardWebhooksSignResult, y as STANDARD_WEBHOOK_SIGNATURE_HEADER, z as validateEmailReceivedEvent } from "./index-CbEivn3S.js";
5
5
 
6
6
  //#region src/index.d.ts
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as parseHeaderAddress, i as normalizeReceivedEmail, n as buildReplySubject, r as formatAddress, t as buildForwardSubject } from "./received-email-D6tKtWwW.js";
2
- import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-DpATn7LQ.js";
2
+ import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-DrAZhxS-.js";
3
3
  import { A as PRIMITIVE_CONFIRMED_HEADER, B as RAW_EMAIL_ERRORS, C as STANDARD_WEBHOOK_ID_HEADER, D as verifyStandardWebhooksSignature, E as signStandardWebhooksPayload, F as verifyDownloadToken, G as WebhookVerificationError, H as VERIFICATION_ERRORS, I as safeValidateEmailReceivedEvent, L as validateEmailReceivedEvent, M as signWebhookPayload, N as verifyWebhookSignature, O as LEGACY_CONFIRMED_HEADER, P as generateDownloadToken, R as PAYLOAD_ERRORS, S as emailReceivedEventJsonSchema, T as STANDARD_WEBHOOK_TIMESTAMP_HEADER, U as WebhookPayloadError, V as RawEmailDecodeError, W as WebhookValidationError, _ as DmarcResult, a as isDownloadExpired, b as ParsedStatus, c as parseWebhookEvent, d as WEBHOOK_VERSION, f as validateEmailAuth, g as DmarcPolicy, h as DkimResult, i as handleWebhook, j as PRIMITIVE_SIGNATURE_HEADER, k as LEGACY_SIGNATURE_HEADER, l as receive, m as AuthVerdict, n as decodeRawEmail, o as isEmailReceivedEvent, p as AuthConfidence, r as getDownloadTimeRemaining, s as isRawIncluded, t as confirmedHeaders, u as verifyRawEmailDownload, v as EventType, w as STANDARD_WEBHOOK_SIGNATURE_HEADER, x as SpfResult, y as ForwardVerdict, z as PrimitiveWebhookError } from "./webhook-zkN4wUTs.js";
4
4
  //#region src/index.ts
5
5
  const primitive = {
@@ -566,9 +566,9 @@ export function createOperationCommand(operation) {
566
566
  // `sdkName` for the operation. Operations without an entry fall
567
567
  // back to no hint (silent empty array, same as before).
568
568
  const EMPTY_RESULT_HINTS = {
569
- listDeliveries: "(no results) Often means no webhook endpoints are configured to receive deliveries. Run `primitive endpoints:list-endpoints` to check.",
569
+ listDeliveries: "(no results) No webhook deliveries logged yet. If you have an endpoint configured but expected to see test fires here: test deliveries from `primitive endpoints:test-endpoint` are NOT logged in this list, they're synchronous and visible only in the test-endpoint command's response. Real deliveries are logged when an inbound `email.received` event fans out to your endpoints. If you have no endpoints, run `primitive endpoints:list-endpoints` to check.",
570
570
  listEndpoints: "(no results) No webhook endpoints configured. Add one with `primitive endpoints:create-endpoint --url <your-url>`.",
571
- listEmails: "(no results) No inbound emails received yet on this account.",
571
+ listEmails: "(no results) No inbound emails received yet on this account. Send one to a verified domain to populate this list. For a compact view, prefer `primitive emails:latest`.",
572
572
  listDomains: "(no results) No domains on this account. Add one with `primitive domains:add-domain --domain <yourdomain.example>`.",
573
573
  listFilters: "(no results) No filter rules configured.",
574
574
  };
@@ -19,7 +19,15 @@ const MAX_LIMIT = 100;
19
19
  // values wrap to "..." rather than blowing out terminal layout.
20
20
  const SUBJECT_DISPLAY_WIDTH = 50;
21
21
  const ADDRESS_DISPLAY_WIDTH = 32;
22
- const ID_DISPLAY_WIDTH = 8;
22
+ // Two ID widths: the short prefix is for human eyes (interactive
23
+ // TTY), the full UUID is for piped output (a script reading the row
24
+ // as a feed). The short prefix is useless when piped because every
25
+ // other operation requires the full UUID, so the AGX walkthrough
26
+ // kept producing a re-run with `--json` just to recover the id.
27
+ // Auto-switching by `process.stdout.isTTY` makes the common piped
28
+ // case a one-call workflow.
29
+ const ID_DISPLAY_WIDTH_SHORT = 8;
30
+ const ID_DISPLAY_WIDTH_FULL = 36;
23
31
  const RECEIVED_DISPLAY_WIDTH = 19;
24
32
  // Truncate to width with right-padding; values longer than width are
25
33
  // cut to width-3 with a "..." suffix so the output is exactly `width`
@@ -48,8 +56,22 @@ export function formatReceivedAt(value) {
48
56
  const pad = (n) => String(n).padStart(2, "0");
49
57
  return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
50
58
  }
51
- export function formatRow(email) {
52
- const id = truncate(email.id.slice(0, ID_DISPLAY_WIDTH), ID_DISPLAY_WIDTH);
59
+ // Decide whether to print the full UUID or the short 8-char prefix
60
+ // based on whether stdout is a TTY. Piped/redirected stdout (the
61
+ // caller is consuming the rows programmatically) gets full UUIDs;
62
+ // interactive terminals get the compact prefix. Pulled out as a
63
+ // helper so tests can drive the rendering branch without touching
64
+ // process.stdout.
65
+ export function pickIdWidth(isTty) {
66
+ return isTty ? ID_DISPLAY_WIDTH_SHORT : ID_DISPLAY_WIDTH_FULL;
67
+ }
68
+ export function formatRow(email, idWidth) {
69
+ // idWidth is one of ID_DISPLAY_WIDTH_SHORT or ID_DISPLAY_WIDTH_FULL.
70
+ // For SHORT, slice the UUID to the prefix length and pad. For FULL,
71
+ // pad to the full UUID width (UUIDs are already 36 chars, so this
72
+ // is effectively just an alignment guarantee for any malformed
73
+ // shorter id).
74
+ const id = truncate(email.id.slice(0, idWidth), idWidth);
53
75
  const received = formatReceivedAt(email.received_at);
54
76
  const from = truncate(email.sender ?? "", ADDRESS_DISPLAY_WIDTH);
55
77
  const to = truncate(email.recipient ?? "", ADDRESS_DISPLAY_WIDTH);
@@ -60,13 +82,14 @@ export function formatRow(email) {
60
82
  class EmailsLatestCommand extends Command {
61
83
  static description = `Print the N most recent inbound emails as a one-line-per-row text table. Designed for quick triage and visual scanning. For programmatic access, use \`primitive emails:list-emails\` (full JSON envelope, cursor pagination, filters) or pass \`--json\` here for the same raw shape without pagination/filters.
62
84
 
63
- The default text table truncates each row's id to the first ${ID_DISPLAY_WIDTH} characters for readability. Operations that take an id (\`emails:get-email\`, \`emails:delete-email\`, etc.) require the full UUID, so pass \`--json\` or use \`emails:list-emails\` when you need to feed an id back into another command.
85
+ ID display is TTY-aware. When STDOUT is a terminal, the table truncates each row's id to the first ${ID_DISPLAY_WIDTH_SHORT} characters for readability. When STDOUT is piped or redirected (the row stream is being consumed by another command), the full UUID is printed so the id can be fed straight back into \`emails:get-email\`, \`emails:delete-email\`, etc. without a separate \`--json\` round-trip.
64
86
 
65
- Output streams: the column header line is written to STDERR so the row data on STDOUT stays grep/awk-friendly. \`--json\` writes everything (including the envelope) to STDOUT.`;
87
+ Output streams: the column header line is written to STDERR so the row data on STDOUT stays grep/awk-friendly. \`--json\` writes everything (including the envelope) to STDOUT and is equivalent to running \`emails:list-emails --limit N\` for the same N.`;
66
88
  static summary = "Show the most recent inbound emails as a compact table";
67
89
  static examples = [
68
90
  "<%= config.bin %> emails:latest",
69
91
  "<%= config.bin %> emails:latest --limit 25",
92
+ "<%= config.bin %> emails:latest | head -1 | awk '{print $1}' # full UUID since piped",
70
93
  "<%= config.bin %> emails:latest --json | jq '.data[0].id'",
71
94
  ];
72
95
  static flags = {
@@ -120,11 +143,12 @@ class EmailsLatestCommand extends Command {
120
143
  process.stderr.write("No inbound emails yet. Send an email to one of your verified domains to populate this list.\n");
121
144
  return;
122
145
  }
146
+ const idWidth = pickIdWidth(Boolean(process.stdout.isTTY));
123
147
  // Header on stderr so the table itself stays grep-friendly.
124
- const header = `${"ID".padEnd(ID_DISPLAY_WIDTH)} ${"RECEIVED (UTC)".padEnd(RECEIVED_DISPLAY_WIDTH)} ${"FROM".padEnd(ADDRESS_DISPLAY_WIDTH)} ${"TO".padEnd(ADDRESS_DISPLAY_WIDTH)} SUBJECT`;
148
+ const header = `${"ID".padEnd(idWidth)} ${"RECEIVED (UTC)".padEnd(RECEIVED_DISPLAY_WIDTH)} ${"FROM".padEnd(ADDRESS_DISPLAY_WIDTH)} ${"TO".padEnd(ADDRESS_DISPLAY_WIDTH)} SUBJECT`;
125
149
  process.stderr.write(`${header}\n`);
126
150
  for (const row of rows) {
127
- this.log(formatRow(row));
151
+ this.log(formatRow(row, idWidth));
128
152
  }
129
153
  }
130
154
  }
@@ -9,7 +9,7 @@ export const openapiDocument = {
9
9
  "info": {
10
10
  "title": "Primitive API",
11
11
  "version": "1.0.0",
12
- "description": "The Primitive API lets you manage domains, emails, webhook endpoints,\nfilters, and account settings programmatically.\n\n## Authentication\n\nAll endpoints require a Bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer prim_<your_api_key>\n```\n\nAPI keys are org-scoped. Create and manage them in your dashboard\nunder Settings > API Keys.\n\n## Rate Limiting\n\nThe API enforces a sliding window rate limit of **120 requests per\n60 seconds** per organization. When exceeded, the API returns `429`\nwith a `Retry-After` header indicating how many seconds to wait.\n\n## Pagination\n\nList endpoints use cursor-based pagination. Responses include a\n`meta` object with `total`, `limit`, and `cursor` fields. Pass the\n`cursor` value as a query parameter to fetch the next page. When\n`cursor` is `null`, there are no more results.\n\n## Response Format\n\nAll responses use a consistent envelope:\n\n```json\n{\n \"success\": true,\n \"data\": { ... },\n \"meta\": { \"total\": 42, \"limit\": 50, \"cursor\": \"...\" }\n}\n```\n\nErrors follow the same pattern:\n\n```json\n{\n \"success\": false,\n \"error\": { \"code\": \"not_found\", \"message\": \"Email not found\" }\n}\n```\n",
12
+ "description": "The Primitive API lets you manage domains, emails, webhook endpoints,\nfilters, and account settings programmatically.\n\n## Authentication\n\nAll endpoints require a Bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer prim_<your_api_key>\n```\n\nAPI keys are org-scoped. Create and manage them in your dashboard\nunder Settings > API Keys.\n\n## Rate Limiting\n\nThe API enforces a sliding window rate limit of **120 requests per\n60 seconds** per organization. When exceeded, the API returns `429`\nwith a `Retry-After` header indicating how many seconds to wait.\n\n## Pagination\n\nList endpoints use cursor-based pagination. Responses include a\n`meta` object with `total`, `limit`, and `cursor` fields. Pass the\n`cursor` value as a query parameter to fetch the next page. When\n`cursor` is `null`, there are no more results.\n\n## Response Format\n\nAll responses use a consistent envelope:\n\n```json\n{\n \"success\": true,\n \"data\": { ... },\n \"meta\": { \"total\": 42, \"limit\": 50, \"cursor\": \"...\" }\n}\n```\n\nErrors follow the same pattern:\n\n```json\n{\n \"success\": false,\n \"error\": { \"code\": \"not_found\", \"message\": \"Email not found\" }\n}\n```\n\n## Webhook signing\n\nOutbound webhook deliveries (configured via the `endpoints` API)\nare signed so receivers can verify they came from Primitive and\nhave not been tampered with in transit. The signing scheme is\ndeliberately simple so it can be reimplemented in any language\nin a few lines. The Node SDK's `verifyWebhookSignature` helper\nis the reference implementation; the wire details below let you\nwrite a verifier in Python, Go, Ruby, etc. without reading our\nsource.\n\n**Header**: `Primitive-Signature: t=<unix-seconds>,v1=<hex>`\n\nA legacy `MyMX-Signature` header is also sent on every delivery\nwith the same value, retained for back-compatibility with\nintegrations written before the rename. New code should read\n`Primitive-Signature`.\n\n**Signed string**: `${timestamp}.${rawBody}` where `timestamp`\nis the Unix-seconds integer from the `t=` parameter and\n`rawBody` is the exact bytes of the HTTP request body BEFORE\nany JSON decoding. Verify against the raw body, not a\nre-serialized parse, or you will silently mismatch on\ninsignificant whitespace.\n\n**Signature**: HMAC-SHA256 of the signed string, hex-encoded\n(lowercase). Use the account's webhook secret as the HMAC key,\nas a UTF-8 byte sequence.\n\n**Secret**: returned by `GET /account/webhook-secret`. The\nstring looks base64-shaped (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`)\nbut is NOT base64; use it AS-IS as a UTF-8 string for the HMAC\nkey. Base64-decoding before HMAC will silently produce\nmismatched signatures.\n\n**Tolerance**: by convention, reject deliveries whose `t=`\ntimestamp is more than 5 minutes off your wall-clock to defend\nagainst replay attacks. The Node SDK's helper enforces this by\ndefault.\n\n**Verification recipe** (any language):\n\n```\n1. Read the raw HTTP body (do not parse).\n2. Read `Primitive-Signature: t=<ts>,v1=<sig>`.\n3. Reject if abs(now - ts) > 300 seconds.\n4. expected = HMAC_SHA256_hex(secret_utf8, f\"{ts}.{rawBody}\")\n5. Constant-time compare expected to sig. Reject if not equal.\n```\n\nFor Node, use `verifyWebhookSignature` from\n`@primitivedotdev/sdk/webhook` (or the higher-level\n`handleWebhook` helper if you want a one-liner). For other\nlanguages, the recipe above is everything you need.\n\nTest deliveries: `POST /endpoints/{id}/test` triggers a fake\ndelivery to your endpoint URL, signed with your real account\nsecret, so you can confirm verification end-to-end without\nneeding real inbound mail. The test response carries the exact\n`signature` header value sent on the wire so you can compare\nstrings directly.\n",
13
13
  "contact": {
14
14
  "name": "Primitive",
15
15
  "url": "https://primitive.dev"
@@ -193,7 +193,7 @@ export const openapiDocument = {
193
193
  "get": {
194
194
  "operationId": "getWebhookSecret",
195
195
  "summary": "Get webhook signing secret",
196
- "description": "Returns the webhook signing secret for your account. If no secret\nexists yet, one is generated automatically on first access.\n",
196
+ "description": "Returns the webhook signing secret for your account. If no\nsecret exists yet, one is generated automatically on first\naccess.\n\nSigning is account-scoped, not per-endpoint. Every webhook\ndelivery from any of your registered endpoints is signed\nwith this single secret. Rotate via\n`POST /account/webhook-secret/rotate`.\n\n**Secret format**: the returned string looks base64-shaped\n(e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.\nUse it AS-IS as a UTF-8 string when computing HMAC over a\ndelivery body. Base64-decoding before HMAC will silently\nproduce mismatched signatures.\n\nSee the API-level \"Webhook signing\" section for the full\nwire format (header name, signed string shape, hash algo,\ntolerance) including a language-agnostic verification\nrecipe.\n",
197
197
  "tags": [
198
198
  "Account"
199
199
  ],
@@ -533,7 +533,7 @@ export const openapiDocument = {
533
533
  "get": {
534
534
  "operationId": "listEmails",
535
535
  "summary": "List inbound emails",
536
- "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are not\nincluded; this endpoint is the inbox view, not a unified\nsend/receive history.\n\nSupports filtering by domain, status, date range, and free-text\nsearch across subject, sender, and recipient fields.\n",
536
+ "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are\nnot included; this endpoint is the inbox view, not a\nunified send/receive history.\n\nSupports filtering by domain, status, date range, and\nfree-text search across subject, sender, and recipient\nfields.\n\nFor a compact text-table summary of the most recent N\ninbounds (no filters, no cursor pagination), the CLI ships\n`primitive emails:latest` as a one-line-per-email shortcut.\nIt's TTY-aware so id columns are full UUIDs when piped, and\na `--json` flag returns the same envelope this endpoint\ndoes. Use whichever fits the call site.\n",
537
537
  "tags": [
538
538
  "Emails"
539
539
  ],
@@ -978,6 +978,66 @@ export const openapiDocument = {
978
978
  }
979
979
  }
980
980
  },
981
+ "/emails/{id}/discard-content": {
982
+ "parameters": [
983
+ {
984
+ "$ref": "#/components/parameters/ResourceId"
985
+ }
986
+ ],
987
+ "post": {
988
+ "operationId": "discardEmailContent",
989
+ "summary": "Discard email content",
990
+ "description": "Permanently deletes the email's raw bytes, parsed body (text + HTML),\nand attachments while preserving metadata (sender, recipient,\nsubject, timestamps, hashes, attachment manifest) for audit logs.\nIdempotent: a second call returns success with\n`already_discarded: true` and does no work.\n\n**Gated** on the customer's discard-content opt-in (managed in the\ndashboard at Settings > Webhooks). When the toggle is off, this\nendpoint returns `403` with code `discard_not_enabled` and a\nmessage pointing the human at the dashboard. There is intentionally\nno API to flip this toggle — opting in to a destructive,\nnon-reversible operation must be a deliberate human click in the\nUI.\n",
991
+ "tags": [
992
+ "Emails"
993
+ ],
994
+ "responses": {
995
+ "200": {
996
+ "description": "Discard result",
997
+ "content": {
998
+ "application/json": {
999
+ "schema": {
1000
+ "allOf": [
1001
+ {
1002
+ "$ref": "#/components/schemas/SuccessEnvelope"
1003
+ },
1004
+ {
1005
+ "type": "object",
1006
+ "properties": {
1007
+ "data": {
1008
+ "$ref": "#/components/schemas/DiscardContentResult"
1009
+ }
1010
+ },
1011
+ "required": [
1012
+ "data"
1013
+ ]
1014
+ }
1015
+ ]
1016
+ }
1017
+ }
1018
+ }
1019
+ },
1020
+ "400": {
1021
+ "$ref": "#/components/responses/ValidationError"
1022
+ },
1023
+ "401": {
1024
+ "$ref": "#/components/responses/Unauthorized"
1025
+ },
1026
+ "403": {
1027
+ "$ref": "#/components/responses/Forbidden"
1028
+ },
1029
+ "404": {
1030
+ "$ref": "#/components/responses/NotFound"
1031
+ },
1032
+ "429": {
1033
+ "$ref": "#/components/responses/RateLimited"
1034
+ },
1035
+ "500": {
1036
+ "$ref": "#/components/responses/InternalError"
1037
+ }
1038
+ }
1039
+ }
1040
+ },
981
1041
  "/endpoints": {
982
1042
  "get": {
983
1043
  "operationId": "listEndpoints",
@@ -1020,7 +1080,7 @@ export const openapiDocument = {
1020
1080
  "post": {
1021
1081
  "operationId": "createEndpoint",
1022
1082
  "summary": "Create a webhook endpoint",
1023
- "description": "Creates a new webhook endpoint. If a deactivated endpoint with the\nsame URL and domain exists, it is reactivated instead.\nSubject to plan limits on the number of active endpoints.\n",
1083
+ "description": "Creates a new webhook endpoint. If a deactivated endpoint\nwith the same URL and domain exists, it is reactivated\ninstead. Subject to plan limits on the number of active\nendpoints.\n\n**Signing is account-scoped, not per-endpoint.** This call\ndoes not return any signing material; every endpoint on the\naccount uses the same webhook secret, fetched via\n`GET /account/webhook-secret`. See the API-level \"Webhook\nsigning\" section for the full wire format (header name,\nsigned string, hash algo, secret format, tolerance) and a\nlanguage-agnostic verification recipe.\n\nAfter creating the endpoint, fire a test delivery against\nit via `POST /endpoints/{id}/test` to confirm your verifier\naccepts the signature.\n",
1024
1084
  "tags": [
1025
1085
  "Endpoints"
1026
1086
  ],
@@ -2096,6 +2156,7 @@ export const openapiDocument = {
2096
2156
  "outbound_capacity_exhausted",
2097
2157
  "outbound_response_malformed",
2098
2158
  "outbound_relay_failed",
2159
+ "discard_not_enabled",
2099
2160
  "inbound_not_repliable"
2100
2161
  ]
2101
2162
  },
@@ -3012,6 +3073,7 @@ export const openapiDocument = {
3012
3073
  },
3013
3074
  "DeliveryStatus": {
3014
3075
  "type": "string",
3076
+ "description": "Narrower enum covering only the four terminal delivery\noutcomes returned to a synchronous `wait: true` send.\n\nOn the SendMailResult shape, `delivery_status` is always\nequal to `status` whenever both are present (i.e. on\nterminal-state replays and live wait=true responses).\nThe two fields exist so callers that want to type-narrow\non \"this is a delivery outcome\" can pattern-match against\nthe four-value enum without handling the broader\nSentEmailStatus value set (which also covers `queued`,\n`submitted_to_agent`, `agent_failed`, `gate_denied`,\n`unknown`).\n\nOn async-mode and pre-terminal responses, `delivery_status`\nis absent and only `status` is populated. Use `status` if\nyou want a single field that's always present.\n",
3015
3077
  "enum": [
3016
3078
  "delivered",
3017
3079
  "bounced",
@@ -3274,7 +3336,7 @@ export const openapiDocument = {
3274
3336
  "string",
3275
3337
  "null"
3276
3338
  ],
3277
- "description": "Message identifier assigned by Primitive's outbound relay, when available."
3339
+ "description": "Message identifier assigned by Primitive's OUTBOUND relay\n(the box that signs your mail and submits it to the\nreceiving MTA). NOT the receiver's queue id.\n\nThe receiver may also report its own queue id in\n`smtp_response_text` (e.g. `\"250 2.0.0 Ok: queued as\n99D111927CDA\"` from a Postfix receiver). Those two ids\nrefer to different mail systems and are NOT comparable.\nTreat `queue_id` as Primitive-internal and the\nreceiver's id as remote-system-internal.\n\nNull on rows that never reached the relay (queued,\ngate_denied, agent_failed before signing).\n"
3278
3340
  },
3279
3341
  "accepted": {
3280
3342
  "type": "array",
@@ -3856,6 +3918,23 @@ export const openapiDocument = {
3856
3918
  "delivered",
3857
3919
  "failed"
3858
3920
  ]
3921
+ },
3922
+ "DiscardContentResult": {
3923
+ "type": "object",
3924
+ "properties": {
3925
+ "discarded": {
3926
+ "type": "boolean",
3927
+ "description": "Always `true` on a 2xx response. The content is either now\ndiscarded as a result of this call, or was already discarded\nbefore this call ran.\n"
3928
+ },
3929
+ "already_discarded": {
3930
+ "type": "boolean",
3931
+ "description": "`true` if the email's content was already discarded before\nthis call ran (no work was done). `false` if this call was\nthe one that performed the discard.\n"
3932
+ }
3933
+ },
3934
+ "required": [
3935
+ "discarded",
3936
+ "already_discarded"
3937
+ ]
3859
3938
  }
3860
3939
  }
3861
3940
  }
@@ -152,7 +152,7 @@ export const operationManifest = [
152
152
  "binaryResponse": false,
153
153
  "bodyRequired": false,
154
154
  "command": "get-webhook-secret",
155
- "description": "Returns the webhook signing secret for your account. If no secret\nexists yet, one is generated automatically on first access.\n",
155
+ "description": "Returns the webhook signing secret for your account. If no\nsecret exists yet, one is generated automatically on first\naccess.\n\nSigning is account-scoped, not per-endpoint. Every webhook\ndelivery from any of your registered endpoints is signed\nwith this single secret. Rotate via\n`POST /account/webhook-secret/rotate`.\n\n**Secret format**: the returned string looks base64-shaped\n(e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.\nUse it AS-IS as a UTF-8 string when computing HMAC over a\ndelivery body. Base64-decoding before HMAC will silently\nproduce mismatched signatures.\n\nSee the API-level \"Webhook signing\" section for the full\nwire format (header name, signed string shape, hash algo,\ntolerance) including a language-agnostic verification\nrecipe.\n",
156
156
  "hasJsonBody": false,
157
157
  "method": "GET",
158
158
  "operationId": "getWebhookSecret",
@@ -664,6 +664,48 @@ export const operationManifest = [
664
664
  "tag": "Emails",
665
665
  "tagCommand": "emails"
666
666
  },
667
+ {
668
+ "binaryResponse": false,
669
+ "bodyRequired": false,
670
+ "command": "discard-email-content",
671
+ "description": "Permanently deletes the email's raw bytes, parsed body (text + HTML),\nand attachments while preserving metadata (sender, recipient,\nsubject, timestamps, hashes, attachment manifest) for audit logs.\nIdempotent: a second call returns success with\n`already_discarded: true` and does no work.\n\n**Gated** on the customer's discard-content opt-in (managed in the\ndashboard at Settings > Webhooks). When the toggle is off, this\nendpoint returns `403` with code `discard_not_enabled` and a\nmessage pointing the human at the dashboard. There is intentionally\nno API to flip this toggle — opting in to a destructive,\nnon-reversible operation must be a deliberate human click in the\nUI.\n",
672
+ "hasJsonBody": false,
673
+ "method": "POST",
674
+ "operationId": "discardEmailContent",
675
+ "path": "/emails/{id}/discard-content",
676
+ "pathParams": [
677
+ {
678
+ "description": "Resource UUID",
679
+ "enum": null,
680
+ "name": "id",
681
+ "required": true,
682
+ "type": "string"
683
+ }
684
+ ],
685
+ "queryParams": [],
686
+ "requestSchema": null,
687
+ "responseSchema": {
688
+ "type": "object",
689
+ "properties": {
690
+ "discarded": {
691
+ "type": "boolean",
692
+ "description": "Always `true` on a 2xx response. The content is either now\ndiscarded as a result of this call, or was already discarded\nbefore this call ran.\n"
693
+ },
694
+ "already_discarded": {
695
+ "type": "boolean",
696
+ "description": "`true` if the email's content was already discarded before\nthis call ran (no work was done). `false` if this call was\nthe one that performed the discard.\n"
697
+ }
698
+ },
699
+ "required": [
700
+ "discarded",
701
+ "already_discarded"
702
+ ]
703
+ },
704
+ "sdkName": "discardEmailContent",
705
+ "summary": "Discard email content",
706
+ "tag": "Emails",
707
+ "tagCommand": "emails"
708
+ },
667
709
  {
668
710
  "binaryResponse": true,
669
711
  "bodyRequired": false,
@@ -1029,7 +1071,7 @@ export const operationManifest = [
1029
1071
  "binaryResponse": false,
1030
1072
  "bodyRequired": false,
1031
1073
  "command": "list-emails",
1032
- "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are not\nincluded; this endpoint is the inbox view, not a unified\nsend/receive history.\n\nSupports filtering by domain, status, date range, and free-text\nsearch across subject, sender, and recipient fields.\n",
1074
+ "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are\nnot included; this endpoint is the inbox view, not a\nunified send/receive history.\n\nSupports filtering by domain, status, date range, and\nfree-text search across subject, sender, and recipient\nfields.\n\nFor a compact text-table summary of the most recent N\ninbounds (no filters, no cursor pagination), the CLI ships\n`primitive emails:latest` as a one-line-per-email shortcut.\nIt's TTY-aware so id columns are full UUIDs when piped, and\na `--json` flag returns the same envelope this endpoint\ndoes. Use whichever fits the call site.\n",
1033
1075
  "hasJsonBody": false,
1034
1076
  "method": "GET",
1035
1077
  "operationId": "listEmails",
@@ -1244,7 +1286,7 @@ export const operationManifest = [
1244
1286
  "binaryResponse": false,
1245
1287
  "bodyRequired": true,
1246
1288
  "command": "create-endpoint",
1247
- "description": "Creates a new webhook endpoint. If a deactivated endpoint with the\nsame URL and domain exists, it is reactivated instead.\nSubject to plan limits on the number of active endpoints.\n",
1289
+ "description": "Creates a new webhook endpoint. If a deactivated endpoint\nwith the same URL and domain exists, it is reactivated\ninstead. Subject to plan limits on the number of active\nendpoints.\n\n**Signing is account-scoped, not per-endpoint.** This call\ndoes not return any signing material; every endpoint on the\naccount uses the same webhook secret, fetched via\n`GET /account/webhook-secret`. See the API-level \"Webhook\nsigning\" section for the full wire format (header name,\nsigned string, hash algo, secret format, tolerance) and a\nlanguage-agnostic verification recipe.\n\nAfter creating the endpoint, fire a test delivery against\nit via `POST /endpoints/{id}/test` to confirm your verifier\naccepts the signature.\n",
1248
1290
  "hasJsonBody": true,
1249
1291
  "method": "POST",
1250
1292
  "operationId": "createEndpoint",
@@ -2836,7 +2878,7 @@ export const operationManifest = [
2836
2878
  "string",
2837
2879
  "null"
2838
2880
  ],
2839
- "description": "Message identifier assigned by Primitive's outbound relay, when available."
2881
+ "description": "Message identifier assigned by Primitive's OUTBOUND relay\n(the box that signs your mail and submits it to the\nreceiving MTA). NOT the receiver's queue id.\n\nThe receiver may also report its own queue id in\n`smtp_response_text` (e.g. `\"250 2.0.0 Ok: queued as\n99D111927CDA\"` from a Postfix receiver). Those two ids\nrefer to different mail systems and are NOT comparable.\nTreat `queue_id` as Primitive-internal and the\nreceiver's id as remote-system-internal.\n\nNull on rows that never reached the relay (queued,\ngate_denied, agent_failed before signing).\n"
2840
2882
  },
2841
2883
  "accepted": {
2842
2884
  "type": "array",
@@ -2866,6 +2908,7 @@ export const operationManifest = [
2866
2908
  },
2867
2909
  "delivery_status": {
2868
2910
  "type": "string",
2911
+ "description": "Narrower enum covering only the four terminal delivery\noutcomes returned to a synchronous `wait: true` send.\n\nOn the SendMailResult shape, `delivery_status` is always\nequal to `status` whenever both are present (i.e. on\nterminal-state replays and live wait=true responses).\nThe two fields exist so callers that want to type-narrow\non \"this is a delivery outcome\" can pattern-match against\nthe four-value enum without handling the broader\nSentEmailStatus value set (which also covers `queued`,\n`submitted_to_agent`, `agent_failed`, `gate_denied`,\n`unknown`).\n\nOn async-mode and pre-terminal responses, `delivery_status`\nis absent and only `status` is populated. Use `status` if\nyou want a single field that's always present.\n",
2869
2912
  "enum": [
2870
2913
  "delivered",
2871
2914
  "bounced",
@@ -3014,7 +3057,7 @@ export const operationManifest = [
3014
3057
  "string",
3015
3058
  "null"
3016
3059
  ],
3017
- "description": "Message identifier assigned by Primitive's outbound relay, when available."
3060
+ "description": "Message identifier assigned by Primitive's OUTBOUND relay\n(the box that signs your mail and submits it to the\nreceiving MTA). NOT the receiver's queue id.\n\nThe receiver may also report its own queue id in\n`smtp_response_text` (e.g. `\"250 2.0.0 Ok: queued as\n99D111927CDA\"` from a Postfix receiver). Those two ids\nrefer to different mail systems and are NOT comparable.\nTreat `queue_id` as Primitive-internal and the\nreceiver's id as remote-system-internal.\n\nNull on rows that never reached the relay (queued,\ngate_denied, agent_failed before signing).\n"
3018
3061
  },
3019
3062
  "accepted": {
3020
3063
  "type": "array",
@@ -3044,6 +3087,7 @@ export const operationManifest = [
3044
3087
  },
3045
3088
  "delivery_status": {
3046
3089
  "type": "string",
3090
+ "description": "Narrower enum covering only the four terminal delivery\noutcomes returned to a synchronous `wait: true` send.\n\nOn the SendMailResult shape, `delivery_status` is always\nequal to `status` whenever both are present (i.e. on\nterminal-state replays and live wait=true responses).\nThe two fields exist so callers that want to type-narrow\non \"this is a delivery outcome\" can pattern-match against\nthe four-value enum without handling the broader\nSentEmailStatus value set (which also covers `queued`,\n`submitted_to_agent`, `agent_failed`, `gate_denied`,\n`unknown`).\n\nOn async-mode and pre-terminal responses, `delivery_status`\nis absent and only `status` is populated. Use `status` if\nyou want a single field that's always present.\n",
3047
3091
  "enum": [
3048
3092
  "delivered",
3049
3093
  "bounced",
@@ -201,10 +201,11 @@
201
201
  "emails:latest": {
202
202
  "aliases": [],
203
203
  "args": {},
204
- "description": "Print the N most recent inbound emails as a one-line-per-row text table. Designed for quick triage and visual scanning. For programmatic access, use `primitive emails:list-emails` (full JSON envelope, cursor pagination, filters) or pass `--json` here for the same raw shape without pagination/filters.\n\n The default text table truncates each row's id to the first 8 characters for readability. Operations that take an id (`emails:get-email`, `emails:delete-email`, etc.) require the full UUID, so pass `--json` or use `emails:list-emails` when you need to feed an id back into another command.\n\n Output streams: the column header line is written to STDERR so the row data on STDOUT stays grep/awk-friendly. `--json` writes everything (including the envelope) to STDOUT.",
204
+ "description": "Print the N most recent inbound emails as a one-line-per-row text table. Designed for quick triage and visual scanning. For programmatic access, use `primitive emails:list-emails` (full JSON envelope, cursor pagination, filters) or pass `--json` here for the same raw shape without pagination/filters.\n\n ID display is TTY-aware. When STDOUT is a terminal, the table truncates each row's id to the first 8 characters for readability. When STDOUT is piped or redirected (the row stream is being consumed by another command), the full UUID is printed so the id can be fed straight back into `emails:get-email`, `emails:delete-email`, etc. without a separate `--json` round-trip.\n\n Output streams: the column header line is written to STDERR so the row data on STDOUT stays grep/awk-friendly. `--json` writes everything (including the envelope) to STDOUT and is equivalent to running `emails:list-emails --limit N` for the same N.",
205
205
  "examples": [
206
206
  "<%= config.bin %> emails:latest",
207
207
  "<%= config.bin %> emails:latest --limit 25",
208
+ "<%= config.bin %> emails:latest | head -1 | awk '{print $1}' # full UUID since piped",
208
209
  "<%= config.bin %> emails:latest --json | jq '.data[0].id'"
209
210
  ],
210
211
  "flags": {
@@ -316,7 +317,7 @@
316
317
  "account:get-webhook-secret": {
317
318
  "aliases": [],
318
319
  "args": {},
319
- "description": "Returns the webhook signing secret for your account. If no secret\nexists yet, one is generated automatically on first access.\n",
320
+ "description": "Returns the webhook signing secret for your account. If no\nsecret exists yet, one is generated automatically on first\naccess.\n\nSigning is account-scoped, not per-endpoint. Every webhook\ndelivery from any of your registered endpoints is signed\nwith this single secret. Rotate via\n`POST /account/webhook-secret/rotate`.\n\n**Secret format**: the returned string looks base64-shaped\n(e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.\nUse it AS-IS as a UTF-8 string when computing HMAC over a\ndelivery body. Base64-decoding before HMAC will silently\nproduce mismatched signatures.\n\nSee the API-level \"Webhook signing\" section for the full\nwire format (header name, signed string shape, hash algo,\ntolerance) including a language-agnostic verification\nrecipe.\n",
320
321
  "flags": {
321
322
  "api-key": {
322
323
  "description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
@@ -708,6 +709,46 @@
708
709
  "summary": "Delete an email",
709
710
  "enableJsonFlag": false
710
711
  },
712
+ "emails:discard-email-content": {
713
+ "aliases": [],
714
+ "args": {},
715
+ "description": "Permanently deletes the email's raw bytes, parsed body (text + HTML),\nand attachments while preserving metadata (sender, recipient,\nsubject, timestamps, hashes, attachment manifest) for audit logs.\nIdempotent: a second call returns success with\n`already_discarded: true` and does no work.\n\n**Gated** on the customer's discard-content opt-in (managed in the\ndashboard at Settings > Webhooks). When the toggle is off, this\nendpoint returns `403` with code `discard_not_enabled` and a\nmessage pointing the human at the dashboard. There is intentionally\nno API to flip this toggle — opting in to a destructive,\nnon-reversible operation must be a deliberate human click in the\nUI.\n",
716
+ "flags": {
717
+ "api-key": {
718
+ "description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
719
+ "env": "PRIMITIVE_API_KEY",
720
+ "name": "api-key",
721
+ "hasDynamicHelp": false,
722
+ "multiple": false,
723
+ "type": "option"
724
+ },
725
+ "base-url": {
726
+ "description": "API base URL (defaults to PRIMITIVE_API_URL or production)",
727
+ "env": "PRIMITIVE_API_URL",
728
+ "name": "base-url",
729
+ "hasDynamicHelp": false,
730
+ "multiple": false,
731
+ "type": "option"
732
+ },
733
+ "id": {
734
+ "description": "Resource UUID",
735
+ "name": "id",
736
+ "required": true,
737
+ "hasDynamicHelp": false,
738
+ "multiple": false,
739
+ "type": "option"
740
+ }
741
+ },
742
+ "hasDynamicHelp": false,
743
+ "hiddenAliases": [],
744
+ "id": "emails:discard-email-content",
745
+ "pluginAlias": "@primitivedotdev/sdk",
746
+ "pluginName": "@primitivedotdev/sdk",
747
+ "pluginType": "core",
748
+ "strict": true,
749
+ "summary": "Discard email content",
750
+ "enableJsonFlag": false
751
+ },
711
752
  "emails:download-attachments": {
712
753
  "aliases": [],
713
754
  "args": {},
@@ -861,7 +902,7 @@
861
902
  "emails:list-emails": {
862
903
  "aliases": [],
863
904
  "args": {},
864
- "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are not\nincluded; this endpoint is the inbox view, not a unified\nsend/receive history.\n\nSupports filtering by domain, status, date range, and free-text\nsearch across subject, sender, and recipient fields.\n",
905
+ "description": "Returns a paginated list of INBOUND emails received at your\nverified domains. Outbound messages sent via /send-mail are\nnot included; this endpoint is the inbox view, not a\nunified send/receive history.\n\nSupports filtering by domain, status, date range, and\nfree-text search across subject, sender, and recipient\nfields.\n\nFor a compact text-table summary of the most recent N\ninbounds (no filters, no cursor pagination), the CLI ships\n`primitive emails:latest` as a one-line-per-email shortcut.\nIt's TTY-aware so id columns are full UUIDs when piped, and\na `--json` flag returns the same envelope this endpoint\ndoes. Use whichever fits the call site.\n",
865
906
  "flags": {
866
907
  "api-key": {
867
908
  "description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
@@ -989,7 +1030,7 @@
989
1030
  "endpoints:create-endpoint": {
990
1031
  "aliases": [],
991
1032
  "args": {},
992
- "description": "Creates a new webhook endpoint. If a deactivated endpoint with the\nsame URL and domain exists, it is reactivated instead.\nSubject to plan limits on the number of active endpoints.\n\n\nBody fields requiring --raw-body JSON (these are not exposed as flags):\n rules object Endpoint-specific filtering rules\n(* = required. Scalar body fields are exposed as individual --flag-name flags; see FLAGS above.)",
1033
+ "description": "Creates a new webhook endpoint. If a deactivated endpoint\nwith the same URL and domain exists, it is reactivated\ninstead. Subject to plan limits on the number of active\nendpoints.\n\n**Signing is account-scoped, not per-endpoint.** This call\ndoes not return any signing material; every endpoint on the\naccount uses the same webhook secret, fetched via\n`GET /account/webhook-secret`. See the API-level \"Webhook\nsigning\" section for the full wire format (header name,\nsigned string, hash algo, secret format, tolerance) and a\nlanguage-agnostic verification recipe.\n\nAfter creating the endpoint, fire a test delivery against\nit via `POST /endpoints/{id}/test` to confirm your verifier\naccepts the signature.\n\n\nBody fields requiring --raw-body JSON (these are not exposed as flags):\n rules object Endpoint-specific filtering rules\n(* = required. Scalar body fields are exposed as individual --flag-name flags; see FLAGS above.)",
993
1034
  "flags": {
994
1035
  "api-key": {
995
1036
  "description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
@@ -1910,5 +1951,5 @@
1910
1951
  "enableJsonFlag": false
1911
1952
  }
1912
1953
  },
1913
- "version": "0.15.0"
1954
+ "version": "0.17.0"
1914
1955
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitivedotdev/sdk",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Official Primitive Node.js SDK — webhook, api, openapi, contract, and parser modules",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",