primitive 1.72.2 → 1.73.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,3 +1,4 @@
1
+ import { n as createConfig, t as createClient } from "./client.gen-CaaMP86o.js";
1
2
  //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -30,6 +31,3587 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
31
  enumerable: true
31
32
  }) : target, mod));
32
33
  //#endregion
34
+ //#region ../packages/api-core/src/api/client.gen.ts
35
+ const client = createClient(createConfig({ baseUrl: "https://api.primitive.dev/v1" }));
36
+ //#endregion
37
+ //#region ../packages/api-core/src/api/sdk.gen.ts
38
+ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
39
+ addDefaultNetworkMember: () => addDefaultNetworkMember,
40
+ addDomain: () => addDomain,
41
+ agentConnectionSetup: () => agentConnectionSetup,
42
+ awaitReply: () => awaitReply,
43
+ cancelSentEmail: () => cancelSentEmail,
44
+ cancelSentEmailByIdempotencyKey: () => cancelSentEmailByIdempotencyKey,
45
+ checkDefaultNetworkContactAdmission: () => checkDefaultNetworkContactAdmission,
46
+ checkDomainDns: () => checkDomainDns,
47
+ claimAgentConnection: () => claimAgentConnection,
48
+ cliLogout: () => cliLogout,
49
+ completeWebhookEvent: () => completeWebhookEvent,
50
+ createAgentAccount: () => createAgentAccount,
51
+ createAgentClaimLink: () => createAgentClaimLink,
52
+ createAgentConnection: () => createAgentConnection,
53
+ createChallenge: () => createChallenge,
54
+ createEmailChallenge: () => createEmailChallenge,
55
+ createEndpoint: () => createEndpoint,
56
+ createFilter: () => createFilter,
57
+ createFunction: () => createFunction,
58
+ createFunctionSecret: () => createFunctionSecret,
59
+ createOrgSecret: () => createOrgSecret,
60
+ createRegistry: () => createRegistry,
61
+ createRoute: () => createRoute,
62
+ createWakeAuthorization: () => createWakeAuthorization,
63
+ createWakeSchedule: () => createWakeSchedule,
64
+ decideRegistryRequest: () => decideRegistryRequest,
65
+ defineAgent: () => defineAgent,
66
+ deleteAgentContact: () => deleteAgentContact,
67
+ deleteContact: () => deleteContact,
68
+ deleteDomain: () => deleteDomain,
69
+ deleteEmail: () => deleteEmail,
70
+ deleteEndpoint: () => deleteEndpoint,
71
+ deleteFilter: () => deleteFilter,
72
+ deleteFunction: () => deleteFunction,
73
+ deleteFunctionSecret: () => deleteFunctionSecret,
74
+ deleteMemory: () => deleteMemory,
75
+ deleteOrgSecret: () => deleteOrgSecret,
76
+ deleteRegistry: () => deleteRegistry,
77
+ deleteRepeatingSend: () => deleteRepeatingSend,
78
+ deleteRoute: () => deleteRoute,
79
+ deleteSentEmail: () => deleteSentEmail,
80
+ deleteWakeAuthorization: () => deleteWakeAuthorization,
81
+ deleteWakeSchedule: () => deleteWakeSchedule,
82
+ discardEmailContent: () => discardEmailContent,
83
+ downloadAttachments: () => downloadAttachments,
84
+ downloadDomainZoneFile: () => downloadDomainZoneFile,
85
+ downloadEmailAttachmentArchiveMember: () => downloadEmailAttachmentArchiveMember,
86
+ downloadEmailAttachmentByFilename: () => downloadEmailAttachmentByFilename,
87
+ downloadEmailAttachmentPart: () => downloadEmailAttachmentPart,
88
+ downloadRawEmail: () => downloadRawEmail,
89
+ downloadSentAttachmentArchiveMember: () => downloadSentAttachmentArchiveMember,
90
+ downloadSentAttachmentByFilename: () => downloadSentAttachmentByFilename,
91
+ downloadSentAttachmentPart: () => downloadSentAttachmentPart,
92
+ getAccount: () => getAccount,
93
+ getAgent: () => getAgent,
94
+ getAgentContactPolicy: () => getAgentContactPolicy,
95
+ getChallenge: () => getChallenge,
96
+ getContact: () => getContact,
97
+ getContactPolicy: () => getContactPolicy,
98
+ getConversation: () => getConversation,
99
+ getCreditBalance: () => getCreditBalance,
100
+ getDefaultNetworkAgent: () => getDefaultNetworkAgent,
101
+ getEmail: () => getEmail,
102
+ getFunction: () => getFunction,
103
+ getFunctionRouting: () => getFunctionRouting,
104
+ getFunctionTestRunTrace: () => getFunctionTestRunTrace,
105
+ getInboxStatus: () => getInboxStatus,
106
+ getMemory: () => getMemory,
107
+ getOrgRoutingTopology: () => getOrgRoutingTopology,
108
+ getOutboundStatus: () => getOutboundStatus,
109
+ getRegistry: () => getRegistry,
110
+ getRepeatingSend: () => getRepeatingSend,
111
+ getSendPermissions: () => getSendPermissions,
112
+ getSentEmail: () => getSentEmail,
113
+ getSpendPolicy: () => getSpendPolicy,
114
+ getStorageStats: () => getStorageStats,
115
+ getTemplate: () => getTemplate,
116
+ getTemplateInstall: () => getTemplateInstall,
117
+ getThread: () => getThread,
118
+ getWakeSchedule: () => getWakeSchedule,
119
+ getWebhookSecret: () => getWebhookSecret,
120
+ installTemplate: () => installTemplate,
121
+ inviteAgentConnection: () => inviteAgentConnection,
122
+ listAgentConnections: () => listAgentConnections,
123
+ listAgentContacts: () => listAgentContacts,
124
+ listAgentNetworks: () => listAgentNetworks,
125
+ listChanges: () => listChanges,
126
+ listContacts: () => listContacts,
127
+ listDeclinedPayments: () => listDeclinedPayments,
128
+ listDefaultNetworkAgents: () => listDefaultNetworkAgents,
129
+ listDefaultNetworkMembers: () => listDefaultNetworkMembers,
130
+ listDeliveries: () => listDeliveries,
131
+ listDomains: () => listDomains,
132
+ listEmailAttachmentArchiveMembers: () => listEmailAttachmentArchiveMembers,
133
+ listEmails: () => listEmails,
134
+ listEndpoints: () => listEndpoints,
135
+ listFilters: () => listFilters,
136
+ listFunctionLogs: () => listFunctionLogs,
137
+ listFunctionSecrets: () => listFunctionSecrets,
138
+ listFunctions: () => listFunctions,
139
+ listOrgSecrets: () => listOrgSecrets,
140
+ listPayoutAddresses: () => listPayoutAddresses,
141
+ listRegistries: () => listRegistries,
142
+ listRegistryAgents: () => listRegistryAgents,
143
+ listRegistryRequests: () => listRegistryRequests,
144
+ listRepeatingSends: () => listRepeatingSends,
145
+ listRoutes: () => listRoutes,
146
+ listSentAttachmentArchiveMembers: () => listSentAttachmentArchiveMembers,
147
+ listSentEmails: () => listSentEmails,
148
+ listTemplates: () => listTemplates,
149
+ listWakeAuthorizations: () => listWakeAuthorizations,
150
+ listWakeDispatches: () => listWakeDispatches,
151
+ listWakeSchedules: () => listWakeSchedules,
152
+ payChallenge: () => payChallenge,
153
+ pollCliLogin: () => pollCliLogin,
154
+ provisionMemberAddress: () => provisionMemberAddress,
155
+ publishAgent: () => publishAgent,
156
+ pullWebhookEvent: () => pullWebhookEvent,
157
+ putAgentContact: () => putAgentContact,
158
+ putAgentContactPolicy: () => putAgentContactPolicy,
159
+ putContact: () => putContact,
160
+ putContactPolicy: () => putContactPolicy,
161
+ redeemCreditCode: () => redeemCreditCode,
162
+ registerPayoutAddress: () => registerPayoutAddress,
163
+ removeAgentConnection: () => removeAgentConnection,
164
+ removeDefaultNetworkMember: () => removeDefaultNetworkMember,
165
+ reorderRoutes: () => reorderRoutes,
166
+ replayDelivery: () => replayDelivery,
167
+ replayEmailWebhooks: () => replayEmailWebhooks,
168
+ replyToEmail: () => replyToEmail,
169
+ rescheduleSentEmail: () => rescheduleSentEmail,
170
+ resendAgentSignupVerification: () => resendAgentSignupVerification,
171
+ resendCliSignupVerification: () => resendCliSignupVerification,
172
+ resolveRegistryHandle: () => resolveRegistryHandle,
173
+ revokeAgentConnection: () => revokeAgentConnection,
174
+ rotateWebhookSecret: () => rotateWebhookSecret,
175
+ runWakeSchedule: () => runWakeSchedule,
176
+ searchEmails: () => searchEmails,
177
+ searchMemories: () => searchMemories,
178
+ semanticSearch: () => semanticSearch,
179
+ sendEmail: () => sendEmail,
180
+ setFunctionRoute: () => setFunctionRoute,
181
+ setFunctionSecret: () => setFunctionSecret,
182
+ setMemory: () => setMemory,
183
+ setOrgSecret: () => setOrgSecret,
184
+ simulateRoute: () => simulateRoute,
185
+ startAgentClaim: () => startAgentClaim,
186
+ startAgentSignup: () => startAgentSignup,
187
+ startCliLogin: () => startCliLogin,
188
+ startCliSignup: () => startCliSignup,
189
+ stopRepeatFromEmail: () => stopRepeatFromEmail,
190
+ testEndpoint: () => testEndpoint,
191
+ testEndpointRules: () => testEndpointRules,
192
+ testFunction: () => testFunction,
193
+ unpublishAgent: () => unpublishAgent,
194
+ unsetFunctionRoute: () => unsetFunctionRoute,
195
+ updateAccount: () => updateAccount,
196
+ updateDefaultNetworkMember: () => updateDefaultNetworkMember,
197
+ updateDomain: () => updateDomain,
198
+ updateEndpoint: () => updateEndpoint,
199
+ updateFilter: () => updateFilter,
200
+ updateFunction: () => updateFunction,
201
+ updateRegistry: () => updateRegistry,
202
+ updateRepeatingSend: () => updateRepeatingSend,
203
+ updateRoute: () => updateRoute,
204
+ updateSpendPolicy: () => updateSpendPolicy,
205
+ updateWakeAuthorization: () => updateWakeAuthorization,
206
+ updateWakeSchedule: () => updateWakeSchedule,
207
+ verifyAgentClaim: () => verifyAgentClaim,
208
+ verifyAgentSignup: () => verifyAgentSignup,
209
+ verifyCliSignup: () => verifyCliSignup,
210
+ verifyDomain: () => verifyDomain,
211
+ whoami: () => whoami
212
+ });
213
+ /**
214
+ * Start CLI browser login
215
+ *
216
+ * Starts a browser-assisted CLI login session. The response includes a
217
+ * device code for polling and a user code that the user approves in the
218
+ * browser. This endpoint does not require an API key.
219
+ *
220
+ */
221
+ const startCliLogin = (options) => (options?.client ?? client).post({
222
+ url: "/cli/login/start",
223
+ ...options,
224
+ headers: {
225
+ "Content-Type": "application/json",
226
+ ...options?.headers
227
+ }
228
+ });
229
+ /**
230
+ * Poll CLI browser login
231
+ *
232
+ * Polls a CLI login session until the browser approval either succeeds,
233
+ * is denied, expires, or is polled too quickly. The OAuth token set is
234
+ * created only after approval and is returned exactly once.
235
+ *
236
+ */
237
+ const pollCliLogin = (options) => (options.client ?? client).post({
238
+ url: "/cli/login/poll",
239
+ ...options,
240
+ headers: {
241
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
242
+ ...options.headers
243
+ }
244
+ });
245
+ /**
246
+ * Start CLI account signup
247
+ *
248
+ * Starts a terminal-native CLI signup. The API creates a pending
249
+ * signup session, sends an email verification code, and returns an opaque
250
+ * signup token used by the resend and verify steps. This endpoint
251
+ * does not require an API key.
252
+ *
253
+ */
254
+ const startCliSignup = (options) => (options.client ?? client).post({
255
+ url: "/cli/signup/start",
256
+ ...options,
257
+ headers: {
258
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
259
+ ...options.headers
260
+ }
261
+ });
262
+ /**
263
+ * Resend CLI signup verification code
264
+ *
265
+ * Sends a new email verification code for a pending CLI signup session.
266
+ * This endpoint does not require an API key.
267
+ *
268
+ */
269
+ const resendCliSignupVerification = (options) => (options.client ?? client).post({
270
+ url: "/cli/signup/resend",
271
+ ...options,
272
+ headers: {
273
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
274
+ ...options.headers
275
+ }
276
+ });
277
+ /**
278
+ * Verify CLI signup and create OAuth session
279
+ *
280
+ * Verifies the email code for a CLI signup session and creates the
281
+ * account. An org-scoped OAuth CLI session is created and the
282
+ * token set is returned exactly once. This endpoint does not
283
+ * require an API key.
284
+ *
285
+ */
286
+ const verifyCliSignup = (options) => (options.client ?? client).post({
287
+ url: "/cli/signup/verify",
288
+ ...options,
289
+ headers: {
290
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
291
+ ...options.headers
292
+ }
293
+ });
294
+ /**
295
+ * Start agent account signup
296
+ *
297
+ * Starts an agent-native signup session. The API creates a pending
298
+ * signup session, sends an email verification code, and returns an opaque
299
+ * signup token used by the resend and verify steps. This endpoint
300
+ * does not require an API key.
301
+ *
302
+ */
303
+ const startAgentSignup = (options) => (options.client ?? client).post({
304
+ url: "/agent/signup/start",
305
+ ...options,
306
+ headers: {
307
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
308
+ ...options.headers
309
+ }
310
+ });
311
+ /**
312
+ * Resend agent signup verification code
313
+ *
314
+ * Sends a new email verification code for a pending agent signup session.
315
+ * This endpoint does not require an API key.
316
+ *
317
+ */
318
+ const resendAgentSignupVerification = (options) => (options.client ?? client).post({
319
+ url: "/agent/signup/resend",
320
+ ...options,
321
+ headers: {
322
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
323
+ ...options.headers
324
+ }
325
+ });
326
+ /**
327
+ * Verify agent signup and create OAuth tokens
328
+ *
329
+ * Verifies the email code for an agent signup session and creates
330
+ * the account when needed. An org-scoped OAuth session for CLI
331
+ * authentication is minted and the raw tokens are returned exactly
332
+ * once. For existing users, the optional `org_id` selects which
333
+ * accessible workspace should receive the new session.
334
+ *
335
+ */
336
+ const verifyAgentSignup = (options) => (options.client ?? client).post({
337
+ url: "/agent/signup/verify",
338
+ ...options,
339
+ headers: {
340
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
341
+ ...options.headers
342
+ }
343
+ });
344
+ /**
345
+ * Create an emailless agent account
346
+ *
347
+ * Creates an emailless agent account without authentication and returns a
348
+ * one-time API key (prefixed `prim_`) plus a provisioned managed inbox.
349
+ * The account is on the `agent` plan: reply-only (it can send only to
350
+ * addresses that have already sent it authenticated mail) with tight send
351
+ * limits. Use the returned `api_key` as a Bearer token on later calls. The
352
+ * account can be upgraded to a full developer account by confirming an
353
+ * email through the claim flow. Upgrading raises the send cap and grants
354
+ * the developer plan's default features (such as Functions); it does not
355
+ * unlock sending to arbitrary recipients, because the recipient rules on
356
+ * the account still apply. `GET /send-permissions` reports those rules
357
+ * (its list of individual addresses can be partial), and
358
+ * `POST /sendability` answers for one specific recipient. This endpoint
359
+ * does not require an API key.
360
+ *
361
+ */
362
+ const createAgentAccount = (options) => (options.client ?? client).post({
363
+ url: "/agent/accounts",
364
+ ...options,
365
+ headers: {
366
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
367
+ ...options.headers
368
+ }
369
+ });
370
+ /**
371
+ * Start an agent account email claim
372
+ *
373
+ * Begins upgrading an emailless `agent` account into a full `developer`
374
+ * account by confirming an email address. Authenticated by the agent's own
375
+ * API key (the org is taken from the credential). Sends a verification
376
+ * code to the supplied email and returns the claim session id plus resend
377
+ * timing. Submit the code to `/agent/claim/verify` to complete the
378
+ * upgrade. Confirming an email that already belongs to a Primitive account
379
+ * is rejected.
380
+ *
381
+ */
382
+ const startAgentClaim = (options) => (options.client ?? client).post({
383
+ security: [{
384
+ scheme: "bearer",
385
+ type: "http"
386
+ }],
387
+ url: "/agent/claim/start",
388
+ ...options,
389
+ headers: {
390
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
391
+ ...options.headers
392
+ }
393
+ });
394
+ /**
395
+ * Verify an agent account email claim
396
+ *
397
+ * Confirms the verification code emailed by `/agent/claim/start` and
398
+ * upgrades the account to the `developer` plan. The org id, API key, and
399
+ * managed inbox all carry over; the send cap lifts and the developer
400
+ * plan's default features (such as Functions) unlock. Upgrading does not
401
+ * unlock sending to arbitrary recipients: the recipient rules on the
402
+ * account still apply. `GET /send-permissions` reports those rules (its
403
+ * list of individual addresses can be partial), and `POST /sendability`
404
+ * answers for one specific recipient. Authenticated by the agent's own
405
+ * API key.
406
+ *
407
+ */
408
+ const verifyAgentClaim = (options) => (options.client ?? client).post({
409
+ security: [{
410
+ scheme: "bearer",
411
+ type: "http"
412
+ }],
413
+ url: "/agent/claim/verify",
414
+ ...options,
415
+ headers: {
416
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
417
+ ...options.headers
418
+ }
419
+ });
420
+ /**
421
+ * Create a browser claim link
422
+ *
423
+ * Mints an opaque, single-use link an agent can hand to a human to
424
+ * complete the email-confirmation upgrade in a browser. Authenticated by
425
+ * the agent's own API key. `claim_url` is null when the API host cannot
426
+ * resolve a web origin to build the link.
427
+ *
428
+ */
429
+ const createAgentClaimLink = (options) => (options?.client ?? client).post({
430
+ security: [{
431
+ scheme: "bearer",
432
+ type: "http"
433
+ }],
434
+ url: "/agent/claim/link",
435
+ ...options,
436
+ headers: {
437
+ "Content-Type": "application/json",
438
+ ...options?.headers
439
+ }
440
+ });
441
+ /**
442
+ * Revoke the current CLI OAuth session
443
+ *
444
+ * Revokes the OAuth grant used to authenticate the request. API-key
445
+ * authenticated legacy logout requests succeed without deleting server API
446
+ * keys so old local CLI state can be cleared safely.
447
+ *
448
+ */
449
+ const cliLogout = (options) => (options?.client ?? client).post({
450
+ security: [{
451
+ scheme: "bearer",
452
+ type: "http"
453
+ }],
454
+ url: "/cli/logout",
455
+ ...options,
456
+ headers: {
457
+ "Content-Type": "application/json",
458
+ ...options?.headers
459
+ }
460
+ });
461
+ /**
462
+ * Get account info
463
+ */
464
+ const getAccount = (options) => (options?.client ?? client).get({
465
+ security: [{
466
+ scheme: "bearer",
467
+ type: "http"
468
+ }],
469
+ url: "/account",
470
+ ...options
471
+ });
472
+ /**
473
+ * Update account settings
474
+ */
475
+ const updateAccount = (options) => (options.client ?? client).patch({
476
+ security: [{
477
+ scheme: "bearer",
478
+ type: "http"
479
+ }],
480
+ url: "/account",
481
+ ...options,
482
+ headers: {
483
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
484
+ ...options.headers
485
+ }
486
+ });
487
+ /**
488
+ * Get storage usage
489
+ */
490
+ const getStorageStats = (options) => (options?.client ?? client).get({
491
+ security: [{
492
+ scheme: "bearer",
493
+ type: "http"
494
+ }],
495
+ url: "/account/storage",
496
+ ...options
497
+ });
498
+ /**
499
+ * Get webhook signing secret
500
+ *
501
+ * Returns the webhook signing secret for your account. If no
502
+ * secret exists yet, one is generated automatically on first
503
+ * access.
504
+ *
505
+ * Signing is account-scoped, not per-endpoint. Every webhook
506
+ * delivery from any of your registered endpoints is signed
507
+ * with this single secret. Rotate via
508
+ * `POST /account/webhook-secret/rotate`.
509
+ *
510
+ * **Secret format**: the returned string looks base64-shaped
511
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
512
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
513
+ * delivery body. Base64-decoding before HMAC will silently
514
+ * produce mismatched signatures.
515
+ *
516
+ * See the API-level "Webhook signing" section for the full
517
+ * wire format (header name, signed string shape, hash algo,
518
+ * tolerance) including a language-agnostic verification
519
+ * recipe.
520
+ *
521
+ */
522
+ const getWebhookSecret = (options) => (options?.client ?? client).get({
523
+ security: [{
524
+ scheme: "bearer",
525
+ type: "http"
526
+ }],
527
+ url: "/account/webhook-secret",
528
+ ...options
529
+ });
530
+ /**
531
+ * Rotate webhook signing secret
532
+ *
533
+ * Generates a new webhook signing secret, replacing the current one.
534
+ * Rate limited to once per 60 minutes.
535
+ *
536
+ */
537
+ const rotateWebhookSecret = (options) => (options?.client ?? client).post({
538
+ security: [{
539
+ scheme: "bearer",
540
+ type: "http"
541
+ }],
542
+ url: "/account/webhook-secret/rotate",
543
+ ...options
544
+ });
545
+ /**
546
+ * Redeem a credit code
547
+ *
548
+ * Redeem a credit code for the authenticated organization. The credit is
549
+ * added to the organization prepaid credit and shows in
550
+ * `GET /credits/balance` under `prepaid_credit`.
551
+ *
552
+ * Redeeming requires an organization owner or admin. An API key redeems
553
+ * with the authority of the user who created it, based on that user's
554
+ * current role; a key without that authority gets the same
555
+ * `credit_code_invalid` refusal as an unknown code.
556
+ *
557
+ * The `Idempotency-Key` header is required. Retrying with the same key
558
+ * and code returns the original grant with `replayed: true` and grants
559
+ * nothing new; the same key with a different code is refused with
560
+ * `idempotency_key_reused`. Every refusal carries a human-readable
561
+ * `error.message` that can be shown to the user as is.
562
+ *
563
+ */
564
+ const redeemCreditCode = (options) => (options.client ?? client).post({
565
+ security: [{
566
+ scheme: "bearer",
567
+ type: "http"
568
+ }],
569
+ url: "/credits/redeem",
570
+ ...options,
571
+ headers: {
572
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
573
+ ...options.headers
574
+ }
575
+ });
576
+ /**
577
+ * Get credit balance
578
+ *
579
+ * Read the organization credit position. `prepaid_credit` is the prepaid
580
+ * usage credit (paid top-ups, redeemed credit codes and granted credit)
581
+ * that can still pay for usage. `budget` is the active agent spending
582
+ * budget an operator funded for top-ups, or null when there is none.
583
+ * Amounts are strings of integer micros (1 USD = 1000000 micros).
584
+ *
585
+ */
586
+ const getCreditBalance = (options) => (options?.client ?? client).get({
587
+ security: [{
588
+ scheme: "bearer",
589
+ type: "http"
590
+ }],
591
+ url: "/credits/balance",
592
+ ...options
593
+ });
594
+ /**
595
+ * List all domains
596
+ *
597
+ * Returns all verified and unverified domains for your organization,
598
+ * sorted by creation date (newest first). Each domain includes a
599
+ * `verified` boolean to distinguish between the two states.
600
+ *
601
+ */
602
+ const listDomains = (options) => (options?.client ?? client).get({
603
+ security: [{
604
+ scheme: "bearer",
605
+ type: "http"
606
+ }],
607
+ url: "/domains",
608
+ ...options
609
+ });
610
+ /**
611
+ * Claim a new domain
612
+ *
613
+ * Creates an unverified domain claim and returns the exact
614
+ * DNS records to publish in `dns_records`. Publish those
615
+ * records before calling the verify endpoint. To give users
616
+ * an importable DNS file, call `downloadDomainZoneFile` or run
617
+ * `primitive domains zone-file --id <domain-id>`.
618
+ *
619
+ */
620
+ const addDomain = (options) => (options.client ?? client).post({
621
+ security: [{
622
+ scheme: "bearer",
623
+ type: "http"
624
+ }],
625
+ url: "/domains",
626
+ ...options,
627
+ headers: {
628
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
629
+ ...options.headers
630
+ }
631
+ });
632
+ /**
633
+ * Delete a domain
634
+ *
635
+ * Deletes a verified or unverified domain claim.
636
+ */
637
+ const deleteDomain = (options) => (options.client ?? client).delete({
638
+ security: [{
639
+ scheme: "bearer",
640
+ type: "http"
641
+ }],
642
+ url: "/domains/{id}",
643
+ ...options
644
+ });
645
+ /**
646
+ * Update domain settings
647
+ *
648
+ * Update a verified domain's settings. Only verified domains can be
649
+ * updated. Per-domain spam thresholds require a Pro plan.
650
+ *
651
+ */
652
+ const updateDomain = (options) => (options.client ?? client).patch({
653
+ security: [{
654
+ scheme: "bearer",
655
+ type: "http"
656
+ }],
657
+ url: "/domains/{id}",
658
+ ...options,
659
+ headers: {
660
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
661
+ ...options.headers
662
+ }
663
+ });
664
+ /**
665
+ * Verify domain ownership
666
+ *
667
+ * Checks DNS records required for inbound routing, ownership,
668
+ * and outbound authentication: MX, ownership TXT, SPF, DKIM,
669
+ * DMARC, and TLS-RPT.
670
+ * On success, the domain is promoted from unverified to verified.
671
+ * On failure, returns which checks passed and which failed,
672
+ * plus the exact DNS records still expected. To give users
673
+ * an importable DNS file for missing records, call
674
+ * `downloadDomainZoneFile` or run
675
+ * `primitive domains zone-file --id <domain-id>`.
676
+ *
677
+ */
678
+ const verifyDomain = (options) => (options.client ?? client).post({
679
+ security: [{
680
+ scheme: "bearer",
681
+ type: "http"
682
+ }],
683
+ url: "/domains/{id}/verify",
684
+ ...options
685
+ });
686
+ /**
687
+ * Run an on-demand DNS health check
688
+ *
689
+ * Re-checks the domain's DNS records and persists the result as
690
+ * the domain's current DNS health state. This is the on-demand
691
+ * counterpart of the scheduled background checker: the response
692
+ * mirrors what the checker records, broken down per scope
693
+ * (`ownership`, `inbound`, `outbound`) with the exact records
694
+ * inspected and each record's individual status.
695
+ *
696
+ * Unlike /domains/{id}/verify, this call never promotes an
697
+ * unverified domain; it only re-evaluates and records health for
698
+ * an existing claim. Managed (Primitive-operated) domains are
699
+ * rejected with a validation error because their DNS is not
700
+ * customer-published.
701
+ *
702
+ * Rate limited per organization; a `Retry-After` header
703
+ * accompanies 429 responses.
704
+ *
705
+ */
706
+ const checkDomainDns = (options) => (options.client ?? client).post({
707
+ security: [{
708
+ scheme: "bearer",
709
+ type: "http"
710
+ }],
711
+ url: "/domains/{id}/dns/check",
712
+ ...options
713
+ });
714
+ /**
715
+ * Download domain DNS zone file
716
+ *
717
+ * Downloads a BIND-format DNS zone file containing the DNS records
718
+ * required for a domain claim. Agents should offer this after
719
+ * `addDomain` when users want to import DNS records instead of
720
+ * copying each record manually.
721
+ *
722
+ */
723
+ const downloadDomainZoneFile = (options) => (options.client ?? client).get({
724
+ security: [{
725
+ scheme: "bearer",
726
+ type: "http"
727
+ }],
728
+ url: "/domains/{id}/zone-file",
729
+ ...options
730
+ });
731
+ /**
732
+ * Get inbound inbox readiness
733
+ *
734
+ * Returns one consolidated view of inbound domain readiness,
735
+ * webhook/function processing routes, deployed Functions, and
736
+ * recent inbound email activity.
737
+ *
738
+ * Agents should call this before guiding a user through inbound
739
+ * setup. It answers the practical questions "can I receive mail",
740
+ * "will anything process that mail", and "what should I do next"
741
+ * without forcing clients to stitch together domains, endpoints,
742
+ * functions, and emails manually.
743
+ *
744
+ */
745
+ const getInboxStatus = (options) => (options?.client ?? client).get({
746
+ security: [{
747
+ scheme: "bearer",
748
+ type: "http"
749
+ }],
750
+ url: "/inbox/status",
751
+ ...options
752
+ });
753
+ /**
754
+ * List inbound emails
755
+ *
756
+ * Returns a paginated list of INBOUND emails received at your
757
+ * verified domains. Outbound messages sent via /send-mail are
758
+ * not included; this endpoint is the inbox view, not a
759
+ * unified send/receive history.
760
+ *
761
+ * Supports filtering by domain, status, date range, and
762
+ * free-text search across subject, sender, and recipient
763
+ * fields.
764
+ *
765
+ * For a compact text-table summary of the most recent N
766
+ * inbounds (no filters, no cursor pagination), the CLI ships
767
+ * `primitive emails:latest` as a one-line-per-email shortcut.
768
+ * It's TTY-aware so id columns are full UUIDs when piped, and
769
+ * a `--json` flag returns the same envelope this endpoint
770
+ * does. Use whichever fits the call site.
771
+ *
772
+ */
773
+ const listEmails = (options) => (options?.client ?? client).get({
774
+ security: [{
775
+ scheme: "bearer",
776
+ type: "http"
777
+ }],
778
+ url: "/emails",
779
+ ...options
780
+ });
781
+ /**
782
+ * Search inbound emails
783
+ *
784
+ * Searches inbound emails with structured filters and optional
785
+ * full-text matching across parsed email fields. This endpoint is
786
+ * optimized for filtered inbox views and CLI polling workflows:
787
+ * callers that only need new accepted mail can pass
788
+ * `sort=received_at_asc`, `snippet=false`, `include_facets=false`,
789
+ * and a `date_from` timestamp.
790
+ *
791
+ * `q`, `subject`, and `body` use the same English full-text index
792
+ * as the web inbox search. Structured filters such as `from`, `to`,
793
+ * `domain_id`, status, attachment presence, and spam score bounds
794
+ * are combined with the text query.
795
+ *
796
+ * The text parameters (`q`, `from`, `to`, `subject` and `body`) must not
797
+ * contain a NUL character; a value that does is rejected with a 400
798
+ * validation error.
799
+ *
800
+ * Connected-agent credentials search only mail received by their own
801
+ * address. This applies to results, totals, facets, and every page;
802
+ * search filters cannot widen the credential's scope. When
803
+ * `reply_to_sent_email_id` is supplied, its parent send must belong
804
+ * to the connected address in the same organization. An unavailable
805
+ * parent returns 404. Sender filters are not authentication proof;
806
+ * inspect the email detail's authentication evidence before trusting it.
807
+ *
808
+ */
809
+ const searchEmails = (options) => (options?.client ?? client).get({
810
+ security: [{
811
+ scheme: "bearer",
812
+ type: "http"
813
+ }],
814
+ url: "/emails/search",
815
+ ...options
816
+ });
817
+ /**
818
+ * Delete an email
819
+ */
820
+ const deleteEmail = (options) => (options.client ?? client).delete({
821
+ security: [{
822
+ scheme: "bearer",
823
+ type: "http"
824
+ }],
825
+ url: "/emails/{id}",
826
+ ...options
827
+ });
828
+ /**
829
+ * Get inbound email by id
830
+ *
831
+ * Returns the full record for an inbound email received at one
832
+ * of your verified domains, including the parsed text and HTML
833
+ * bodies, threading metadata, SMTP envelope detail, webhook
834
+ * delivery state, and a `replies` array for any outbound sends
835
+ * recorded as replies to this inbound.
836
+ *
837
+ * For listing inbound emails (with cursor pagination, status
838
+ * and date filters, and free-text search), use
839
+ * `/emails`. Outbound (sent) email records are NOT returned
840
+ * here; use `/sent-emails/{id}` for those.
841
+ *
842
+ * The response carries four sender-shaped fields whose
843
+ * meanings overlap. `from_email` is the canonical "who sent
844
+ * this" field for most use cases (parsed bare address from
845
+ * the `From:` header, with a `sender` fallback). `from_header`
846
+ * is the raw header including any display name. `sender` and
847
+ * `smtp_mail_from` both carry the SMTP envelope MAIL FROM
848
+ * (return-path) and are equal by construction; `sender` is
849
+ * the older field name retained for compatibility. See
850
+ * `primitive describe emails:get-email | jq '.responseSchema.properties'`
851
+ * for per-field detail.
852
+ *
853
+ */
854
+ const getEmail = (options) => (options.client ?? client).get({
855
+ security: [{
856
+ scheme: "bearer",
857
+ type: "http"
858
+ }],
859
+ url: "/emails/{id}",
860
+ ...options
861
+ });
862
+ /**
863
+ * Download raw email
864
+ *
865
+ * Downloads the raw RFC 822 email file (.eml). Authenticates via
866
+ * a signed download token (provided in webhook payloads) or a
867
+ * valid session.
868
+ *
869
+ */
870
+ const downloadRawEmail = (options) => (options.client ?? client).get({
871
+ security: [{
872
+ scheme: "bearer",
873
+ type: "http"
874
+ }, {
875
+ in: "query",
876
+ name: "token",
877
+ type: "apiKey"
878
+ }],
879
+ url: "/emails/{id}/raw",
880
+ ...options
881
+ });
882
+ /**
883
+ * Download email attachments
884
+ *
885
+ * Downloads all attachments as a gzip-compressed tar archive.
886
+ * Authenticates via a signed download token (provided in webhook
887
+ * payloads) or a valid session.
888
+ *
889
+ */
890
+ const downloadAttachments = (options) => (options.client ?? client).get({
891
+ security: [{
892
+ scheme: "bearer",
893
+ type: "http"
894
+ }, {
895
+ in: "query",
896
+ name: "token",
897
+ type: "apiKey"
898
+ }],
899
+ url: "/emails/{id}/attachments.tar.gz",
900
+ ...options
901
+ });
902
+ /**
903
+ * Download one inbound email attachment
904
+ *
905
+ * Pending service release. This contract does not establish live availability.
906
+ * Downloads the original bytes of one ordinary email attachment, selected by
907
+ * its metadata `part_index`, not its position in an attachments array. Refresh
908
+ * the email detail after `attachment_changed` before choosing an index again.
909
+ * Uses bearer authentication only; signed raw-email download tokens are not accepted.
910
+ * A paired-agent credential may read only a message addressed to its claimed address.
911
+ * Function credentials are denied. Other bearer credentials retain their
912
+ * existing email access boundaries. This endpoint serves email bytes only.
913
+ *
914
+ */
915
+ const downloadEmailAttachmentPart = (options) => (options.client ?? client).get({
916
+ security: [{
917
+ scheme: "bearer",
918
+ type: "http"
919
+ }],
920
+ url: "/emails/{id}/attachments/{part_index}",
921
+ ...options
922
+ });
923
+ /**
924
+ * Download one received email attachment by filename
925
+ *
926
+ * Returns the same bytes as downloadEmailAttachmentPart, selecting the attachment by its exact filename. The path form `/emails/{id}/attachments/{filename}` also works for any name that is not digits only, which that form reads as a part_index. When several attachments share the filename the response is 409 attachment_name_ambiguous with every matching part_index, and nothing is returned. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
927
+ */
928
+ const downloadEmailAttachmentByFilename = (options) => (options.client ?? client).get({
929
+ security: [{
930
+ scheme: "bearer",
931
+ type: "http"
932
+ }],
933
+ url: "/emails/{id}/attachments",
934
+ ...options
935
+ });
936
+ /**
937
+ * List the files inside a received zip or tar attachment
938
+ *
939
+ * Lists the regular files inside a zip, tar or tar.gz attachment with each one's path, decoded size and SHA-256. The format is detected from the content. Unsafe paths refuse the whole archive, and resource limits bound the work (see the 413 and 422 responses). Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
940
+ */
941
+ const listEmailAttachmentArchiveMembers = (options) => (options.client ?? client).get({
942
+ security: [{
943
+ scheme: "bearer",
944
+ type: "http"
945
+ }],
946
+ url: "/emails/{id}/attachments/{attachment}/members",
947
+ ...options
948
+ });
949
+ /**
950
+ * Download one file from inside a received zip or tar attachment
951
+ *
952
+ * Returns the decoded bytes of one regular file inside a zip, tar or tar.gz attachment, by its listed path. The archive's structure, every member path and every limit are checked as for the listing, but only the requested file is decoded and verified (its zip CRC-32, and X-Content-SHA256 of the bytes returned); list the archive to have every file decoded. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail received at its own address. Function credentials are not supported. Discarded content is unavailable.
953
+ */
954
+ const downloadEmailAttachmentArchiveMember = (options) => (options.client ?? client).get({
955
+ security: [{
956
+ scheme: "bearer",
957
+ type: "http"
958
+ }],
959
+ url: "/emails/{id}/attachments/{attachment}/members/{path}",
960
+ ...options
961
+ });
962
+ /**
963
+ * Download one sent email attachment
964
+ *
965
+ * Pending service release. This contract does not establish live availability.
966
+ * Downloads the original bytes of one ordinary email attachment, selected by
967
+ * its metadata `part_index`, not its position in an attachments array. Refresh
968
+ * the email detail after `attachment_changed` before choosing an index again.
969
+ * Uses bearer authentication only; signed raw-email download tokens are not accepted.
970
+ * A paired-agent credential may read only mail sent from its claimed address.
971
+ * Receiving a copy does not authorize downloading another sender's sent content.
972
+ * Function credentials are denied. Other bearer credentials retain their
973
+ * existing email access boundaries. This endpoint serves email bytes only.
974
+ *
975
+ */
976
+ const downloadSentAttachmentPart = (options) => (options.client ?? client).get({
977
+ security: [{
978
+ scheme: "bearer",
979
+ type: "http"
980
+ }],
981
+ url: "/sent-emails/{id}/attachments/{part_index}",
982
+ ...options
983
+ });
984
+ /**
985
+ * Download one sent email attachment by filename
986
+ *
987
+ * Returns the same bytes as downloadSentAttachmentPart, selecting the attachment by its exact filename. The path form `/sent-emails/{id}/attachments/{filename}` also works for any name that is not digits only, which that form reads as a part_index. When several attachments share the filename the response is 409 attachment_name_ambiguous with every matching part_index, and nothing is returned. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
988
+ */
989
+ const downloadSentAttachmentByFilename = (options) => (options.client ?? client).get({
990
+ security: [{
991
+ scheme: "bearer",
992
+ type: "http"
993
+ }],
994
+ url: "/sent-emails/{id}/attachments",
995
+ ...options
996
+ });
997
+ /**
998
+ * List the files inside a sent zip or tar attachment
999
+ *
1000
+ * Lists the regular files inside a zip, tar or tar.gz attachment with each one's path, decoded size and SHA-256. The format is detected from the content. Unsafe paths refuse the whole archive, and resource limits bound the work (see the 413 and 422 responses). Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
1001
+ */
1002
+ const listSentAttachmentArchiveMembers = (options) => (options.client ?? client).get({
1003
+ security: [{
1004
+ scheme: "bearer",
1005
+ type: "http"
1006
+ }],
1007
+ url: "/sent-emails/{id}/attachments/{attachment}/members",
1008
+ ...options
1009
+ });
1010
+ /**
1011
+ * Download one file from inside a sent zip or tar attachment
1012
+ *
1013
+ * Returns the decoded bytes of one regular file inside a zip, tar or tar.gz attachment, by its listed path. The archive's structure, every member path and every limit are checked as for the listing, but only the requested file is decoded and verified (its zip CRC-32, and X-Content-SHA256 of the bytes returned); list the archive to have every file decoded. Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.
1014
+ */
1015
+ const downloadSentAttachmentArchiveMember = (options) => (options.client ?? client).get({
1016
+ security: [{
1017
+ scheme: "bearer",
1018
+ type: "http"
1019
+ }],
1020
+ url: "/sent-emails/{id}/attachments/{attachment}/members/{path}",
1021
+ ...options
1022
+ });
1023
+ /**
1024
+ * Stop the repeat behind a received message
1025
+ *
1026
+ * Called by the recipient of a repeating send: the connected agent's own
1027
+ * credential for an agent address, or the signed-in member whose personal
1028
+ * address it is. `id` is the caller's received copy of any message of the
1029
+ * repeat, or the repeat id printed in the message footer, which resolves
1030
+ * to the caller's newest received copy. Stops the repeat when it lets the recipient stop it, cancels the
1031
+ * pending message, and replies once in the thread with a
1032
+ * `repeat.stop/1` interaction so the sender sees it. A repeat call returns
1033
+ * the same result without a second reply.
1034
+ *
1035
+ */
1036
+ const stopRepeatFromEmail = (options) => (options.client ?? client).post({
1037
+ security: [{
1038
+ scheme: "bearer",
1039
+ type: "http"
1040
+ }],
1041
+ url: "/emails/{id}/repeat-stop",
1042
+ ...options,
1043
+ headers: {
1044
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1045
+ ...options.headers
1046
+ }
1047
+ });
1048
+ /**
1049
+ * Reply to an inbound email
1050
+ *
1051
+ * Sends an outbound reply to the inbound email identified by `id`.
1052
+ * Threading headers (`In-Reply-To`, `References`), recipient
1053
+ * derivation (Reply-To, then From, then bare sender), and the
1054
+ * `Re:` subject prefix are all derived server-side from the
1055
+ * stored inbound row. The request body carries only the message
1056
+ * body, optional From override, optional attachments, optional
1057
+ * `wait` flag, and optional `reply_all` flag, which also copies
1058
+ * every other To and Cc address of the inbound (never Bcc).
1059
+ * Passing any header or explicit recipient override is rejected
1060
+ * by the schema (`additionalProperties: false`).
1061
+ *
1062
+ * Forwards through the same gates as `/send-mail`: the response
1063
+ * status, error envelope, and `idempotent_replay` flag mirror
1064
+ * the send-mail contract verbatim.
1065
+ *
1066
+ */
1067
+ const replyToEmail = (options) => (options.client ?? client).post({
1068
+ security: [{
1069
+ scheme: "bearer",
1070
+ type: "http"
1071
+ }],
1072
+ url: "/emails/{id}/reply",
1073
+ ...options,
1074
+ headers: {
1075
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1076
+ ...options.headers
1077
+ }
1078
+ });
1079
+ /**
1080
+ * Replay email webhooks
1081
+ *
1082
+ * Re-delivers the webhook payload for this email to all active
1083
+ * endpoints matching the email's domain. Rate limited per-email
1084
+ * (short cooldown between successive replays of the same email)
1085
+ * and per-org (burst + sustained windows), sharing an org-wide
1086
+ * budget with delivery replays.
1087
+ *
1088
+ */
1089
+ const replayEmailWebhooks = (options) => (options.client ?? client).post({
1090
+ security: [{
1091
+ scheme: "bearer",
1092
+ type: "http"
1093
+ }],
1094
+ url: "/emails/{id}/replay",
1095
+ ...options
1096
+ });
1097
+ /**
1098
+ * Discard email content
1099
+ *
1100
+ * Permanently deletes the email's raw bytes, parsed body (text + HTML),
1101
+ * and attachments while preserving metadata (sender, recipient,
1102
+ * subject, timestamps, hashes, attachment manifest) for audit logs.
1103
+ * Idempotent: a second call returns success with
1104
+ * `already_discarded: true` and does no work.
1105
+ *
1106
+ * **Gated** on the customer's discard-content opt-in (managed in the
1107
+ * dashboard at Settings > Webhooks). When the toggle is off, this
1108
+ * endpoint returns `403` with code `discard_not_enabled` and a
1109
+ * message pointing the human at the dashboard. There is intentionally
1110
+ * no API to flip this toggle. Opting in to a destructive,
1111
+ * non-reversible operation must be a deliberate human click in the
1112
+ * UI.
1113
+ *
1114
+ */
1115
+ const discardEmailContent = (options) => (options.client ?? client).post({
1116
+ security: [{
1117
+ scheme: "bearer",
1118
+ type: "http"
1119
+ }],
1120
+ url: "/emails/{id}/discard-content",
1121
+ ...options
1122
+ });
1123
+ /**
1124
+ * Get the conversation an email belongs to
1125
+ *
1126
+ * Returns the full conversation the given inbound email belongs
1127
+ * to, as ordered, ready-to-prompt turns WITH bodies. It resolves
1128
+ * the thread from the email and returns every message oldest-first,
1129
+ * so an agent that received an email can pass `messages` straight
1130
+ * to a chat model in one call instead of walking `/threads/{id}`
1131
+ * plus `/emails/{id}` and `/sent-emails/{id}` per message.
1132
+ *
1133
+ * Each message carries a `direction` (`inbound` | `outbound`) and a
1134
+ * derived `role`: `inbound` -> `user`, `outbound` -> `assistant`
1135
+ * (your own prior replies). The role mapping assumes the caller
1136
+ * owns the outbound side, which is the agent-reply case this exists
1137
+ * for. If the email has no thread yet (a brand-new message), the
1138
+ * conversation is just that one message as a single user turn.
1139
+ *
1140
+ * The message list is capped; check `truncated` to detect when
1141
+ * older messages were omitted. Consecutive same-role turns are not
1142
+ * merged here; that normalization is model-specific and left to the
1143
+ * caller.
1144
+ *
1145
+ * Pass `since` for an incremental read. `since=start` returns the
1146
+ * full conversation plus a `cursor`. Sending that `cursor` back as
1147
+ * `since` returns only the messages created or changed after it,
1148
+ * oldest first, with the same per-message shape, and a new
1149
+ * `cursor`. Without `since` the response carries no `cursor` and
1150
+ * no per-message `status`.
1151
+ *
1152
+ */
1153
+ const getConversation = (options) => (options.client ?? client).get({
1154
+ security: [{
1155
+ scheme: "bearer",
1156
+ type: "http"
1157
+ }],
1158
+ url: "/emails/{id}/conversation",
1159
+ ...options
1160
+ });
1161
+ /**
1162
+ * List webhook endpoints
1163
+ *
1164
+ * Returns all active (non-deleted) webhook endpoints.
1165
+ */
1166
+ const listEndpoints = (options) => (options?.client ?? client).get({
1167
+ security: [{
1168
+ scheme: "bearer",
1169
+ type: "http"
1170
+ }],
1171
+ url: "/endpoints",
1172
+ ...options
1173
+ });
1174
+ /**
1175
+ * Create a webhook endpoint
1176
+ *
1177
+ * Creates a new webhook endpoint. If a deactivated endpoint
1178
+ * with the same URL and domain exists, it is reactivated
1179
+ * instead. Subject to plan limits on the number of active
1180
+ * endpoints.
1181
+ *
1182
+ * **Signing is account-scoped, not per-endpoint.** This call
1183
+ * does not return any signing material; every endpoint on the
1184
+ * account uses the same webhook secret, fetched via
1185
+ * `GET /account/webhook-secret`. See the API-level "Webhook
1186
+ * signing" section for the full wire format (header name,
1187
+ * signed string, hash algo, secret format, tolerance) and a
1188
+ * language-agnostic verification recipe.
1189
+ *
1190
+ * After creating the endpoint, fire a test delivery against
1191
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
1192
+ * accepts the signature.
1193
+ *
1194
+ *
1195
+ * For local receiving, use kind=pull and a stable name, without url, function_id or domain_id. Named creation resumes the same active destination; omitted filters preserve its selection, while conflicting supplied configuration returns 409. New unfiltered destinations receive all subsequently ready eligible event types within their credential scope. Connected-agent credentials automatically create private subscriptions restricted to inbound email for their assigned address. Names are isolated per credential; revocation or replacement deletes its subscriptions. Address-scoped events contain parsed mail without raw MIME, signed download links, routing metadata, or sibling envelope recipients. Pull destinations do not occupy HTTP routing slots. Signing-secret setup and a test HTTP delivery are not required for pull receiving.
1196
+ */
1197
+ const createEndpoint = (options) => (options.client ?? client).post({
1198
+ security: [{
1199
+ scheme: "bearer",
1200
+ type: "http"
1201
+ }],
1202
+ url: "/endpoints",
1203
+ ...options,
1204
+ headers: {
1205
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1206
+ ...options.headers
1207
+ }
1208
+ });
1209
+ /**
1210
+ * Delete a webhook endpoint
1211
+ *
1212
+ * Soft-deletes a webhook endpoint. The endpoint will no longer
1213
+ * receive webhook deliveries.
1214
+ *
1215
+ */
1216
+ const deleteEndpoint = (options) => (options.client ?? client).delete({
1217
+ security: [{
1218
+ scheme: "bearer",
1219
+ type: "http"
1220
+ }],
1221
+ url: "/endpoints/{id}",
1222
+ ...options
1223
+ });
1224
+ /**
1225
+ * Update a webhook endpoint
1226
+ *
1227
+ * Updates an active webhook endpoint. If the URL is changed, the old
1228
+ * endpoint is deactivated and a new one is created (or an existing
1229
+ * deactivated endpoint with the new URL is reactivated).
1230
+ *
1231
+ *
1232
+ * Pull destinations cannot be assigned a URL, function or recipient-routing domain. Existing endpoint deletion disconnects the destination; creating a new destination does not backfill historical events.
1233
+ */
1234
+ const updateEndpoint = (options) => (options.client ?? client).patch({
1235
+ security: [{
1236
+ scheme: "bearer",
1237
+ type: "http"
1238
+ }],
1239
+ url: "/endpoints/{id}",
1240
+ ...options,
1241
+ headers: {
1242
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1243
+ ...options.headers
1244
+ }
1245
+ });
1246
+ /**
1247
+ * Receive a pending webhook event without a public endpoint
1248
+ *
1249
+ * Wait up to 30 seconds for one existing event. The body string preserves the exact webhook serialization; headers and canonical occurrence/type metadata travel alongside it. A fixed lease protects the attempt while a short handler accepts input. Retry may redeliver an occurrence: deduplicate event_id. Empty delivery means no offer now, not proof all input was delivered; inspect backlog and persistent gap_count/last_gap_reason. Queue retention is 24 hours and does not extend source-content retention. Disconnecting preserves pending work. Same named destination shares consumption; different destinations get independent copies.
1250
+ */
1251
+ const pullWebhookEvent = (options) => (options.client ?? client).post({
1252
+ security: [{
1253
+ scheme: "bearer",
1254
+ type: "http"
1255
+ }],
1256
+ url: "/endpoints/{id}/pull",
1257
+ ...options,
1258
+ headers: {
1259
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1260
+ ...options.headers
1261
+ }
1262
+ });
1263
+ /**
1264
+ * Report the outcome of a local webhook delivery attempt
1265
+ *
1266
+ * Report normalized handling evidence for the queue, attempt and lease. Required JSON fields: queue_id, delivery_id, lease_token, mode, duration_ms. For mode=exec include exit_code; stdout includes write_succeeded; http includes status_code and optional transport_error, error_code, confirmed. Supply this discriminated request with --raw-body in the generated CLI. The server classifies success and retry. Duplicate identical completion is idempotent; a stale lease cannot finish a newer attempt. Exec success means durable input acceptance, not completion of agent reasoning. Only successful HTTP handling with recognized confirmation evidence can confirm content discard. Never send arbitrary handler output or HTTP response bodies.
1267
+ */
1268
+ const completeWebhookEvent = (options) => (options.client ?? client).post({
1269
+ security: [{
1270
+ scheme: "bearer",
1271
+ type: "http"
1272
+ }],
1273
+ url: "/endpoints/{id}/complete",
1274
+ ...options,
1275
+ headers: {
1276
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1277
+ ...options.headers
1278
+ }
1279
+ });
1280
+ /**
1281
+ * Send a test webhook
1282
+ *
1283
+ * Sends a sample `email.received` event to the endpoint. The request
1284
+ * includes SSRF protection (private IP rejection and DNS pinning).
1285
+ * Rate limited to 4 per minute and 30 per hour (non-exempt).
1286
+ * Successful deliveries and verified-domain endpoints are exempt
1287
+ * from the rate limit.
1288
+ *
1289
+ */
1290
+ const testEndpoint = (options) => (options.client ?? client).post({
1291
+ security: [{
1292
+ scheme: "bearer",
1293
+ type: "http"
1294
+ }],
1295
+ url: "/endpoints/{id}/test",
1296
+ ...options
1297
+ });
1298
+ /**
1299
+ * Dry-run endpoint rules against a received email
1300
+ *
1301
+ * Evaluates the endpoint's filtering rules against an
1302
+ * already-received email WITHOUT delivering anything. The same
1303
+ * shared matcher the live delivery paths use produces the
1304
+ * verdict, so the response explains exactly why a webhook fired
1305
+ * or was suppressed for that message.
1306
+ *
1307
+ * When delivery would be suppressed, `rule` names the failing
1308
+ * rule and `reason` carries a human-readable explanation; both
1309
+ * are null when the message matches. `evaluated` echoes the
1310
+ * message metadata the matcher compared (size, attachments, and
1311
+ * the authenticated From identity versus the raw envelope
1312
+ * sender), so a surprising verdict can be traced to its inputs.
1313
+ *
1314
+ * Two independent gates are surfaced separately:
1315
+ * `subscribed_to_event` reports the endpoint's event-type
1316
+ * subscription (checked before message matching), and
1317
+ * `rules_valid` reports whether the stored rules blob parsed at
1318
+ * all. Delivery fails OPEN on an invalid blob (the message is
1319
+ * delivered as if unfiltered), so `rules_valid: false` exposes a
1320
+ * misconfiguration that is otherwise silent.
1321
+ *
1322
+ */
1323
+ const testEndpointRules = (options) => (options.client ?? client).post({
1324
+ security: [{
1325
+ scheme: "bearer",
1326
+ type: "http"
1327
+ }],
1328
+ url: "/endpoints/{id}/rules/test",
1329
+ ...options,
1330
+ headers: {
1331
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1332
+ ...options.headers
1333
+ }
1334
+ });
1335
+ /**
1336
+ * List filter rules
1337
+ *
1338
+ * Returns all whitelist and blocklist filter rules.
1339
+ */
1340
+ const listFilters = (options) => (options?.client ?? client).get({
1341
+ security: [{
1342
+ scheme: "bearer",
1343
+ type: "http"
1344
+ }],
1345
+ url: "/filters",
1346
+ ...options
1347
+ });
1348
+ /**
1349
+ * Create a filter rule
1350
+ *
1351
+ * Creates a new whitelist or blocklist filter. Per-domain filters
1352
+ * require a Pro plan. Patterns are stored as lowercase.
1353
+ *
1354
+ */
1355
+ const createFilter = (options) => (options.client ?? client).post({
1356
+ security: [{
1357
+ scheme: "bearer",
1358
+ type: "http"
1359
+ }],
1360
+ url: "/filters",
1361
+ ...options,
1362
+ headers: {
1363
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1364
+ ...options.headers
1365
+ }
1366
+ });
1367
+ /**
1368
+ * Delete a filter rule
1369
+ */
1370
+ const deleteFilter = (options) => (options.client ?? client).delete({
1371
+ security: [{
1372
+ scheme: "bearer",
1373
+ type: "http"
1374
+ }],
1375
+ url: "/filters/{id}",
1376
+ ...options
1377
+ });
1378
+ /**
1379
+ * Update a filter rule
1380
+ *
1381
+ * Toggle a filter's enabled state.
1382
+ */
1383
+ const updateFilter = (options) => (options.client ?? client).patch({
1384
+ security: [{
1385
+ scheme: "bearer",
1386
+ type: "http"
1387
+ }],
1388
+ url: "/filters/{id}",
1389
+ ...options,
1390
+ headers: {
1391
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1392
+ ...options.headers
1393
+ }
1394
+ });
1395
+ /**
1396
+ * List wake schedules
1397
+ *
1398
+ * Returns the org's wake.dispatch schedules.
1399
+ */
1400
+ const listWakeSchedules = (options) => (options?.client ?? client).get({
1401
+ security: [{
1402
+ scheme: "bearer",
1403
+ type: "http"
1404
+ }],
1405
+ url: "/wake/schedules",
1406
+ ...options
1407
+ });
1408
+ /**
1409
+ * Create a wake schedule
1410
+ *
1411
+ * Create a cron schedule that sends a wake.dispatch command to one of your
1412
+ * own function addresses. `from` and `to` must differ (no self-dispatch);
1413
+ * the cron expression and IANA timezone are validated and the first fire
1414
+ * time is computed without firing immediately.
1415
+ *
1416
+ */
1417
+ const createWakeSchedule = (options) => (options.client ?? client).post({
1418
+ security: [{
1419
+ scheme: "bearer",
1420
+ type: "http"
1421
+ }],
1422
+ url: "/wake/schedules",
1423
+ ...options,
1424
+ headers: {
1425
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1426
+ ...options.headers
1427
+ }
1428
+ });
1429
+ /**
1430
+ * Delete a wake schedule
1431
+ */
1432
+ const deleteWakeSchedule = (options) => (options.client ?? client).delete({
1433
+ security: [{
1434
+ scheme: "bearer",
1435
+ type: "http"
1436
+ }],
1437
+ url: "/wake/schedules/{id}",
1438
+ ...options
1439
+ });
1440
+ /**
1441
+ * Get a wake schedule
1442
+ */
1443
+ const getWakeSchedule = (options) => (options.client ?? client).get({
1444
+ security: [{
1445
+ scheme: "bearer",
1446
+ type: "http"
1447
+ }],
1448
+ url: "/wake/schedules/{id}",
1449
+ ...options
1450
+ });
1451
+ /**
1452
+ * Update a wake schedule
1453
+ *
1454
+ * Update a schedule's command, args, cadence, addresses, note, or enabled
1455
+ * state. Changing the cadence (or re-enabling) recomputes the next fire time.
1456
+ *
1457
+ */
1458
+ const updateWakeSchedule = (options) => (options.client ?? client).patch({
1459
+ security: [{
1460
+ scheme: "bearer",
1461
+ type: "http"
1462
+ }],
1463
+ url: "/wake/schedules/{id}",
1464
+ ...options,
1465
+ headers: {
1466
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1467
+ ...options.headers
1468
+ }
1469
+ });
1470
+ /**
1471
+ * Run a wake schedule now
1472
+ *
1473
+ * Fire the schedule immediately, sending one wake.dispatch via the same
1474
+ * signed-send path as a scheduled fire. Does not change the schedule's next
1475
+ * fire time.
1476
+ *
1477
+ */
1478
+ const runWakeSchedule = (options) => (options.client ?? client).post({
1479
+ security: [{
1480
+ scheme: "bearer",
1481
+ type: "http"
1482
+ }],
1483
+ url: "/wake/schedules/{id}/run",
1484
+ ...options
1485
+ });
1486
+ /**
1487
+ * List wake authorizations
1488
+ *
1489
+ * Returns the per-target allowlist grants that authorize which senders may
1490
+ * wake a function. Optionally filter by the target endpoint.
1491
+ *
1492
+ */
1493
+ const listWakeAuthorizations = (options) => (options?.client ?? client).get({
1494
+ security: [{
1495
+ scheme: "bearer",
1496
+ type: "http"
1497
+ }],
1498
+ url: "/wake/authorizations",
1499
+ ...options
1500
+ });
1501
+ /**
1502
+ * Create a wake authorization
1503
+ *
1504
+ * Grant a sender domain (and optionally a specific address and command set)
1505
+ * permission to wake a target function. The domain must be fully-qualified.
1506
+ *
1507
+ */
1508
+ const createWakeAuthorization = (options) => (options.client ?? client).post({
1509
+ security: [{
1510
+ scheme: "bearer",
1511
+ type: "http"
1512
+ }],
1513
+ url: "/wake/authorizations",
1514
+ ...options,
1515
+ headers: {
1516
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1517
+ ...options.headers
1518
+ }
1519
+ });
1520
+ /**
1521
+ * Delete a wake authorization
1522
+ */
1523
+ const deleteWakeAuthorization = (options) => (options.client ?? client).delete({
1524
+ security: [{
1525
+ scheme: "bearer",
1526
+ type: "http"
1527
+ }],
1528
+ url: "/wake/authorizations/{id}",
1529
+ ...options
1530
+ });
1531
+ /**
1532
+ * Update a wake authorization
1533
+ *
1534
+ * Toggle a wake authorization's enabled state.
1535
+ */
1536
+ const updateWakeAuthorization = (options) => (options.client ?? client).patch({
1537
+ security: [{
1538
+ scheme: "bearer",
1539
+ type: "http"
1540
+ }],
1541
+ url: "/wake/authorizations/{id}",
1542
+ ...options,
1543
+ headers: {
1544
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1545
+ ...options.headers
1546
+ }
1547
+ });
1548
+ /**
1549
+ * List recent wake dispatches
1550
+ *
1551
+ * Read-only audit of recent wake.dispatch interactions for the org.
1552
+ */
1553
+ const listWakeDispatches = (options) => (options?.client ?? client).get({
1554
+ security: [{
1555
+ scheme: "bearer",
1556
+ type: "http"
1557
+ }],
1558
+ url: "/wake/dispatches",
1559
+ ...options
1560
+ });
1561
+ /**
1562
+ * List recipient routes
1563
+ *
1564
+ * Returns the org's recipient routing rules in evaluation order. Each rule
1565
+ * binds a recipient address pattern to one endpoint; inbound mail resolves
1566
+ * to a single destination at delivery time.
1567
+ *
1568
+ */
1569
+ const listRoutes = (options) => (options?.client ?? client).get({
1570
+ security: [{
1571
+ scheme: "bearer",
1572
+ type: "http"
1573
+ }],
1574
+ url: "/routes",
1575
+ ...options
1576
+ });
1577
+ /**
1578
+ * Create a recipient route
1579
+ *
1580
+ * Binds a recipient pattern to a destination. Provide exactly one of
1581
+ * `endpoint_id` (an existing endpoint) or `function_id`. With `function_id`,
1582
+ * a dedicated route-target endpoint is minted for that function in the same
1583
+ * transaction, enabling per-address function routing (e.g.
1584
+ * `alice@acme.com -> functionA`).
1585
+ *
1586
+ */
1587
+ const createRoute = (options) => (options.client ?? client).post({
1588
+ security: [{
1589
+ scheme: "bearer",
1590
+ type: "http"
1591
+ }],
1592
+ url: "/routes",
1593
+ ...options,
1594
+ headers: {
1595
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1596
+ ...options.headers
1597
+ }
1598
+ });
1599
+ /**
1600
+ * Reorder recipient routes
1601
+ *
1602
+ * Update the priority of one or more routes in a single call.
1603
+ */
1604
+ const reorderRoutes = (options) => (options.client ?? client).post({
1605
+ security: [{
1606
+ scheme: "bearer",
1607
+ type: "http"
1608
+ }],
1609
+ url: "/routes/reorder",
1610
+ ...options,
1611
+ headers: {
1612
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1613
+ ...options.headers
1614
+ }
1615
+ });
1616
+ /**
1617
+ * Simulate routing for a recipient
1618
+ *
1619
+ * Resolves where an inbound email to `recipient` would be delivered, with a
1620
+ * trace of every rule evaluated and why. Read-only; creates nothing.
1621
+ *
1622
+ */
1623
+ const simulateRoute = (options) => (options.client ?? client).post({
1624
+ security: [{
1625
+ scheme: "bearer",
1626
+ type: "http"
1627
+ }],
1628
+ url: "/routes/simulate",
1629
+ ...options,
1630
+ headers: {
1631
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1632
+ ...options.headers
1633
+ }
1634
+ });
1635
+ /**
1636
+ * Delete a recipient route
1637
+ */
1638
+ const deleteRoute = (options) => (options.client ?? client).delete({
1639
+ security: [{
1640
+ scheme: "bearer",
1641
+ type: "http"
1642
+ }],
1643
+ url: "/routes/{id}",
1644
+ ...options
1645
+ });
1646
+ /**
1647
+ * Update a recipient route
1648
+ */
1649
+ const updateRoute = (options) => (options.client ?? client).patch({
1650
+ security: [{
1651
+ scheme: "bearer",
1652
+ type: "http"
1653
+ }],
1654
+ url: "/routes/{id}",
1655
+ ...options,
1656
+ headers: {
1657
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1658
+ ...options.headers
1659
+ }
1660
+ });
1661
+ /**
1662
+ * List webhook deliveries
1663
+ *
1664
+ * Returns a paginated list of webhook delivery attempts, newest first.
1665
+ * A delivery of an inbound email includes a nested `email` object with
1666
+ * sender, recipient, and subject. A delivery of an opt-in
1667
+ * `sent_email.*` event has `email_id` and `email` set to null and
1668
+ * `sent_email_id` set to the send it is about. Filter by `event_type`
1669
+ * and `sent_email_id` to find the deliveries of one send.
1670
+ *
1671
+ */
1672
+ const listDeliveries = (options) => (options?.client ?? client).get({
1673
+ security: [{
1674
+ scheme: "bearer",
1675
+ type: "http"
1676
+ }],
1677
+ url: "/webhooks/deliveries",
1678
+ ...options
1679
+ });
1680
+ /**
1681
+ * Replay a webhook delivery
1682
+ *
1683
+ * Re-sends a previous delivery to its original endpoint. If that
1684
+ * endpoint was deleted or deactivated, the replay is rejected.
1685
+ * Supports inbound email deliveries and `sent_email.*` deliveries.
1686
+ * An inbound email delivery is replayed with its original stored
1687
+ * payload and event id. A `sent_email.*` delivery is replayed with the
1688
+ * same event id but a payload rebuilt from the send as it is now; it
1689
+ * is rejected if the send was deleted or the endpoint is no longer an
1690
+ * active http endpoint. Rate limited per-org, sharing an org-wide
1691
+ * budget with email replays.
1692
+ *
1693
+ */
1694
+ const replayDelivery = (options) => (options.client ?? client).post({
1695
+ security: [{
1696
+ scheme: "bearer",
1697
+ type: "http"
1698
+ }],
1699
+ url: "/webhooks/deliveries/{id}/replay",
1700
+ ...options
1701
+ });
1702
+ /**
1703
+ * List send-permission rules
1704
+ *
1705
+ * Returns a flat list of rules describing every recipient the
1706
+ * caller may send to. Each rule has a `type`, a kind-specific
1707
+ * payload, and a human-readable `description`. If any rule
1708
+ * matches the recipient, /send-mail will accept the send under
1709
+ * the recipient-scope check.
1710
+ *
1711
+ * The endpoint is the answer to "where can I send" without
1712
+ * exposing internal entitlement names. Agents that don't
1713
+ * recognize a `type` can still read the `description` prose
1714
+ * and act on it.
1715
+ *
1716
+ * Rule kinds, ordered broadest-first so an agent can stop
1717
+ * scanning at the first match:
1718
+ *
1719
+ * 1. `any_recipient` (one entry, only when the org can send
1720
+ * anywhere): every other rule below it is redundant.
1721
+ * 2. `managed_zone` (always emitted, one per Primitive-managed
1722
+ * zone): sends to any address at *.primitive.email or
1723
+ * *.email.works always succeed; no entitlement required.
1724
+ * 3. `your_domain` (one per active verified outbound domain
1725
+ * owned by the org): sends to that domain are approved.
1726
+ * 4. `address` (one per address that has authenticated
1727
+ * inbound mail to the org, capped at `meta.address_cap`):
1728
+ * sends to that exact address are approved.
1729
+ *
1730
+ * The list is informational, not an authorization check.
1731
+ * /send-mail remains the source of truth on whether an
1732
+ * individual send will succeed (it also enforces the
1733
+ * from-address and the `send_mail` entitlement, which are
1734
+ * not recipient-scope concerns and are not represented here).
1735
+ *
1736
+ */
1737
+ const getSendPermissions = (options) => (options?.client ?? client).get({
1738
+ security: [{
1739
+ scheme: "bearer",
1740
+ type: "http"
1741
+ }],
1742
+ url: "/send-permissions",
1743
+ ...options
1744
+ });
1745
+ /**
1746
+ * Send outbound email
1747
+ *
1748
+ * Sends an outbound email through Primitive's outbound relay. By default
1749
+ * the request returns once the relay accepts the message for delivery.
1750
+ * Set `wait: true` to wait for the first downstream SMTP delivery outcome.
1751
+ *
1752
+ * **Host routing.** /send-mail is served by the canonical API host
1753
+ * (`https://api.primitive.dev/v1`) so the request body can carry
1754
+ * inline attachments up to ~30 MiB raw. The legacy dashboard
1755
+ * compatibility host (`https://www.primitive.dev/api/v1`) also accepts
1756
+ * /send-mail, but Vercel request body limits apply before proxying.
1757
+ * The typed SDKs route /send-mail to the canonical API host
1758
+ * automatically.
1759
+ *
1760
+ */
1761
+ const sendEmail = (options) => (options.client ?? client).post({
1762
+ security: [{
1763
+ scheme: "bearer",
1764
+ type: "http"
1765
+ }],
1766
+ url: "/send-mail",
1767
+ ...options,
1768
+ headers: {
1769
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1770
+ ...options.headers
1771
+ }
1772
+ });
1773
+ /**
1774
+ * Semantic search across received and sent mail
1775
+ *
1776
+ * Ranked search across both received and sent mail. The `mode`
1777
+ * field selects the ranking strategy:
1778
+ *
1779
+ * - `keyword`: lexical full-text matching only (no embeddings).
1780
+ * - `semantic`: meaning-based matching using vector embeddings.
1781
+ * - `hybrid` (default): blends the semantic and keyword signals.
1782
+ *
1783
+ * Results are ordered by a relevance `score`. Every row reports the
1784
+ * fields it matched (`matched_fields`), a match-centered excerpt per
1785
+ * field (`snippets`), and a `score_breakdown` whose components account
1786
+ * for the `score`. Page through results by passing the prior
1787
+ * response's `meta.cursor` back as `cursor`.
1788
+ *
1789
+ * Requires the Pro plan and the `semantic_search_enabled`
1790
+ * entitlement; callers without them receive `403`.
1791
+ *
1792
+ */
1793
+ const semanticSearch = (options) => (options.client ?? client).post({
1794
+ security: [{
1795
+ scheme: "bearer",
1796
+ type: "http"
1797
+ }],
1798
+ url: "/semantic-search",
1799
+ ...options,
1800
+ headers: {
1801
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1802
+ ...options.headers
1803
+ }
1804
+ });
1805
+ /**
1806
+ * Get outbound sending readiness
1807
+ *
1808
+ * The "what can I send From?" bootstrap, the outbound mirror of
1809
+ * /inbox/status. Returns per-domain sending readiness for every
1810
+ * domain in the caller's org, plus the flat `sendable_domains`
1811
+ * list of From-domains the org may send from right now. That
1812
+ * list is the same set echoed in a `cannot_send_from_domain`
1813
+ * error's details, so orienting here before a send and
1814
+ * recovering from that error use identical data.
1815
+ *
1816
+ * Each domain's `status` collapses the sending prerequisites
1817
+ * into one actionable state: `sendable`, `pending_ownership`
1818
+ * (ownership TXT not verified), `pending_outbound_dns`
1819
+ * (SPF/DKIM/DMARC not verified), or `inactive` (domain
1820
+ * deactivated). `next_actions` lists concrete remediation steps,
1821
+ * each with a suggested CLI command where one exists.
1822
+ *
1823
+ */
1824
+ const getOutboundStatus = (options) => (options?.client ?? client).get({
1825
+ security: [{
1826
+ scheme: "bearer",
1827
+ type: "http"
1828
+ }],
1829
+ url: "/outbound/status",
1830
+ ...options
1831
+ });
1832
+ /**
1833
+ * List repeating sends
1834
+ *
1835
+ * Repeating sends you created, newest first. A repeat is visible to the
1836
+ * member who created it, or to any organization API key or member for
1837
+ * repeats created with an organization API key. Agent credentials get
1838
+ * 403.
1839
+ *
1840
+ */
1841
+ const listRepeatingSends = (options) => (options?.client ?? client).get({
1842
+ security: [{
1843
+ scheme: "bearer",
1844
+ type: "http"
1845
+ }],
1846
+ url: "/repeating-sends",
1847
+ ...options
1848
+ });
1849
+ /**
1850
+ * Delete a repeating send
1851
+ *
1852
+ * Deletes the repeat and cancels its pending message. Messages already sent are not affected.
1853
+ */
1854
+ const deleteRepeatingSend = (options) => (options.client ?? client).delete({
1855
+ security: [{
1856
+ scheme: "bearer",
1857
+ type: "http"
1858
+ }],
1859
+ url: "/repeating-sends/{id}",
1860
+ ...options
1861
+ });
1862
+ /**
1863
+ * Get a repeating send
1864
+ */
1865
+ const getRepeatingSend = (options) => (options.client ?? client).get({
1866
+ security: [{
1867
+ scheme: "bearer",
1868
+ type: "http"
1869
+ }],
1870
+ url: "/repeating-sends/{id}",
1871
+ ...options
1872
+ });
1873
+ /**
1874
+ * Update a repeating send
1875
+ *
1876
+ * Pause, resume or cancel a repeat, or change its cadence, limits,
1877
+ * message or whether the recipient may stop it. `active` resumes a paused
1878
+ * repeat or one the recipient stopped; the next message goes out within
1879
+ * about a minute. A null `only_if_recipient_idle_minutes`, `max_sends`
1880
+ * or `until` clears that limit.
1881
+ *
1882
+ */
1883
+ const updateRepeatingSend = (options) => (options.client ?? client).patch({
1884
+ security: [{
1885
+ scheme: "bearer",
1886
+ type: "http"
1887
+ }],
1888
+ url: "/repeating-sends/{id}",
1889
+ ...options,
1890
+ headers: {
1891
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
1892
+ ...options.headers
1893
+ }
1894
+ });
1895
+ /**
1896
+ * List outbound sent emails
1897
+ *
1898
+ * Returns a paginated list of OUTBOUND emails the caller's
1899
+ * org has sent via /send-mail (and /emails/{id}/reply, which
1900
+ * forwards through /send-mail). Includes every recorded
1901
+ * attempt, including gate-denied attempts that the agent
1902
+ * never called and rows still in `queued` state.
1903
+ *
1904
+ * Under an address-bound agent connection credential, the
1905
+ * list holds this agent's own sends plus delivered sends from
1906
+ * other addresses in the org that name this agent in to, cc
1907
+ * or bcc and have matching inbound delivery evidence at this
1908
+ * agent. Pass `from` with the agent's own address to list
1909
+ * only its own sends.
1910
+ *
1911
+ * For inbound mail received at your verified domains, see
1912
+ * /emails. There is no unified send/receive history endpoint;
1913
+ * the two surfaces are intentionally separate because the
1914
+ * underlying tables, statuses, and lifecycle differ.
1915
+ *
1916
+ * Email bodies (`body_text`, `body_html`) are NOT included on
1917
+ * list rows so a 50-row page can't balloon into a multi-MB
1918
+ * response when sends are near the 5MB body cap. Use
1919
+ * /sent-emails/{id} to fetch a single row with bodies, or
1920
+ * cross-reference by `client_idempotency_key` if the caller
1921
+ * already has the body locally.
1922
+ *
1923
+ */
1924
+ const listSentEmails = (options) => (options?.client ?? client).get({
1925
+ security: [{
1926
+ scheme: "bearer",
1927
+ type: "http"
1928
+ }],
1929
+ url: "/sent-emails",
1930
+ ...options
1931
+ });
1932
+ /**
1933
+ * Delete a sent email
1934
+ *
1935
+ * Permanently deletes sender mailbox history and its owned attachment archive
1936
+ * and transient payload. Allows delivered, bounced, agent_failed, gate_denied,
1937
+ * canceled, deferred and wait_timeout; other states return 409. Cancel scheduled
1938
+ * sends first. This does not recall or cancel delivery already admitted.
1939
+ * Recipient copies, received replies and independent audit records are preserved.
1940
+ * Occupied idempotency keys and delivered-reply deduplication remain reserved.
1941
+ * Keys already released by cancellation, gate denial or a never-attempted failure
1942
+ * remain reusable. Repeating a completed deletion succeeds; unknown or foreign
1943
+ * IDs return 404. Organization API keys, sessions and OAuth are supported;
1944
+ * Function and connected-agent credentials are denied.
1945
+ *
1946
+ */
1947
+ const deleteSentEmail = (options) => (options.client ?? client).delete({
1948
+ security: [{
1949
+ scheme: "bearer",
1950
+ type: "http"
1951
+ }],
1952
+ url: "/sent-emails/{id}",
1953
+ ...options
1954
+ });
1955
+ /**
1956
+ * Get a sent email by id
1957
+ *
1958
+ * Returns the full sent-email record by id, including
1959
+ * `body_text` and `body_html` (omitted from the listing
1960
+ * endpoint to keep paginated responses small). Use this when
1961
+ * diagnosing a specific send, e.g. inspecting the receiver's
1962
+ * SMTP response on a `bounced` row or pulling the gate
1963
+ * denial detail on a `gate_denied` row.
1964
+ *
1965
+ * Under an address-bound agent connection credential, only
1966
+ * ids in the same scope as /sent-emails resolve: this agent's
1967
+ * own sends, and delivered sends addressed to it with
1968
+ * matching inbound delivery evidence. Other ids return 404.
1969
+ *
1970
+ */
1971
+ const getSentEmail = (options) => (options.client ?? client).get({
1972
+ security: [{
1973
+ scheme: "bearer",
1974
+ type: "http"
1975
+ }],
1976
+ url: "/sent-emails/{id}",
1977
+ ...options
1978
+ });
1979
+ /**
1980
+ * Reschedule a scheduled send
1981
+ *
1982
+ * Moves a STILL-SCHEDULED send (status `scheduled`) to a new
1983
+ * execution time. The new `scheduled_at` must be in the future
1984
+ * and at most 30 days out, the same bounds as the create-time
1985
+ * field on /send-mail.
1986
+ *
1987
+ * The update is a compare-and-swap on `status = 'scheduled'`:
1988
+ * once the scheduler has claimed the row for execution, or it
1989
+ * was already canceled or executed, the update loses and the
1990
+ * call returns a 409 `not_scheduled` conflict naming the row's
1991
+ * current status. A due send can therefore never be moved out
1992
+ * from under an in-progress execution.
1993
+ *
1994
+ * Returns the full updated sent-email record on success.
1995
+ *
1996
+ */
1997
+ const rescheduleSentEmail = (options) => (options.client ?? client).patch({
1998
+ security: [{
1999
+ scheme: "bearer",
2000
+ type: "http"
2001
+ }],
2002
+ url: "/sent-emails/{id}",
2003
+ ...options,
2004
+ headers: {
2005
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2006
+ ...options.headers
2007
+ }
2008
+ });
2009
+ /**
2010
+ * list Agent Connections
2011
+ *
2012
+ * Address-bound external runtime pairing. Any current human organization member may create and manage their personal agent connections. Organization owners and admins may manage all connections and explicitly create shared ones. An owner removed from the organization loses personal agent access, and rejoining does not revive the old connection. Organization API keys cannot manage connections. A current connected credential may disconnect only its own exact address. Claim is authorized only by its one-use invitation. Connected means a real challenge was received and a reply sent by the current bound credential was received back. Invitations expire after 15 minutes. Reconnection preserves the address and revokes previous credentials. Status responses contain no credentials. Runtime credentials allow address-scoped mail operations, organization note reads, own-address note writes, exact-address self-disconnect, network discovery when can_view is enabled, and recipient-bound network contact admission.
2013
+ */
2014
+ const listAgentConnections = (options) => (options?.client ?? client).get({
2015
+ security: [{
2016
+ scheme: "bearer",
2017
+ type: "http"
2018
+ }],
2019
+ url: "/agent-connections",
2020
+ ...options
2021
+ });
2022
+ /**
2023
+ * create Agent Connection
2024
+ *
2025
+ * Address-bound external runtime pairing. Any current human organization member may create and manage their personal agent connections. Organization owners and admins may manage all connections and explicitly create shared ones. An owner removed from the organization loses personal agent access, and rejoining does not revive the old connection. Organization API keys cannot manage connections. A current connected credential may disconnect only its own exact address. Claim is authorized only by its one-use invitation. Connected means a real challenge was received and a reply sent by the current bound credential was received back. Invitations expire after 15 minutes. Reconnection preserves the address and revokes previous credentials. Status responses contain no credentials. Runtime credentials allow address-scoped mail operations, organization note reads, own-address note writes, exact-address self-disconnect, network discovery when can_view is enabled, and recipient-bound network contact admission. Save create_request_id before dispatch to recover an interrupted creation. Recovery returns the original current connection with recovered:true and invitation:null; it never replays a secret or rotates credentials.
2026
+ */
2027
+ const createAgentConnection = (options) => (options.client ?? client).post({
2028
+ security: [{
2029
+ scheme: "bearer",
2030
+ type: "http"
2031
+ }],
2032
+ url: "/agent-connections",
2033
+ ...options,
2034
+ headers: {
2035
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2036
+ ...options.headers
2037
+ }
2038
+ });
2039
+ /**
2040
+ * invite Agent Connection
2041
+ *
2042
+ * Address-bound external runtime pairing. Any current human organization member may create and manage their personal agent connections. Organization owners and admins may manage all connections and explicitly create shared ones. An owner removed from the organization loses personal agent access, and rejoining does not revive the old connection. Organization API keys cannot manage connections. A current connected credential may disconnect only its own exact address. Claim is authorized only by its one-use invitation. Connected means a real challenge was received and a reply sent by the current bound credential was received back. Invitations expire after 15 minutes. Reconnection preserves the address and revokes previous credentials. Status responses contain no credentials. Runtime credentials allow address-scoped mail operations, organization note reads, own-address note writes, exact-address self-disconnect, network discovery when can_view is enabled, and recipient-bound network contact admission. pending_only protects an already claimed credential. An ambiguous invitation response must not be retried automatically; invitation secrets are never replayed.
2043
+ */
2044
+ const inviteAgentConnection = (options) => (options.client ?? client).post({
2045
+ security: [{
2046
+ scheme: "bearer",
2047
+ type: "http"
2048
+ }],
2049
+ url: "/agent-connections/{address}/invitation",
2050
+ ...options,
2051
+ headers: {
2052
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2053
+ ...options.headers
2054
+ }
2055
+ });
2056
+ /**
2057
+ * revoke Agent Connection
2058
+ *
2059
+ * Disconnect an agent and invalidate its bound credential. A current personal owner may disconnect their own agent; organization owners and admins may disconnect any connection. A connected agent may disconnect only its own exact address using its current bound credential. This preserves the connection record, mail, notes and domain. A current personal owner may permanently remove their own revoked record.
2060
+ */
2061
+ const revokeAgentConnection = (options) => (options.client ?? client).delete({
2062
+ security: [{
2063
+ scheme: "bearer",
2064
+ type: "http"
2065
+ }],
2066
+ url: "/agent-connections/{address}",
2067
+ ...options
2068
+ });
2069
+ /**
2070
+ * remove Agent Connection
2071
+ *
2072
+ * Permanently remove a revoked connection record. A current personal owner may permanently remove their own record; organization owners and admins may remove any record. Disconnect first using revokeAgentConnection; an active connection returns 409 connection_not_revoked. Missing or already removed records return 404. Mail, address notes, domains and external runtimes are preserved. The same address can be paired again with a new invitation; old credentials and invitations remain invalid.
2073
+ */
2074
+ const removeAgentConnection = (options) => (options.client ?? client).post({
2075
+ security: [{
2076
+ scheme: "bearer",
2077
+ type: "http"
2078
+ }],
2079
+ url: "/agent-connections/{address}/remove",
2080
+ ...options
2081
+ });
2082
+ /**
2083
+ * claim Agent Connection
2084
+ *
2085
+ * Address-bound external runtime pairing. Any current human organization member may create and manage their personal agent connections. Organization owners and admins may manage all connections and explicitly create shared ones. An owner removed from the organization loses personal agent access, and rejoining does not revive the old connection. Organization API keys cannot manage connections. A current connected credential may disconnect only its own exact address. Claim is authorized only by its one-use invitation. Connected means a real challenge was received and a reply sent by the current bound credential was received back. Invitations expire after 15 minutes. Reconnection preserves the address and revokes previous credentials. Status responses contain no credentials. Runtime credentials allow address-scoped mail operations, organization note reads, own-address note writes, exact-address self-disconnect, network discovery when can_view is enabled, and recipient-bound network contact admission.
2086
+ */
2087
+ const claimAgentConnection = (options) => (options.client ?? client).post({
2088
+ url: "/agent-connections/claim",
2089
+ ...options,
2090
+ headers: {
2091
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2092
+ ...options.headers
2093
+ }
2094
+ });
2095
+ /**
2096
+ * agent Connection Setup
2097
+ *
2098
+ * Instructions for pairing an external runtime. GET never consumes an invitation. The invitation token stays in the URL fragment and is submitted only in the claim POST body.
2099
+ */
2100
+ const agentConnectionSetup = (options) => (options?.client ?? client).get({
2101
+ url: "/agent-connections/setup",
2102
+ ...options
2103
+ });
2104
+ /**
2105
+ * Long-poll what changed
2106
+ *
2107
+ * One feed of small invalidations (ids and kinds) for everything an app keeps a snapshot of: inbound mail, sent mail, the member's conversation read state, the agent directory and presence, and the credential's own access. Non-consumptive and replayable: any number of devices can read the same cursor independently.
2108
+ *
2109
+ * Start with `since=start` (or no `since`): it returns an empty page whose `next_cursor` is a baseline. Take it BEFORE the initial list reads; every change that commits after it is delivered, including ones those reads already reflect. Then call with `since=<next_cursor>&wait=20` in a loop. Changes come oldest first in commit order, at least once: a write that commits late is never skipped, because positions are assigned at commit.
2110
+ *
2111
+ * Every change is scoped to what this credential's full reads would show: a connected agent sees only its own mail, its own sends and sends it provably received; mail held for sender authentication is announced only when released; read state reaches only the member it belongs to; agent changes reach members and agents allowed to view the network; organization API keys receive no agent changes. Function credentials cannot call this.
2112
+ *
2113
+ * Changes are kept 7 days. A cursor answers 410 `cursor_expired` only when changes after it were pruned (an idle cursor stays valid); rebuild the snapshots from `since=start`.
2114
+ */
2115
+ const listChanges = (options) => (options?.client ?? client).get({
2116
+ security: [{
2117
+ scheme: "bearer",
2118
+ type: "http"
2119
+ }],
2120
+ url: "/changes",
2121
+ ...options
2122
+ });
2123
+ /**
2124
+ * Cancel a scheduled send by idempotency key
2125
+ *
2126
+ * Cancels the still-scheduled send created with this `Idempotency-Key` (matched exactly), as `POST /sent-emails/{id}/cancel` does, and releases the key. 404 `not_found`: no send this credential can act on was created with the key. 409 `not_scheduled`: the send holding the key is no longer scheduled; `error.details` names its `sent_email_id` and `status` (`canceled` if already canceled). Pass `created_before` on a retry so it cannot reach a newer send that reused the released key. A connected agent can cancel any scheduled send from its own address, whoever created it, and no other.
2127
+ */
2128
+ const cancelSentEmailByIdempotencyKey = (options) => (options.client ?? client).post({
2129
+ security: [{
2130
+ scheme: "bearer",
2131
+ type: "http"
2132
+ }],
2133
+ url: "/sent-emails/cancel",
2134
+ ...options,
2135
+ headers: {
2136
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2137
+ ...options.headers
2138
+ }
2139
+ });
2140
+ /**
2141
+ * Cancel a scheduled send
2142
+ *
2143
+ * Cancels a STILL-SCHEDULED send (status `scheduled`), moving it
2144
+ * to the terminal `canceled` status. Nothing is dispatched and
2145
+ * the row is kept for historical lookup with `canceled_at` set.
2146
+ *
2147
+ * Uses the same compare-and-swap guard as reschedule: once the
2148
+ * scheduler has claimed the row for execution, or it was already
2149
+ * canceled or executed, the call returns a 409 `not_scheduled`
2150
+ * conflict naming the row's current status. Canceling can
2151
+ * therefore never race an in-progress execution; a send that
2152
+ * reports `canceled` was never handed to the delivery path.
2153
+ *
2154
+ * Returns the full updated sent-email record on success.
2155
+ *
2156
+ */
2157
+ const cancelSentEmail = (options) => (options.client ?? client).post({
2158
+ security: [{
2159
+ scheme: "bearer",
2160
+ type: "http"
2161
+ }],
2162
+ url: "/sent-emails/{id}/cancel",
2163
+ ...options
2164
+ });
2165
+ /**
2166
+ * Get (or wait for) the reply to a sent email
2167
+ *
2168
+ * Returns the first threaded inbound reply to a send, keyed by
2169
+ * the inbound email's `reply_to_sent_email_id`. This is the
2170
+ * canonical "did a reply arrive for this send?" call: after
2171
+ * /send-mail, poll (or long-poll) here instead of hand-rolling
2172
+ * an /emails/search loop.
2173
+ *
2174
+ * By default the call returns immediately with `reply: null`
2175
+ * when nothing has arrived yet. Set `wait=true` to long-poll:
2176
+ * the server holds the request up to `wait_timeout_ms`
2177
+ * (default 10000, max 30000), returning as soon as the first
2178
+ * reply lands. On a wait that elapses with no reply, the
2179
+ * response has `reply: null` and `timed_out: true`.
2180
+ *
2181
+ * The reply object is compact (headers plus bodies); fetch
2182
+ * `/emails/{id}` with `reply.id` for the fully parsed record,
2183
+ * or `/threads/{thread_id}` for the whole back-and-forth.
2184
+ *
2185
+ */
2186
+ const awaitReply = (options) => (options.client ?? client).get({
2187
+ security: [{
2188
+ scheme: "bearer",
2189
+ type: "http"
2190
+ }],
2191
+ url: "/sent-emails/{id}/reply",
2192
+ ...options
2193
+ });
2194
+ /**
2195
+ * Get a conversation thread by id
2196
+ *
2197
+ * Returns a conversation thread: its metadata plus the inbound
2198
+ * and outbound messages that belong to it, interleaved in time
2199
+ * order (oldest first). A thread spans both received emails and
2200
+ * your sends, so an agent can reconstruct an entire back-and-forth
2201
+ * from one call instead of walking reply headers.
2202
+ *
2203
+ * Each message carries a `direction` (`inbound` | `outbound`) and
2204
+ * an `id`; fetch the full message via `/emails/{id}` or
2205
+ * `/sent-emails/{id}` accordingly. Bodies are omitted here to keep
2206
+ * the thread view lightweight.
2207
+ *
2208
+ * Discover a thread id from the `thread_id` field on any email or
2209
+ * sent-email (list or detail). The message list is capped; compare
2210
+ * `message_count` against `messages.length` to detect truncation.
2211
+ *
2212
+ */
2213
+ const getThread = (options) => (options.client ?? client).get({
2214
+ security: [{
2215
+ scheme: "bearer",
2216
+ type: "http"
2217
+ }],
2218
+ url: "/threads/{id}",
2219
+ ...options
2220
+ });
2221
+ /**
2222
+ * List functions
2223
+ *
2224
+ * Returns every active (non-deleted) function in the org, newest
2225
+ * first. Each entry carries deploy status and timestamps. To
2226
+ * inspect the source code or deploy errors, use `GET /functions/{id}`.
2227
+ *
2228
+ */
2229
+ const listFunctions = (options) => (options?.client ?? client).get({
2230
+ security: [{
2231
+ scheme: "bearer",
2232
+ type: "http"
2233
+ }],
2234
+ url: "/functions",
2235
+ ...options
2236
+ });
2237
+ /**
2238
+ * Deploy a function
2239
+ *
2240
+ * Creates and deploys a new function. The handler must be a single
2241
+ * ESM module whose default export is an object with an async
2242
+ * `fetch(request, env)` method (Workers-style). Primitive signs
2243
+ * each delivery and forwards the `Primitive-Signature` header to
2244
+ * the handler. Verify the raw request body with
2245
+ * `PRIMITIVE_WEBHOOK_SECRET` before parsing JSON; after verification
2246
+ * the request body parses to a webhook event whose `event` field is
2247
+ * `email.received` for normal inbound mail, or a machine-mail type
2248
+ * (`email.bounced`, `email.tls_report`, `email.dmarc_report`,
2249
+ * `email.dmarc_failure`) for bounces and reports. Code is bundled
2250
+ * before being uploaded; ship a single self-contained file rather
2251
+ * than relying on external imports.
2252
+ *
2253
+ * **Code limits.** `code` is capped at 1 MiB UTF-8. `sourceMap`
2254
+ * (optional) is capped at 5 MiB UTF-8, stored with each deployment
2255
+ * attempt, and sent to the runtime so stack traces can resolve to
2256
+ * original source files.
2257
+ *
2258
+ * **Routing.** On successful deploy, the function code is live
2259
+ * in the runtime, but inbound mail will not reach it until at
2260
+ * least one route is bound. Routes are managed from the Primitive
2261
+ * dashboard. A `deploy_status` of `deployed` means the script is
2262
+ * installed, not that the function is receiving mail. The
2263
+ * internal runtime URL is not returned by the API and is not a
2264
+ * customer-facing integration surface.
2265
+ *
2266
+ * **Secrets.** New functions ship with the managed secrets
2267
+ * (`PRIMITIVE_WEBHOOK_SECRET`, `PRIMITIVE_API_KEY`,
2268
+ * `PRIMITIVE_API_BASE_URL`) already bound. Add user-set secrets via
2269
+ * `POST /functions/{id}/secrets`; secret writes only land in the
2270
+ * running handler on the next redeploy.
2271
+ *
2272
+ */
2273
+ const createFunction = (options) => (options.client ?? client).post({
2274
+ security: [{
2275
+ scheme: "bearer",
2276
+ type: "http"
2277
+ }],
2278
+ url: "/functions",
2279
+ ...options,
2280
+ headers: {
2281
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2282
+ ...options.headers
2283
+ }
2284
+ });
2285
+ /**
2286
+ * Delete a function
2287
+ *
2288
+ * Soft-deletes the function row, removes the script from the edge
2289
+ * runtime, and deactivates any route bound to this function so no
2290
+ * further inbound mail is delivered. Past deploy history,
2291
+ * invocations, and logs are retained.
2292
+ *
2293
+ * Returns 502 if the runtime delete fails partway; the function
2294
+ * row stays in place and the call is safe to retry until it
2295
+ * succeeds.
2296
+ *
2297
+ */
2298
+ const deleteFunction = (options) => (options.client ?? client).delete({
2299
+ security: [{
2300
+ scheme: "bearer",
2301
+ type: "http"
2302
+ }],
2303
+ url: "/functions/{id}",
2304
+ ...options
2305
+ });
2306
+ /**
2307
+ * Get a function
2308
+ *
2309
+ * Returns the full record for a function, including its current
2310
+ * source code and the deploy status / error from the most recent
2311
+ * deploy attempt.
2312
+ *
2313
+ */
2314
+ const getFunction = (options) => (options.client ?? client).get({
2315
+ security: [{
2316
+ scheme: "bearer",
2317
+ type: "http"
2318
+ }],
2319
+ url: "/functions/{id}",
2320
+ ...options
2321
+ });
2322
+ /**
2323
+ * Update and redeploy a function
2324
+ *
2325
+ * Replaces the function's source code with the body's `code` and
2326
+ * triggers a redeploy. Same size limits as `POST /functions`.
2327
+ * Use this verb to push secret writes into the running handler:
2328
+ * passing the same `code` re-runs the deploy and refreshes the
2329
+ * binding set with the latest values from the secrets table.
2330
+ *
2331
+ * On deploy failure, the previously-deployed code stays live; the
2332
+ * runtime never serves a half-built bundle. The response uses
2333
+ * `error.code` `deploy_failed`, and the function's `deploy_error`
2334
+ * field carries the latest deploy error for dashboard/API reads.
2335
+ *
2336
+ */
2337
+ const updateFunction = (options) => (options.client ?? client).put({
2338
+ security: [{
2339
+ scheme: "bearer",
2340
+ type: "http"
2341
+ }],
2342
+ url: "/functions/{id}",
2343
+ ...options,
2344
+ headers: {
2345
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2346
+ ...options.headers
2347
+ }
2348
+ });
2349
+ /**
2350
+ * Send a test invocation
2351
+ *
2352
+ * Sends a real test email from a Primitive-controlled sender to a
2353
+ * local-part on one of the org's verified inbound domains. By
2354
+ * default the recipient is a synthetic
2355
+ * `__primitive_function_test+<random>@<domain>` address on a
2356
+ * domain selected to route to the function. Scoped functions use
2357
+ * their scoped domain; fallback functions use a domain that has
2358
+ * no enabled domain-scoped endpoint. Pass `local_part` to
2359
+ * override and exercise routing logic that branches on a specific
2360
+ * recipient (the common pattern when one function handles multiple
2361
+ * inboxes like `summarize@` and `action@`). The function fires
2362
+ * through the normal MX delivery path, so reply / send-mail calls
2363
+ * from inside the handler against the inbound's `email.id` work
2364
+ * the same as in production. Returns immediately after the send is
2365
+ * queued; the invocation appears on the function's invocations
2366
+ * list within a few seconds.
2367
+ *
2368
+ * Requires that the function is currently `deployed`. Returns 422
2369
+ * if the function is in `pending` or `failed` state, or if the
2370
+ * org has no verified inbound domain to receive the test mail.
2371
+ * Returns 400 if `local_part` is set to a value that does not
2372
+ * match the local-part character set.
2373
+ *
2374
+ */
2375
+ const testFunction = (options) => (options.client ?? client).post({
2376
+ security: [{
2377
+ scheme: "bearer",
2378
+ type: "http"
2379
+ }],
2380
+ url: "/functions/{id}/test",
2381
+ ...options,
2382
+ headers: {
2383
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2384
+ ...options.headers
2385
+ }
2386
+ });
2387
+ /**
2388
+ * Get a function test run trace
2389
+ *
2390
+ * Returns the current end-to-end trace for a function test run.
2391
+ * The trace is intentionally partial while the test is still in
2392
+ * flight: callers can poll this endpoint and watch it fill in
2393
+ * from send -> inbound -> webhook deliveries -> outbound
2394
+ * requests, logs, and replies.
2395
+ *
2396
+ */
2397
+ const getFunctionTestRunTrace = (options) => (options.client ?? client).get({
2398
+ security: [{
2399
+ scheme: "bearer",
2400
+ type: "http"
2401
+ }],
2402
+ url: "/functions/{id}/test-runs/{run_id}/trace",
2403
+ ...options
2404
+ });
2405
+ /**
2406
+ * Get the org's function routing topology
2407
+ *
2408
+ * Returns a single snapshot of how inbound mail is routed across
2409
+ * this org's active domains and functions: which active domain has
2410
+ * which function bound, the org's fallback function (if any), and
2411
+ * every deployed function with no route bound. Use this to answer
2412
+ * "which of my functions actually receive mail?" diagnostically.
2413
+ *
2414
+ */
2415
+ const getOrgRoutingTopology = (options) => (options?.client ?? client).get({
2416
+ security: [{
2417
+ scheme: "bearer",
2418
+ type: "http"
2419
+ }],
2420
+ url: "/functions/routing-topology",
2421
+ ...options
2422
+ });
2423
+ /**
2424
+ * Get a function's current route binding
2425
+ *
2426
+ * Returns the endpoint binding for the function, or null when no
2427
+ * route is currently bound. The binding identifies whether the
2428
+ * function receives mail for a specific domain (scoped) or for any
2429
+ * active domain that has no scoped binding (fallback).
2430
+ *
2431
+ */
2432
+ const getFunctionRouting = (options) => (options.client ?? client).get({
2433
+ security: [{
2434
+ scheme: "bearer",
2435
+ type: "http"
2436
+ }],
2437
+ url: "/functions/{id}/routing",
2438
+ ...options
2439
+ });
2440
+ /**
2441
+ * Unbind any route from a function
2442
+ *
2443
+ * Deactivates every active endpoint bound to this function. The
2444
+ * function stays deployed but stops receiving inbound mail. Safe
2445
+ * to call when no route is currently bound (no-op).
2446
+ *
2447
+ */
2448
+ const unsetFunctionRoute = (options) => (options.client ?? client).delete({
2449
+ security: [{
2450
+ scheme: "bearer",
2451
+ type: "http"
2452
+ }],
2453
+ url: "/functions/{id}/route",
2454
+ ...options
2455
+ });
2456
+ /**
2457
+ * Bind a route to a function
2458
+ *
2459
+ * Binds inbound mail to this function. The route target is either
2460
+ * a specific verified domain (scoped) or the org's fallback (any
2461
+ * active domain with no scoped binding). If another function is
2462
+ * already bound at the target, returns a `conflict` envelope
2463
+ * describing the holder; re-issue with `takeover: true` to
2464
+ * deactivate that prior binding and install this one.
2465
+ *
2466
+ */
2467
+ const setFunctionRoute = (options) => (options.client ?? client).put({
2468
+ security: [{
2469
+ scheme: "bearer",
2470
+ type: "http"
2471
+ }],
2472
+ url: "/functions/{id}/route",
2473
+ ...options,
2474
+ headers: {
2475
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2476
+ ...options.headers
2477
+ }
2478
+ });
2479
+ /**
2480
+ * List a function's secrets
2481
+ *
2482
+ * Returns metadata for every secret bound to the function, with
2483
+ * managed entries (provisioned by Primitive) listed first and
2484
+ * user-set entries listed alphabetically after. **Values are
2485
+ * never returned.** Secret writes are write-only.
2486
+ *
2487
+ * Managed entries (e.g. `PRIMITIVE_WEBHOOK_SECRET`,
2488
+ * `PRIMITIVE_API_KEY`, `PRIMITIVE_API_BASE_URL`) carry a
2489
+ * `description` instead of `created_at` / `updated_at`. They
2490
+ * cannot be created, updated, or deleted via this API.
2491
+ *
2492
+ */
2493
+ const listFunctionSecrets = (options) => (options.client ?? client).get({
2494
+ security: [{
2495
+ scheme: "bearer",
2496
+ type: "http"
2497
+ }],
2498
+ url: "/functions/{id}/secrets",
2499
+ ...options
2500
+ });
2501
+ /**
2502
+ * Create or update a secret
2503
+ *
2504
+ * Idempotent insert-or-update keyed on `(function_id, key)`.
2505
+ * Returns 201 the first time the key is set, 200 on subsequent
2506
+ * updates. Values are encrypted at rest and only become visible
2507
+ * to the running handler on the next deploy (`PUT /functions/{id}`
2508
+ * with the existing code is sufficient to refresh bindings).
2509
+ *
2510
+ * Keys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,
2511
+ * digits, underscores; first character is a letter or
2512
+ * underscore). Values are at most 4096 UTF-8 bytes. System-
2513
+ * managed keys are reserved and rejected.
2514
+ *
2515
+ */
2516
+ const createFunctionSecret = (options) => (options.client ?? client).post({
2517
+ security: [{
2518
+ scheme: "bearer",
2519
+ type: "http"
2520
+ }],
2521
+ url: "/functions/{id}/secrets",
2522
+ ...options,
2523
+ headers: {
2524
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2525
+ ...options.headers
2526
+ }
2527
+ });
2528
+ /**
2529
+ * Delete a secret
2530
+ *
2531
+ * Removes the secret. The binding stays live in the running
2532
+ * handler until the next deploy refreshes the binding set
2533
+ * (`PUT /functions/{id}` with the existing code is sufficient).
2534
+ * Returns 404 if the key did not exist. Managed system keys
2535
+ * cannot be deleted.
2536
+ *
2537
+ */
2538
+ const deleteFunctionSecret = (options) => (options.client ?? client).delete({
2539
+ security: [{
2540
+ scheme: "bearer",
2541
+ type: "http"
2542
+ }],
2543
+ url: "/functions/{id}/secrets/{key}",
2544
+ ...options
2545
+ });
2546
+ /**
2547
+ * Set a secret by key
2548
+ *
2549
+ * Path-keyed companion to `POST /functions/{id}/secrets`.
2550
+ * Idempotent: returns 201 the first time the key is set, 200 on
2551
+ * subsequent updates. Same validation rules and same write-only
2552
+ * guarantees as the POST verb; the new value lands in the running
2553
+ * handler on the next deploy.
2554
+ *
2555
+ */
2556
+ const setFunctionSecret = (options) => (options.client ?? client).put({
2557
+ security: [{
2558
+ scheme: "bearer",
2559
+ type: "http"
2560
+ }],
2561
+ url: "/functions/{id}/secrets/{key}",
2562
+ ...options,
2563
+ headers: {
2564
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2565
+ ...options.headers
2566
+ }
2567
+ });
2568
+ /**
2569
+ * List org-level (global) secrets
2570
+ *
2571
+ * Returns metadata for every org-level secret. Org secrets apply
2572
+ * to every function in the org and are read as `env.<KEY>` in
2573
+ * handlers. **Values are never returned.** Secret writes are
2574
+ * write-only. A function-level secret of the same name overrides
2575
+ * the org-level value for that function.
2576
+ *
2577
+ */
2578
+ const listOrgSecrets = (options) => (options?.client ?? client).get({
2579
+ security: [{
2580
+ scheme: "bearer",
2581
+ type: "http"
2582
+ }],
2583
+ url: "/org/secrets",
2584
+ ...options
2585
+ });
2586
+ /**
2587
+ * Create or update an org secret
2588
+ *
2589
+ * Idempotent insert-or-update keyed on `(org_id, key)`. Returns
2590
+ * 201 the first time the key is set, 200 on subsequent updates.
2591
+ * Values are encrypted at rest. A changed value lands in a
2592
+ * function only on that function's next deploy.
2593
+ *
2594
+ * Keys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,
2595
+ * digits, underscores; first character is a letter or
2596
+ * underscore). Values are at most 4096 UTF-8 bytes. System-
2597
+ * managed keys are reserved and rejected.
2598
+ *
2599
+ */
2600
+ const createOrgSecret = (options) => (options.client ?? client).post({
2601
+ security: [{
2602
+ scheme: "bearer",
2603
+ type: "http"
2604
+ }],
2605
+ url: "/org/secrets",
2606
+ ...options,
2607
+ headers: {
2608
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2609
+ ...options.headers
2610
+ }
2611
+ });
2612
+ /**
2613
+ * Delete an org secret
2614
+ *
2615
+ * Removes the org secret. Functions keep the previous value until
2616
+ * each is redeployed. Returns 404 if the key did not exist.
2617
+ *
2618
+ */
2619
+ const deleteOrgSecret = (options) => (options.client ?? client).delete({
2620
+ security: [{
2621
+ scheme: "bearer",
2622
+ type: "http"
2623
+ }],
2624
+ url: "/org/secrets/{key}",
2625
+ ...options
2626
+ });
2627
+ /**
2628
+ * Set an org secret by key
2629
+ *
2630
+ * Path-keyed companion to `POST /org/secrets`. Idempotent:
2631
+ * returns 201 the first time the key is set, 200 on subsequent
2632
+ * updates. Same validation and write-only guarantees as POST.
2633
+ *
2634
+ */
2635
+ const setOrgSecret = (options) => (options.client ?? client).put({
2636
+ security: [{
2637
+ scheme: "bearer",
2638
+ type: "http"
2639
+ }],
2640
+ url: "/org/secrets/{key}",
2641
+ ...options,
2642
+ headers: {
2643
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2644
+ ...options.headers
2645
+ }
2646
+ });
2647
+ /**
2648
+ * List a function's execution logs
2649
+ *
2650
+ * Returns the most recent `function_logs` rows for the function,
2651
+ * newest first. Each row is a single `console.log` / `console.error`
2652
+ * invocation captured from the running handler.
2653
+ *
2654
+ * Page through history with the opaque `cursor` returned as
2655
+ * `next_cursor`; pass it back as the `cursor` query param on the
2656
+ * next call. `next_cursor` is `null` when there are no further
2657
+ * rows. The cursor format is an implementation detail and should
2658
+ * not be parsed by callers.
2659
+ *
2660
+ */
2661
+ const listFunctionLogs = (options) => (options.client ?? client).get({
2662
+ security: [{
2663
+ scheme: "bearer",
2664
+ type: "http"
2665
+ }],
2666
+ url: "/functions/{id}/logs",
2667
+ ...options
2668
+ });
2669
+ /**
2670
+ * Delete a memory
2671
+ *
2672
+ * Delete one active memory by key and scope. Deletes are idempotent when
2673
+ * `if_version` is omitted: deleting a missing key returns `deleted:
2674
+ * false`. With `if_version`, a missing key still returns `deleted: false`,
2675
+ * but a stale version returns `memory_conflict`.
2676
+ *
2677
+ * A successful delete records memory write usage.
2678
+ *
2679
+ */
2680
+ const deleteMemory = (options) => (options.client ?? client).delete({
2681
+ security: [{
2682
+ scheme: "bearer",
2683
+ type: "http"
2684
+ }],
2685
+ url: "/memories",
2686
+ ...options
2687
+ });
2688
+ /**
2689
+ * Get a memory
2690
+ *
2691
+ * Fetch one active memory by key and scope. Omit scope parameters to use
2692
+ * the automatic default: function-authenticated context, then the
2693
+ * `x-primitive-function-id` header, then org scope. Function scope uses a
2694
+ * function id UUID in `scope_id`.
2695
+ *
2696
+ * A successful read records memory read usage and updates the memory's
2697
+ * read stats asynchronously.
2698
+ *
2699
+ */
2700
+ const getMemory = (options) => (options.client ?? client).get({
2701
+ security: [{
2702
+ scheme: "bearer",
2703
+ type: "http"
2704
+ }],
2705
+ url: "/memories",
2706
+ ...options
2707
+ });
2708
+ /**
2709
+ * Set a memory
2710
+ *
2711
+ * Create or update a durable JSON memory under an org or function scope.
2712
+ * When no explicit scope is provided, function-authenticated requests
2713
+ * use that function's id automatically; requests with
2714
+ * `x-primitive-function-id` use that function id; all other requests
2715
+ * default to org scope.
2716
+ *
2717
+ * `scope.type = function` requires the function id UUID in `scope.id`.
2718
+ * Function names are not accepted as scope identifiers. Values must be
2719
+ * valid JSON and serialize to at most 65536 UTF-8 bytes. Keys must be at
2720
+ * most 512 UTF-8 bytes. `version`, `read_count`, and `write_count` are
2721
+ * bigint counters serialized as strings.
2722
+ *
2723
+ * Passing `if_absent` turns the write into create-only. Passing
2724
+ * `if_version` turns the write into compare-and-set. These options are
2725
+ * mutually exclusive and return `memory_conflict` on a stale version or
2726
+ * existing key.
2727
+ *
2728
+ */
2729
+ const setMemory = (options) => (options.client ?? client).put({
2730
+ security: [{
2731
+ scheme: "bearer",
2732
+ type: "http"
2733
+ }],
2734
+ url: "/memories",
2735
+ ...options,
2736
+ headers: {
2737
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2738
+ ...options.headers
2739
+ }
2740
+ });
2741
+ /**
2742
+ * Search memories
2743
+ *
2744
+ * List active memories in a scope by lexicographic key prefix. Results
2745
+ * are ordered by key ascending. The `meta.cursor` value is the next key
2746
+ * cursor; pass it back as `cursor` to continue after that key.
2747
+ *
2748
+ * Search records one memory read usage event for the operation. Pass
2749
+ * `include_value=false` to return metadata only.
2750
+ *
2751
+ */
2752
+ const searchMemories = (options) => (options?.client ?? client).get({
2753
+ security: [{
2754
+ scheme: "bearer",
2755
+ type: "http"
2756
+ }],
2757
+ url: "/memories/search",
2758
+ ...options
2759
+ });
2760
+ /**
2761
+ * List function templates
2762
+ *
2763
+ * List approved Function templates available for browsing and
2764
+ * installation. Results are cacheable and paginated with
2765
+ * `data.next_cursor`.
2766
+ *
2767
+ */
2768
+ const listTemplates = (options) => (options?.client ?? client).get({
2769
+ url: "/templates",
2770
+ ...options
2771
+ });
2772
+ /**
2773
+ * Get a function template
2774
+ *
2775
+ * Fetch one approved Function template by slug, including its manifest
2776
+ * snapshot and README. The stored source files used for install are not
2777
+ * returned.
2778
+ *
2779
+ */
2780
+ const getTemplate = (options) => (options.client ?? client).get({
2781
+ url: "/templates/{id}",
2782
+ ...options
2783
+ });
2784
+ /**
2785
+ * Install a function template
2786
+ *
2787
+ * Start a one-shot deploy of an approved deploy-mode Function template.
2788
+ * The response returns an install record immediately; poll
2789
+ * `GET /templates/installs/{id}` for progress.
2790
+ *
2791
+ */
2792
+ const installTemplate = (options) => (options.client ?? client).post({
2793
+ security: [{
2794
+ scheme: "bearer",
2795
+ type: "http"
2796
+ }],
2797
+ url: "/templates/{id}/install",
2798
+ ...options,
2799
+ headers: {
2800
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2801
+ ...options.headers
2802
+ }
2803
+ });
2804
+ /**
2805
+ * Get template install status
2806
+ *
2807
+ * Fetch the current state of a template install. Reads may advance the
2808
+ * self-test phase when a reply effect has been observed.
2809
+ *
2810
+ */
2811
+ const getTemplateInstall = (options) => (options.client ?? client).get({
2812
+ security: [{
2813
+ scheme: "bearer",
2814
+ type: "http"
2815
+ }],
2816
+ url: "/templates/installs/{id}",
2817
+ ...options
2818
+ });
2819
+ /**
2820
+ * List payout addresses
2821
+ *
2822
+ * List your org's registered payout addresses, newest first.
2823
+ */
2824
+ const listPayoutAddresses = (options) => (options?.client ?? client).get({
2825
+ security: [{
2826
+ scheme: "bearer",
2827
+ type: "http"
2828
+ }],
2829
+ url: "/x402/payout-addresses",
2830
+ ...options
2831
+ });
2832
+ /**
2833
+ * Register a payout address
2834
+ *
2835
+ * Register (or update) the default payout address your org receives x402
2836
+ * payments at, for a given network. You prove control of the address with
2837
+ * an org-bound `personal_sign` signature over the message produced by the
2838
+ * SDK helper `buildPayoutRegistrationMessage`. The org id is taken from your
2839
+ * authenticated key, never the body, so a captured signature can't register
2840
+ * an address under another org. Exactly one default address exists per
2841
+ * (org, network); registering again replaces it. A payee MUST register a
2842
+ * payout address before calling `createChallenge`, because the challenge's
2843
+ * `pay_to` is resolved from this directory.
2844
+ *
2845
+ */
2846
+ const registerPayoutAddress = (options) => (options.client ?? client).post({
2847
+ security: [{
2848
+ scheme: "bearer",
2849
+ type: "http"
2850
+ }],
2851
+ url: "/x402/payout-addresses",
2852
+ ...options,
2853
+ headers: {
2854
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2855
+ ...options.headers
2856
+ }
2857
+ });
2858
+ /**
2859
+ * Create an email-native payment challenge
2860
+ *
2861
+ * Issue an x402 payment challenge over a real email thread (the payee
2862
+ * side). Unlike `createChallenge` (which mints a synthetic challenge id),
2863
+ * this sends the challenge as an email from `from` to `to` and binds the
2864
+ * payment to that DKIM-authenticated thread. The `pay_to` address and the
2865
+ * token asset are resolved server-side from your registered default payout
2866
+ * address for the network, never from the request. The response carries
2867
+ * the thread's `interaction_id` plus the `challenge` (the
2868
+ * `payment_requirements`, the `nonce_binding`, and `expires_at`) the payer
2869
+ * needs to sign; the payer replies with a signed `payment` interaction
2870
+ * step. Amounts are in token base units (USDC has 6 decimals, so `"10000"`
2871
+ * is 0.01 USDC).
2872
+ *
2873
+ */
2874
+ const createEmailChallenge = (options) => (options.client ?? client).post({
2875
+ security: [{
2876
+ scheme: "bearer",
2877
+ type: "http"
2878
+ }],
2879
+ url: "/x402/email-challenges",
2880
+ ...options,
2881
+ headers: {
2882
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2883
+ ...options.headers
2884
+ }
2885
+ });
2886
+ /**
2887
+ * Create a payment challenge
2888
+ *
2889
+ * Create an x402 payment challenge (the payee side of a payment). The
2890
+ * `pay_to` address is resolved server-side from your registered default
2891
+ * payout address for the network, never from the request. The response
2892
+ * carries the `nonce_binding` and `payment_requirements` the payer needs to
2893
+ * sign; hand the whole challenge object to the payer (for example in an
2894
+ * email reply). Amounts are in token base units (USDC has 6 decimals, so
2895
+ * `"10000"` is 0.01 USDC).
2896
+ *
2897
+ */
2898
+ const createChallenge = (options) => (options.client ?? client).post({
2899
+ security: [{
2900
+ scheme: "bearer",
2901
+ type: "http"
2902
+ }],
2903
+ url: "/x402/challenges",
2904
+ ...options,
2905
+ headers: {
2906
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2907
+ ...options.headers
2908
+ }
2909
+ });
2910
+ /**
2911
+ * Get a payment challenge
2912
+ *
2913
+ * Fetch a challenge you created, to poll its `status` and settlement
2914
+ * receipt (`settle_tx`). Scoped to the challenger org that created it.
2915
+ *
2916
+ */
2917
+ const getChallenge = (options) => (options.client ?? client).get({
2918
+ security: [{
2919
+ scheme: "bearer",
2920
+ type: "http"
2921
+ }],
2922
+ url: "/x402/challenges/{id}",
2923
+ ...options
2924
+ });
2925
+ /**
2926
+ * Pay a payment challenge
2927
+ *
2928
+ * Settle a challenge addressed to your org as payer. The request body
2929
+ * carries a signed x402 `PaymentPayload`: an EIP-3009
2930
+ * `transferWithAuthorization` signed locally with your own key, whose nonce
2931
+ * is bound to the challenge via the SDK's `deriveEip3009Nonce`. The platform
2932
+ * verifies every signed field against its own record of the challenge,
2933
+ * applies your spend policy, and settles on-chain through a facilitator.
2934
+ * Settlement is non-custodial; Primitive never holds funds. Idempotent:
2935
+ * paying an already-settled challenge returns the original receipt. Most
2936
+ * callers use the SDK `pay()` helper rather than building the payload by
2937
+ * hand.
2938
+ *
2939
+ */
2940
+ const payChallenge = (options) => (options.client ?? client).post({
2941
+ security: [{
2942
+ scheme: "bearer",
2943
+ type: "http"
2944
+ }],
2945
+ url: "/x402/challenges/{id}/pay",
2946
+ ...options,
2947
+ headers: {
2948
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2949
+ ...options.headers
2950
+ }
2951
+ });
2952
+ /**
2953
+ * Get your spend policy
2954
+ *
2955
+ * Read your org's outbound spend policy: the kill-switch, per-payment and
2956
+ * per-day caps, and the payee allowlist. Returns the defaults (no limits,
2957
+ * not paused) when no policy has been set.
2958
+ *
2959
+ */
2960
+ const getSpendPolicy = (options) => (options?.client ?? client).get({
2961
+ security: [{
2962
+ scheme: "bearer",
2963
+ type: "http"
2964
+ }],
2965
+ url: "/x402/spend-policy",
2966
+ ...options
2967
+ });
2968
+ /**
2969
+ * Update your spend policy
2970
+ *
2971
+ * Update your org's spend policy. Applied as a merge: only the fields you
2972
+ * include change, and omitted fields keep their current value, so a partial
2973
+ * update can't silently reset the kill-switch. Send an explicit `null` to
2974
+ * clear a cap. Caps are in token base units.
2975
+ *
2976
+ */
2977
+ const updateSpendPolicy = (options) => (options.client ?? client).put({
2978
+ security: [{
2979
+ scheme: "bearer",
2980
+ type: "http"
2981
+ }],
2982
+ url: "/x402/spend-policy",
2983
+ ...options,
2984
+ headers: {
2985
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
2986
+ ...options.headers
2987
+ }
2988
+ });
2989
+ /**
2990
+ * List declined payments
2991
+ *
2992
+ * The 50 most recent payments your org's spend policy declined, newest
2993
+ * first. Use this to see why an outbound payment was refused (a cap, the
2994
+ * payee allowlist, or the kill-switch) instead of only reading the
2995
+ * dashboard.
2996
+ *
2997
+ */
2998
+ const listDeclinedPayments = (options) => (options?.client ?? client).get({
2999
+ security: [{
3000
+ scheme: "bearer",
3001
+ type: "http"
3002
+ }],
3003
+ url: "/x402/declined-payments",
3004
+ ...options
3005
+ });
3006
+ /**
3007
+ * List your organization's agent networks
3008
+ *
3009
+ * An organization member login or an active connected agent allowed to see the network can read networks. The default organization network is always present. can_manage_all is true only for a current owner or admin; a connected credential receives false.
3010
+ */
3011
+ const listAgentNetworks = (options) => (options?.client ?? client).get({
3012
+ security: [{
3013
+ scheme: "bearer",
3014
+ type: "http"
3015
+ }],
3016
+ url: "/agent-networks",
3017
+ ...options
3018
+ });
3019
+ /**
3020
+ * List default network memberships available to your login
3021
+ *
3022
+ * An owner or admin sees all connected addresses, including hidden and excluded members. Other human members see only personal addresses owned by their current membership. Filtering happens before pagination. Connected-agent credentials cannot read this roster. Each row includes whether the requester can manage it.
3023
+ */
3024
+ const listDefaultNetworkMembers = (options) => (options?.client ?? client).get({
3025
+ security: [{
3026
+ scheme: "bearer",
3027
+ type: "http"
3028
+ }],
3029
+ url: "/agent-networks/default/members",
3030
+ ...options
3031
+ });
3032
+ /**
3033
+ * Remove an agent from the default network
3034
+ *
3035
+ * Owner or admin login required. The explicit exclusion persists across synchronization.
3036
+ */
3037
+ const removeDefaultNetworkMember = (options) => (options.client ?? client).delete({
3038
+ security: [{
3039
+ scheme: "bearer",
3040
+ type: "http"
3041
+ }],
3042
+ url: "/agent-networks/default/members/{address}",
3043
+ ...options
3044
+ });
3045
+ /**
3046
+ * Change whether an agent can see or be seen in the network
3047
+ *
3048
+ * An owner or admin may update any active address. Other human members may update only their own current, non-excluded personal address. Connected-agent credentials cannot update visibility. Omitted settings keep their current value.
3049
+ */
3050
+ const updateDefaultNetworkMember = (options) => (options.client ?? client).patch({
3051
+ security: [{
3052
+ scheme: "bearer",
3053
+ type: "http"
3054
+ }],
3055
+ url: "/agent-networks/default/members/{address}",
3056
+ ...options,
3057
+ headers: {
3058
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3059
+ ...options.headers
3060
+ }
3061
+ });
3062
+ /**
3063
+ * Add an agent to the default network
3064
+ *
3065
+ * Owner or admin login required. Restores an explicitly excluded member.
3066
+ */
3067
+ const addDefaultNetworkMember = (options) => (options.client ?? client).post({
3068
+ security: [{
3069
+ scheme: "bearer",
3070
+ type: "http"
3071
+ }],
3072
+ url: "/agent-networks/default/members/{address}",
3073
+ ...options
3074
+ });
3075
+ /**
3076
+ * Discover listed agents in your organization network
3077
+ *
3078
+ * Requires a connected-agent credential for an active member allowed to see the network, or an organization member login.
3079
+ */
3080
+ const listDefaultNetworkAgents = (options) => (options?.client ?? client).get({
3081
+ security: [{
3082
+ scheme: "bearer",
3083
+ type: "http"
3084
+ }],
3085
+ url: "/agent-networks/default/agents",
3086
+ ...options
3087
+ });
3088
+ /**
3089
+ * Get a listed agent by email address
3090
+ *
3091
+ * Requires a connected-agent credential allowed to see the network, or an organization member login. Unlisted agents look absent.
3092
+ */
3093
+ const getDefaultNetworkAgent = (options) => (options.client ?? client).get({
3094
+ security: [{
3095
+ scheme: "bearer",
3096
+ type: "http"
3097
+ }],
3098
+ url: "/agent-networks/default/agents/{address}",
3099
+ ...options
3100
+ });
3101
+ /**
3102
+ * Check whether network mail may wake this connected agent
3103
+ *
3104
+ * Requires the recipient's connected-agent credential. The recipient
3105
+ * address is derived from that credential. The email ID must identify
3106
+ * accepted or completed inbound mail for that exact recipient, with
3107
+ * matching stored sender and delivery evidence. Returns no sender profile
3108
+ * or existence detail. Clients must also verify the email detail's sender
3109
+ * provenance and respect explicit contact silence before using the result.
3110
+ * Network wake requires the sender to be connected and able to view the
3111
+ * network, and the recipient to be connected and listed. The sender need
3112
+ * not be listed and the recipient need not view the network. Ordinary
3113
+ * known-address email remains independent. Mail received before
3114
+ * allowed_since cannot be newly admitted.
3115
+ *
3116
+ */
3117
+ const checkDefaultNetworkContactAdmission = (options) => (options.client ?? client).post({
3118
+ security: [{
3119
+ scheme: "bearer",
3120
+ type: "http"
3121
+ }],
3122
+ url: "/agent-networks/default/contact-admission",
3123
+ ...options,
3124
+ headers: {
3125
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3126
+ ...options.headers
3127
+ }
3128
+ });
3129
+ /**
3130
+ * List the registries you own
3131
+ */
3132
+ const listRegistries = (options) => (options?.client ?? client).get({
3133
+ security: [{
3134
+ scheme: "bearer",
3135
+ type: "http"
3136
+ }],
3137
+ url: "/registries",
3138
+ ...options
3139
+ });
3140
+ /**
3141
+ * Create a registry
3142
+ */
3143
+ const createRegistry = (options) => (options.client ?? client).post({
3144
+ security: [{
3145
+ scheme: "bearer",
3146
+ type: "http"
3147
+ }],
3148
+ url: "/registries",
3149
+ ...options,
3150
+ headers: {
3151
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3152
+ ...options.headers
3153
+ }
3154
+ });
3155
+ /**
3156
+ * Delete a registry you own
3157
+ *
3158
+ * Removes the registry from discovery and frees its slug for re-creation.
3159
+ */
3160
+ const deleteRegistry = (options) => (options.client ?? client).delete({
3161
+ security: [{
3162
+ scheme: "bearer",
3163
+ type: "http"
3164
+ }],
3165
+ url: "/registries/{slug}",
3166
+ ...options
3167
+ });
3168
+ /**
3169
+ * Get a public registry's metadata
3170
+ */
3171
+ const getRegistry = (options) => (options.client ?? client).get({
3172
+ url: "/registries/{slug}",
3173
+ ...options
3174
+ });
3175
+ /**
3176
+ * Update a registry you own
3177
+ */
3178
+ const updateRegistry = (options) => (options.client ?? client).patch({
3179
+ security: [{
3180
+ scheme: "bearer",
3181
+ type: "http"
3182
+ }],
3183
+ url: "/registries/{slug}",
3184
+ ...options,
3185
+ headers: {
3186
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3187
+ ...options.headers
3188
+ }
3189
+ });
3190
+ /**
3191
+ * List agents in a registry
3192
+ */
3193
+ const listRegistryAgents = (options) => (options.client ?? client).get({
3194
+ url: "/registries/{slug}/agents",
3195
+ ...options
3196
+ });
3197
+ /**
3198
+ * Publish an agent into a registry
3199
+ */
3200
+ const publishAgent = (options) => (options.client ?? client).post({
3201
+ security: [{
3202
+ scheme: "bearer",
3203
+ type: "http"
3204
+ }],
3205
+ url: "/registries/{slug}/agents",
3206
+ ...options,
3207
+ headers: {
3208
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3209
+ ...options.headers
3210
+ }
3211
+ });
3212
+ /**
3213
+ * Unpublish an agent from a registry
3214
+ */
3215
+ const unpublishAgent = (options) => (options.client ?? client).delete({
3216
+ security: [{
3217
+ scheme: "bearer",
3218
+ type: "http"
3219
+ }],
3220
+ url: "/registries/{slug}/agents/{handle}",
3221
+ ...options
3222
+ });
3223
+ /**
3224
+ * Resolve a registry handle to its agent
3225
+ */
3226
+ const resolveRegistryHandle = (options) => (options.client ?? client).get({
3227
+ url: "/registries/{slug}/agents/{handle}",
3228
+ ...options
3229
+ });
3230
+ /**
3231
+ * List pending publication requests
3232
+ */
3233
+ const listRegistryRequests = (options) => (options.client ?? client).get({
3234
+ security: [{
3235
+ scheme: "bearer",
3236
+ type: "http"
3237
+ }],
3238
+ url: "/registries/{slug}/requests",
3239
+ ...options
3240
+ });
3241
+ /**
3242
+ * Approve or reject a publication request
3243
+ */
3244
+ const decideRegistryRequest = (options) => (options.client ?? client).post({
3245
+ security: [{
3246
+ scheme: "bearer",
3247
+ type: "http"
3248
+ }],
3249
+ url: "/registries/{slug}/requests/{id}",
3250
+ ...options,
3251
+ headers: {
3252
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3253
+ ...options.headers
3254
+ }
3255
+ });
3256
+ /**
3257
+ * Define an agent identity
3258
+ */
3259
+ const defineAgent = (options) => (options.client ?? client).post({
3260
+ security: [{
3261
+ scheme: "bearer",
3262
+ type: "http"
3263
+ }],
3264
+ url: "/agents",
3265
+ ...options,
3266
+ headers: {
3267
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3268
+ ...options.headers
3269
+ }
3270
+ });
3271
+ /**
3272
+ * Get an agent's public profile by address
3273
+ */
3274
+ const getAgent = (options) => (options.client ?? client).get({
3275
+ url: "/agents/{address}",
3276
+ ...options
3277
+ });
3278
+ /**
3279
+ * list Contacts
3280
+ *
3281
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3282
+ */
3283
+ const listContacts = (options) => (options?.client ?? client).get({
3284
+ security: [{
3285
+ scheme: "bearer",
3286
+ type: "http"
3287
+ }],
3288
+ url: "/contacts",
3289
+ ...options
3290
+ });
3291
+ /**
3292
+ * delete Contact
3293
+ *
3294
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3295
+ */
3296
+ const deleteContact = (options) => (options.client ?? client).delete({
3297
+ security: [{
3298
+ scheme: "bearer",
3299
+ type: "http"
3300
+ }],
3301
+ url: "/contacts/{address}",
3302
+ ...options
3303
+ });
3304
+ /**
3305
+ * get Contact
3306
+ *
3307
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3308
+ */
3309
+ const getContact = (options) => (options.client ?? client).get({
3310
+ security: [{
3311
+ scheme: "bearer",
3312
+ type: "http"
3313
+ }],
3314
+ url: "/contacts/{address}",
3315
+ ...options
3316
+ });
3317
+ /**
3318
+ * put Contact
3319
+ *
3320
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3321
+ */
3322
+ const putContact = (options) => (options.client ?? client).put({
3323
+ security: [{
3324
+ scheme: "bearer",
3325
+ type: "http"
3326
+ }],
3327
+ url: "/contacts/{address}",
3328
+ ...options,
3329
+ headers: {
3330
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3331
+ ...options.headers
3332
+ }
3333
+ });
3334
+ /**
3335
+ * list Agent Contacts
3336
+ *
3337
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3338
+ */
3339
+ const listAgentContacts = (options) => (options.client ?? client).get({
3340
+ security: [{
3341
+ scheme: "bearer",
3342
+ type: "http"
3343
+ }],
3344
+ url: "/agent-contacts/{agent_address}",
3345
+ ...options
3346
+ });
3347
+ /**
3348
+ * delete Agent Contact
3349
+ *
3350
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3351
+ */
3352
+ const deleteAgentContact = (options) => (options.client ?? client).delete({
3353
+ security: [{
3354
+ scheme: "bearer",
3355
+ type: "http"
3356
+ }],
3357
+ url: "/agent-contacts/{agent_address}/{contact_address}",
3358
+ ...options
3359
+ });
3360
+ /**
3361
+ * put Agent Contact
3362
+ *
3363
+ * Organization directory and agent preferences; no profiles, message history or runtime presence. Existing organization credentials use tenant permissions. Connected keys may read the directory, create address-only missing contacts using if_absent:true, and access only their own agent memberships; they cannot edit shared labels or delete directory entries. Function credentials are not granted access. Memberships require an existing local agent connection (including revoked connections) and an existing contact. PUT requires exactly one precondition. if_absent returns an existing row unchanged when supplied fields agree; otherwise 409. notify defaults false. Off-to-on generates a new server timestamp and generation; on-to-on and purpose-only edits preserve them. Disable clears activation metadata. Deletion atomically removes membership eligibility. Receivers must recheck generation/preferences before dispatch and pause admission when their policy cache is older than 30 seconds; explicit reply waits are independent. DELETE requires if_version, returns deleted:false for an absent row, and rejects stale versions of recreated rows. Pages use ascending canonical address, with meta.cursor null on the last page. Lists are live pages, not snapshots.
3364
+ */
3365
+ const putAgentContact = (options) => (options.client ?? client).put({
3366
+ security: [{
3367
+ scheme: "bearer",
3368
+ type: "http"
3369
+ }],
3370
+ url: "/agent-contacts/{agent_address}/{contact_address}",
3371
+ ...options,
3372
+ headers: {
3373
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3374
+ ...options.headers
3375
+ }
3376
+ });
3377
+ /**
3378
+ * Read organization contact policy
3379
+ *
3380
+ * Receiver-side email notification admission preferences; never task, tool, code execution or account authority. Rules take effect only in receivers implementing this current contact-policy contract. Older receivers may continue their previous exact-contact notifications until updated. Ordinary email delivery, storage, webhooks and explicit reply waits remain independent of these preferences. Organization owners/admins using session, OAuth or signed dashboard credentials may read/write policies. Connected credentials may only GET their own agent composite; they cannot write either policy. Function and signed capability credentials are not granted access. Rules are unordered. Exact membership notify:false always silences. Next use matching agent rules, otherwise matching organization rules; silence wins ties within that scope. If neither scope matches, existing exact membership notify:true allows using its own activation metadata; otherwise only enabled contact-request intake is allowed. Owner policy silence therefore cannot be bypassed by a connected agent adding a notify:true membership. Patterns are canonical lowercase bare mailboxes, *@example.com, research-*@example.com or *@*.example.com. Only a terminal local-part * and a leading whole domain-label *. are supported; subdomain patterns exclude the apex and require a literal multi-label suffix. No regular expressions, question marks, universal domains or wildcard TLDs. Domain-only UI input must be converted to *@domain. PUT fully replaces up to 100 rules and the request-intake option using exactly one CAS precondition. Duplicate pattern/effect pairs are rejected. if_absent returns an identical existing document, otherwise 409. A missing document reads as empty rules, null version/timestamps, false request intake for the organization and null (inherit) for the agent. Reset overrides with empty rules and null request intake. Allow rules preserve server activation metadata while retained unchanged; removing/recreating or changing a rule to allow resets it. Request intake defaults off; agent null inherits the organization. No-op writes preserve versions. Agent composite effective_version changes with either policy document, connection identity, generation or successful claim; effective_since is the latest policy mutation, connection creation or successful claim. Reclaiming a connection invalidates prior admission snapshots and starts a fresh rule/request cutoff; routine heartbeats do not. Rule/request admissions require received_at >= both the selected activation time and effective_since. Consequently even unrelated policy edits suppress queued older rule/request admissions, without deleting email history or affecting explicit reply waits. Exact membership fallback retains its own notify_since and generation but must still recheck current policy denies and effective_version. Before dispatch, receivers must recheck the current composite version and applicable activation generation and membership; stop new admissions when policy is unavailable or older than 30 seconds. Snapshot fields explain scope and matched rules locally; the API does not execute tasks or dispatch notifications.
3381
+ */
3382
+ const getContactPolicy = (options) => (options?.client ?? client).get({
3383
+ security: [{
3384
+ scheme: "bearer",
3385
+ type: "http"
3386
+ }],
3387
+ url: "/contact-policy",
3388
+ ...options
3389
+ });
3390
+ /**
3391
+ * Replace organization contact policy
3392
+ *
3393
+ * Receiver-side email notification admission preferences; never task, tool, code execution or account authority. Rules take effect only in receivers implementing this current contact-policy contract. Older receivers may continue their previous exact-contact notifications until updated. Ordinary email delivery, storage, webhooks and explicit reply waits remain independent of these preferences. Organization owners/admins using session, OAuth or signed dashboard credentials may read/write policies. Connected credentials may only GET their own agent composite; they cannot write either policy. Function and signed capability credentials are not granted access. Rules are unordered. Exact membership notify:false always silences. Next use matching agent rules, otherwise matching organization rules; silence wins ties within that scope. If neither scope matches, existing exact membership notify:true allows using its own activation metadata; otherwise only enabled contact-request intake is allowed. Owner policy silence therefore cannot be bypassed by a connected agent adding a notify:true membership. Patterns are canonical lowercase bare mailboxes, *@example.com, research-*@example.com or *@*.example.com. Only a terminal local-part * and a leading whole domain-label *. are supported; subdomain patterns exclude the apex and require a literal multi-label suffix. No regular expressions, question marks, universal domains or wildcard TLDs. Domain-only UI input must be converted to *@domain. PUT fully replaces up to 100 rules and the request-intake option using exactly one CAS precondition. Duplicate pattern/effect pairs are rejected. if_absent returns an identical existing document, otherwise 409. A missing document reads as empty rules, null version/timestamps, false request intake for the organization and null (inherit) for the agent. Reset overrides with empty rules and null request intake. Allow rules preserve server activation metadata while retained unchanged; removing/recreating or changing a rule to allow resets it. Request intake defaults off; agent null inherits the organization. No-op writes preserve versions. Agent composite effective_version changes with either policy document, connection identity, generation or successful claim; effective_since is the latest policy mutation, connection creation or successful claim. Reclaiming a connection invalidates prior admission snapshots and starts a fresh rule/request cutoff; routine heartbeats do not. Rule/request admissions require received_at >= both the selected activation time and effective_since. Consequently even unrelated policy edits suppress queued older rule/request admissions, without deleting email history or affecting explicit reply waits. Exact membership fallback retains its own notify_since and generation but must still recheck current policy denies and effective_version. Before dispatch, receivers must recheck the current composite version and applicable activation generation and membership; stop new admissions when policy is unavailable or older than 30 seconds. Snapshot fields explain scope and matched rules locally; the API does not execute tasks or dispatch notifications.
3394
+ */
3395
+ const putContactPolicy = (options) => (options.client ?? client).put({
3396
+ security: [{
3397
+ scheme: "bearer",
3398
+ type: "http"
3399
+ }],
3400
+ url: "/contact-policy",
3401
+ ...options,
3402
+ headers: {
3403
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3404
+ ...options.headers
3405
+ }
3406
+ });
3407
+ /**
3408
+ * Read agent contact policy
3409
+ *
3410
+ * Receiver-side email notification admission preferences; never task, tool, code execution or account authority. Rules take effect only in receivers implementing this current contact-policy contract. Older receivers may continue their previous exact-contact notifications until updated. Ordinary email delivery, storage, webhooks and explicit reply waits remain independent of these preferences. Organization owners/admins using session, OAuth or signed dashboard credentials may read/write policies. Connected credentials may only GET their own agent composite; they cannot write either policy. Function and signed capability credentials are not granted access. Rules are unordered. Exact membership notify:false always silences. Next use matching agent rules, otherwise matching organization rules; silence wins ties within that scope. If neither scope matches, existing exact membership notify:true allows using its own activation metadata; otherwise only enabled contact-request intake is allowed. Owner policy silence therefore cannot be bypassed by a connected agent adding a notify:true membership. Patterns are canonical lowercase bare mailboxes, *@example.com, research-*@example.com or *@*.example.com. Only a terminal local-part * and a leading whole domain-label *. are supported; subdomain patterns exclude the apex and require a literal multi-label suffix. No regular expressions, question marks, universal domains or wildcard TLDs. Domain-only UI input must be converted to *@domain. PUT fully replaces up to 100 rules and the request-intake option using exactly one CAS precondition. Duplicate pattern/effect pairs are rejected. if_absent returns an identical existing document, otherwise 409. A missing document reads as empty rules, null version/timestamps, false request intake for the organization and null (inherit) for the agent. Reset overrides with empty rules and null request intake. Allow rules preserve server activation metadata while retained unchanged; removing/recreating or changing a rule to allow resets it. Request intake defaults off; agent null inherits the organization. No-op writes preserve versions. Agent composite effective_version changes with either policy document, connection identity, generation or successful claim; effective_since is the latest policy mutation, connection creation or successful claim. Reclaiming a connection invalidates prior admission snapshots and starts a fresh rule/request cutoff; routine heartbeats do not. Rule/request admissions require received_at >= both the selected activation time and effective_since. Consequently even unrelated policy edits suppress queued older rule/request admissions, without deleting email history or affecting explicit reply waits. Exact membership fallback retains its own notify_since and generation but must still recheck current policy denies and effective_version. Before dispatch, receivers must recheck the current composite version and applicable activation generation and membership; stop new admissions when policy is unavailable or older than 30 seconds. Snapshot fields explain scope and matched rules locally; the API does not execute tasks or dispatch notifications.
3411
+ */
3412
+ const getAgentContactPolicy = (options) => (options.client ?? client).get({
3413
+ security: [{
3414
+ scheme: "bearer",
3415
+ type: "http"
3416
+ }],
3417
+ url: "/agent-contact-policy/{agent_address}",
3418
+ ...options
3419
+ });
3420
+ /**
3421
+ * Replace agent contact policy
3422
+ *
3423
+ * Receiver-side email notification admission preferences; never task, tool, code execution or account authority. Rules take effect only in receivers implementing this current contact-policy contract. Older receivers may continue their previous exact-contact notifications until updated. Ordinary email delivery, storage, webhooks and explicit reply waits remain independent of these preferences. Organization owners/admins using session, OAuth or signed dashboard credentials may read/write policies. Connected credentials may only GET their own agent composite; they cannot write either policy. Function and signed capability credentials are not granted access. Rules are unordered. Exact membership notify:false always silences. Next use matching agent rules, otherwise matching organization rules; silence wins ties within that scope. If neither scope matches, existing exact membership notify:true allows using its own activation metadata; otherwise only enabled contact-request intake is allowed. Owner policy silence therefore cannot be bypassed by a connected agent adding a notify:true membership. Patterns are canonical lowercase bare mailboxes, *@example.com, research-*@example.com or *@*.example.com. Only a terminal local-part * and a leading whole domain-label *. are supported; subdomain patterns exclude the apex and require a literal multi-label suffix. No regular expressions, question marks, universal domains or wildcard TLDs. Domain-only UI input must be converted to *@domain. PUT fully replaces up to 100 rules and the request-intake option using exactly one CAS precondition. Duplicate pattern/effect pairs are rejected. if_absent returns an identical existing document, otherwise 409. A missing document reads as empty rules, null version/timestamps, false request intake for the organization and null (inherit) for the agent. Reset overrides with empty rules and null request intake. Allow rules preserve server activation metadata while retained unchanged; removing/recreating or changing a rule to allow resets it. Request intake defaults off; agent null inherits the organization. No-op writes preserve versions. Agent composite effective_version changes with either policy document, connection identity, generation or successful claim; effective_since is the latest policy mutation, connection creation or successful claim. Reclaiming a connection invalidates prior admission snapshots and starts a fresh rule/request cutoff; routine heartbeats do not. Rule/request admissions require received_at >= both the selected activation time and effective_since. Consequently even unrelated policy edits suppress queued older rule/request admissions, without deleting email history or affecting explicit reply waits. Exact membership fallback retains its own notify_since and generation but must still recheck current policy denies and effective_version. Before dispatch, receivers must recheck the current composite version and applicable activation generation and membership; stop new admissions when policy is unavailable or older than 30 seconds. Snapshot fields explain scope and matched rules locally; the API does not execute tasks or dispatch notifications.
3424
+ */
3425
+ const putAgentContactPolicy = (options) => (options.client ?? client).put({
3426
+ security: [{
3427
+ scheme: "bearer",
3428
+ type: "http"
3429
+ }],
3430
+ url: "/agent-contact-policy/{agent_address}",
3431
+ ...options,
3432
+ headers: {
3433
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3434
+ ...options.headers
3435
+ }
3436
+ });
3437
+ /**
3438
+ * Get current caller identity
3439
+ *
3440
+ * Current authenticated identity. member_address is null for machine credentials or an unavailable member address.
3441
+ */
3442
+ const whoami = (options) => (options?.client ?? client).get({
3443
+ security: [{
3444
+ scheme: "bearer",
3445
+ type: "http"
3446
+ }],
3447
+ url: "/whoami",
3448
+ ...options
3449
+ });
3450
+ /**
3451
+ * Provision your member email address
3452
+ *
3453
+ * Provision or return this authenticated human member's stable managed address in this organization. API keys, connected agents and Functions cannot provision or impersonate humans. The owner explicitly chooses the address. Existing retained mail requires confirmation; reserved identities cannot be overridden. There is no target user input. An unavailable domain never silently changes the address.
3454
+ */
3455
+ const provisionMemberAddress = (options) => (options.client ?? client).put({
3456
+ security: [{
3457
+ scheme: "bearer",
3458
+ type: "http"
3459
+ }],
3460
+ url: "/account/member-address",
3461
+ ...options,
3462
+ headers: {
3463
+ ...options.body !== void 0 && { "Content-Type": "application/json" },
3464
+ ...options.headers
3465
+ }
3466
+ });
3467
+ //#endregion
3468
+ //#region src/oclif/automated-filter.ts
3469
+ /**
3470
+ * The server-side `automated` verdict on inbound email: `automated`
3471
+ * (boolean) and `automated_reasons` (why, in rule order), decided by
3472
+ * the API when the email arrives, and the `automated=true|false` filter
3473
+ * on GET /emails and GET /emails/search.
3474
+ *
3475
+ * A server that predates it either rejects the `automated` filter (GET
3476
+ * /emails validates its query strictly) or ignores it and returns rows
3477
+ * without the fields (GET /emails/search). Both must fail loudly: a CLI
3478
+ * that read a missing verdict as "not automated" would hand an agent
3479
+ * every bounce and newsletter as mail from a person, and one that fell
3480
+ * back to deciding it locally would re-read all unanswered automated
3481
+ * mail on every call.
3482
+ */
3483
+ const AUTOMATED_FILTER_UNSUPPORTED_CODE = "automated_filter_unsupported";
3484
+ const AUTOMATED_VALUES = ["true", "false"];
3485
+ const AUTOMATED_FLAG_DESCRIPTION = "Only emails whose server-decided `automated` verdict is this value: `false` = sent by a person, `true` = bounces and delivery reports, auto-replies, list and newsletter mail, and mail from the address it was sent to. Fails if the server does not support the automated filter yet.";
3486
+ var AutomatedFilterUnsupportedError = class extends Error {
3487
+ code = AUTOMATED_FILTER_UNSUPPORTED_CODE;
3488
+ constructor(detail) {
3489
+ super(`The server does not support the \`automated\` filter yet: ${detail} Nothing was treated as sent by a person. Upgrade to a server that returns \`automated\` and \`automated_reasons\`, or pass --include-automated.`);
3490
+ this.name = "AutomatedFilterUnsupportedError";
3491
+ }
3492
+ };
3493
+ /** Like AutomatedFilterUnsupportedError, for a probe that failed. */
3494
+ var AutomatedFilterUnverifiedError = class extends AutomatedFilterUnsupportedError {
3495
+ constructor(detail) {
3496
+ super(detail);
3497
+ this.message = `Could not verify that the server supports the \`automated\` filter: ${detail} Nothing was treated as matching. Retry the command.`;
3498
+ this.name = "AutomatedFilterUnverifiedError";
3499
+ this.code = "automated_filter_unverified";
3500
+ }
3501
+ };
3502
+ function hasAutomatedVerdict(row) {
3503
+ if (row === null || typeof row !== "object") return false;
3504
+ const candidate = row;
3505
+ return typeof candidate.automated === "boolean" && Array.isArray(candidate.automated_reasons) && candidate.automated_reasons.every((reason) => typeof reason === "string");
3506
+ }
3507
+ /**
3508
+ * Throw unless every row carries the verdict, and, for each `expected`
3509
+ * value given, unless every row has that value: a server that accepted
3510
+ * the filter but did not apply it must not pass for one that did.
3511
+ */
3512
+ function assertAutomatedVerdict(rows, surface, expected) {
3513
+ const missing = rows.filter((row) => !hasAutomatedVerdict(row)).length;
3514
+ if (missing > 0) throw new AutomatedFilterUnsupportedError(`${surface} returned ${missing} of ${rows.length} email${rows.length === 1 ? "" : "s"} without the \`automated\` and \`automated_reasons\` fields.`);
3515
+ const verdicts = expected === void 0 ? [] : typeof expected === "boolean" ? [expected] : expected;
3516
+ for (const verdict of verdicts) {
3517
+ const wrong = rows.filter((row) => row.automated !== verdict).length;
3518
+ if (wrong > 0) throw new AutomatedFilterUnsupportedError(`${surface} ignored \`automated=${verdict}\` and returned ${wrong} email${wrong === 1 ? "" : "s"} with \`automated=${!verdict}\`.`);
3519
+ }
3520
+ }
3521
+ /**
3522
+ * The verdicts the `automated:` terms in a search DSL query require.
3523
+ * The DSL joins its terms with AND, so every `automated:true|false`
3524
+ * term must hold for every returned row. Quoted text is skipped, so a
3525
+ * phrase that merely contains "automated:false" does not count.
3526
+ */
3527
+ function automatedVerdictsFromQuery(q) {
3528
+ if (typeof q !== "string") return [];
3529
+ const verdicts = [];
3530
+ const tokens = q.match(/(?:[^\s"]|"(?:[^"\\]|\\.)*"?)+/g) ?? [];
3531
+ for (const token of tokens) {
3532
+ const match = /^automated:"?(true|false)"?$/i.exec(token);
3533
+ if (match) verdicts.push(match[1].toLowerCase() === "true");
3534
+ }
3535
+ return verdicts;
3536
+ }
3537
+ /**
3538
+ * Every verdict a list or search call asked for: the `automated`
3539
+ * parameter plus any `automated:` terms in the search query.
3540
+ */
3541
+ function expectedAutomatedVerdicts(automated, q) {
3542
+ return [...automated === void 0 ? [] : [automated], ...automatedVerdictsFromQuery(q)];
3543
+ }
3544
+ /** True when a search DSL query uses the `automated:` term. */
3545
+ function queryUsesAutomated(q) {
3546
+ return typeof q === "string" && /(^|[\s(])-?automated:/i.test(q);
3547
+ }
3548
+ function errorBody$1(payload) {
3549
+ if (payload === null || typeof payload !== "object") return {};
3550
+ const inner = payload.error;
3551
+ return inner !== null && typeof inner === "object" ? inner : payload;
3552
+ }
3553
+ /**
3554
+ * True when an API error is an older server rejecting the `automated`
3555
+ * query parameter or the `automated:` search term as unknown.
3556
+ */
3557
+ function isAutomatedRejectedError(payload) {
3558
+ const body = errorBody$1(payload);
3559
+ if (body.code !== "validation_error") return false;
3560
+ const message = typeof body.message === "string" ? body.message : JSON.stringify(payload);
3561
+ return /automated/i.test(message) && /unrecogni[sz]ed|unknown/i.test(message);
3562
+ }
3563
+ function automatedRejectedError(surface) {
3564
+ return new AutomatedFilterUnsupportedError(`${surface} rejected the \`automated\` filter as unknown.`);
3565
+ }
3566
+ const AUTOMATED_SURFACES = {
3567
+ listEmails: "GET /emails",
3568
+ searchEmails: "GET /emails/search"
3569
+ };
3570
+ /**
3571
+ * For the generated `emails list` / `emails search` commands: the
3572
+ * surface name when this call filtered on `automated` (the parameter or
3573
+ * an `automated:` search term), else null.
3574
+ */
3575
+ function automatedSurfaceForOperation(sdkName, query) {
3576
+ const surface = AUTOMATED_SURFACES[sdkName];
3577
+ if (!surface || !query) return null;
3578
+ const q = typeof query.q === "string" ? query.q : void 0;
3579
+ return query.automated !== void 0 || queryUsesAutomated(q) ? surface : null;
3580
+ }
3581
+ const searchSupportProbes$1 = /* @__PURE__ */ new WeakMap();
3582
+ /**
3583
+ * GET /emails/search ignores unknown parameters, so an empty page for
3584
+ * `automated=...` does not show that the server applied the filter.
3585
+ * Read one unfiltered row: if it lacks the verdict the server does not
3586
+ * support it. No rows at all means the mailbox is empty, so the empty
3587
+ * answer stands. One probe per API client per process.
3588
+ */
3589
+ function ensureSearchReportsAutomated(apiClient) {
3590
+ const key = apiClient;
3591
+ let probe = searchSupportProbes$1.get(key);
3592
+ if (!probe) {
3593
+ probe = (async () => {
3594
+ const result = await searchEmails({
3595
+ client: apiClient.client,
3596
+ query: {
3597
+ limit: 1,
3598
+ include_facets: "false",
3599
+ snippet: "false"
3600
+ },
3601
+ responseStyle: "fields"
3602
+ });
3603
+ if (result.error) throw new AutomatedFilterUnverifiedError("the empty result could not be checked: reading one unfiltered row from GET /emails/search failed.");
3604
+ const rows = result.data?.data;
3605
+ assertAutomatedVerdict(rows ?? [], "GET /emails/search");
3606
+ })();
3607
+ searchSupportProbes$1.set(key, probe);
3608
+ probe.catch(() => {
3609
+ if (searchSupportProbes$1.get(key) === probe) searchSupportProbes$1.delete(key);
3610
+ });
3611
+ }
3612
+ return probe;
3613
+ }
3614
+ //#endregion
33
3615
  //#region ../node_modules/.pnpm/nodemailer@10.1.0/node_modules/nodemailer/dist/esm/addressparser/index.js
34
3616
  /**
35
3617
  * Restores the quoting of a local part that was read out of a quoted string.
@@ -17621,6 +21203,428 @@ function normalizeOptions(options) {
17621
21203
  };
17622
21204
  }
17623
21205
  //#endregion
21206
+ //#region src/oclif/reply-state.ts
21207
+ const AWAITING_VALUES = ["you", "them"];
21208
+ const AWAITING_FLAG_DESCRIPTION = "Only emails whose reply state is this value: `you` = waiting on your reply (the thread's latest message is inbound), `them` = you replied last. Queued and scheduled replies count as replied. Delivered mail only: rejected mail is never returned. Fails if the server does not report reply state yet.";
21209
+ const REPLY_STATE_UNSUPPORTED_CODE = "reply_state_unsupported";
21210
+ /** True when a search DSL query uses the `awaiting:` term. */
21211
+ function queryUsesAwaiting(q) {
21212
+ return typeof q === "string" && /(^|[\s(])-?awaiting:/i.test(q);
21213
+ }
21214
+ var ReplyStateUnsupportedError = class extends Error {
21215
+ code = REPLY_STATE_UNSUPPORTED_CODE;
21216
+ constructor(detail) {
21217
+ super(`The server does not support reply state yet: ${detail} Nothing was treated as awaiting your reply. Upgrade to a server that returns \`awaiting\` and \`reply_count\`, or run without reply-state options.`);
21218
+ this.name = "ReplyStateUnsupportedError";
21219
+ }
21220
+ };
21221
+ /**
21222
+ * The server's reply-state support could not be established (a probe
21223
+ * failed). Reported like ReplyStateUnsupportedError so callers never
21224
+ * read an unverified empty answer as "nothing matched".
21225
+ */
21226
+ var ReplyStateUnverifiedError = class extends ReplyStateUnsupportedError {
21227
+ constructor(detail) {
21228
+ super(detail);
21229
+ this.message = `Could not verify that the server supports reply state: ${detail} Nothing was treated as matching. Retry the command.`;
21230
+ this.name = "ReplyStateUnverifiedError";
21231
+ this.code = "reply_state_unverified";
21232
+ }
21233
+ };
21234
+ function hasReplyState(row) {
21235
+ if (row === null || typeof row !== "object") return false;
21236
+ const candidate = row;
21237
+ return (candidate.awaiting === "you" || candidate.awaiting === "them") && typeof candidate.reply_count === "number" && (candidate.last_replied_at === null || typeof candidate.last_replied_at === "string");
21238
+ }
21239
+ /**
21240
+ * Throw unless every row carries reply state. An empty page proves
21241
+ * nothing either way; callers that asked for reply state follow an
21242
+ * empty search page with ensureSearchReportsReplyState(). `surface` names the
21243
+ * response for the error, e.g. "GET /emails".
21244
+ */
21245
+ function assertReplyState(rows, surface) {
21246
+ const missing = rows.filter((row) => !hasReplyState(row)).length;
21247
+ if (missing > 0) throw new ReplyStateUnsupportedError(`${surface} returned ${missing} of ${rows.length} email${rows.length === 1 ? "" : "s"} without the \`awaiting\` and \`reply_count\` fields.`);
21248
+ }
21249
+ const AWAITING_REJECTED_UNSUPPORTED_CODE = "awaiting_rejected_unsupported";
21250
+ /**
21251
+ * The `awaiting` filter matches delivered mail only: a rejected email
21252
+ * (for example refused over the storage limit) was never delivered, so it
21253
+ * awaits no one. A server that returns one through the filter predates
21254
+ * that, and an agent would be handed mail nobody can answer.
21255
+ */
21256
+ var AwaitingIncludesRejectedError = class extends ReplyStateUnsupportedError {
21257
+ constructor(detail) {
21258
+ super(detail);
21259
+ this.message = `The server's \`awaiting\` filter does not exclude undelivered mail yet: ${detail} Upgrade to a server whose \`awaiting\` filter matches delivered mail only.`;
21260
+ this.name = "AwaitingIncludesRejectedError";
21261
+ this.code = AWAITING_REJECTED_UNSUPPORTED_CODE;
21262
+ }
21263
+ };
21264
+ /**
21265
+ * For rows returned BY an `awaiting` filter (not the unfiltered probe):
21266
+ * every row carries reply state, and none has status `rejected`.
21267
+ */
21268
+ function assertAwaitingFilterRows(rows, surface) {
21269
+ assertReplyState(rows, surface);
21270
+ const rejected = rows.filter((row) => row !== null && typeof row === "object" && row.status === "rejected").length;
21271
+ if (rejected > 0) throw new AwaitingIncludesRejectedError(`${surface} returned ${rejected} email${rejected === 1 ? "" : "s"} with status \`rejected\`.`);
21272
+ }
21273
+ function errorBody(payload) {
21274
+ if (payload === null || typeof payload !== "object") return {};
21275
+ const inner = payload.error;
21276
+ return inner !== null && typeof inner === "object" ? inner : payload;
21277
+ }
21278
+ /**
21279
+ * True when an API error is an older server rejecting the `awaiting`
21280
+ * query parameter or the `awaiting:` search term as unknown. A current
21281
+ * server accepts both, and the CLI only ever sends valid values.
21282
+ */
21283
+ function isAwaitingRejectedError(payload) {
21284
+ const body = errorBody(payload);
21285
+ if (body.code !== "validation_error") return false;
21286
+ const message = typeof body.message === "string" ? body.message : JSON.stringify(payload);
21287
+ return /awaiting/i.test(message) && /unrecogni[sz]ed|unknown/i.test(message);
21288
+ }
21289
+ function awaitingRejectedError(surface) {
21290
+ return new ReplyStateUnsupportedError(`${surface} rejected the \`awaiting\` filter as unknown.`);
21291
+ }
21292
+ /** Short column value for tables: "you", "them", or "-" when absent. */
21293
+ function formatAwaitingCell(row) {
21294
+ if (!hasReplyState(row)) return "-";
21295
+ return row.awaiting;
21296
+ }
21297
+ /** Reply count for tables, or "-" when the server did not report it. */
21298
+ function formatRepliesCell(row) {
21299
+ if (!hasReplyState(row)) return "-";
21300
+ return String(row.reply_count);
21301
+ }
21302
+ const REPLY_STATE_SURFACES = {
21303
+ listEmails: "GET /emails",
21304
+ searchEmails: "GET /emails/search"
21305
+ };
21306
+ /**
21307
+ * For the generated `emails list` / `emails search` commands: the
21308
+ * surface name when this call asked for reply state (an `awaiting`
21309
+ * parameter or an `awaiting:` search term), else null.
21310
+ */
21311
+ function replyStateSurfaceForOperation(sdkName, query) {
21312
+ const surface = REPLY_STATE_SURFACES[sdkName];
21313
+ if (!surface || !query) return null;
21314
+ const q = typeof query.q === "string" ? query.q : void 0;
21315
+ return query.awaiting !== void 0 || queryUsesAwaiting(q) ? surface : null;
21316
+ }
21317
+ const searchSupportProbes = /* @__PURE__ */ new WeakMap();
21318
+ /**
21319
+ * GET /emails/search ignores unknown parameters, so an empty page for
21320
+ * `awaiting=...` does not show that the server applied the filter.
21321
+ * Read one unfiltered row: if it lacks reply state the server does not
21322
+ * support it and this throws ReplyStateUnsupportedError. No rows at all
21323
+ * means the mailbox is empty, so the empty answer stands.
21324
+ */
21325
+ function ensureSearchReportsReplyState(apiClient) {
21326
+ const key = apiClient;
21327
+ let probe = searchSupportProbes.get(key);
21328
+ if (!probe) {
21329
+ probe = (async () => {
21330
+ const result = await searchEmails({
21331
+ client: apiClient.client,
21332
+ query: {
21333
+ limit: 1,
21334
+ include_facets: "false",
21335
+ snippet: "false"
21336
+ },
21337
+ responseStyle: "fields"
21338
+ });
21339
+ if (result.error) throw new ReplyStateUnverifiedError("the empty result could not be checked: reading one unfiltered row from GET /emails/search failed.");
21340
+ const rows = result.data?.data;
21341
+ assertReplyState(rows ?? [], "GET /emails/search");
21342
+ })();
21343
+ searchSupportProbes.set(key, probe);
21344
+ probe.catch(() => {
21345
+ if (searchSupportProbes.get(key) === probe) searchSupportProbes.delete(key);
21346
+ });
21347
+ }
21348
+ return probe;
21349
+ }
21350
+ //#endregion
21351
+ //#region src/oclif/commands/emails-poll.ts
21352
+ function quoteDslValue(value) {
21353
+ if (/^[^\s"]+$/.test(value)) return value;
21354
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
21355
+ }
21356
+ function combineQ(q, domain) {
21357
+ const parts = [q?.trim(), domain ? `domain:${quoteDslValue(domain.trim())}` : void 0].filter((part) => Boolean(part));
21358
+ return parts.length > 0 ? parts.join(" ") : void 0;
21359
+ }
21360
+ function normalizeIsoDate(value, label) {
21361
+ const parsed = new Date(value);
21362
+ if (Number.isNaN(parsed.getTime())) throw new Error(`${label} must be a valid date or ISO-8601 timestamp.`);
21363
+ return parsed.toISOString();
21364
+ }
21365
+ function filtersFromFlags(flags) {
21366
+ if (flags.automated !== void 0 && !AUTOMATED_VALUES.includes(flags.automated)) throw new Error("--automated must be true or false.");
21367
+ return {
21368
+ automated: flags.automated === void 0 ? void 0 : flags.automated === "true",
21369
+ awaiting: flags.awaiting,
21370
+ body: flags.body,
21371
+ domain: flags.domain,
21372
+ domainId: flags["domain-id"],
21373
+ from: flags.from,
21374
+ hasAttachment: flags["has-attachment"],
21375
+ q: flags.q,
21376
+ replyToSentEmailId: flags["reply-to-sent-email-id"],
21377
+ spamScoreGte: flags["spam-score-gte"],
21378
+ spamScoreLt: flags["spam-score-lt"],
21379
+ subject: flags.subject,
21380
+ to: flags.to
21381
+ };
21382
+ }
21383
+ function sinceFromFlags(flags) {
21384
+ if (flags.since) return normalizeIsoDate(flags.since, "--since");
21385
+ return flags["include-existing"] ? void 0 : (/* @__PURE__ */ new Date()).toISOString();
21386
+ }
21387
+ function buildEmailSearchQuery(params) {
21388
+ const query = {
21389
+ include_facets: "false",
21390
+ limit: params.pageSize,
21391
+ snippet: "false",
21392
+ sort: "received_at_asc"
21393
+ };
21394
+ const q = combineQ(params.filters.q, params.filters.domain);
21395
+ if (q) query.q = q;
21396
+ if (params.filters.awaiting) query.awaiting = params.filters.awaiting;
21397
+ if (params.filters.automated !== void 0) query.automated = params.filters.automated ? "true" : "false";
21398
+ if (params.filters.body) query.body = params.filters.body;
21399
+ if (params.filters.domainId) query.domain_id = params.filters.domainId;
21400
+ if (params.filters.from) query.from = params.filters.from;
21401
+ if (params.filters.hasAttachment !== void 0) query.has_attachment = params.filters.hasAttachment ? "true" : "false";
21402
+ if (params.filters.spamScoreGte !== void 0) query.spam_score_gte = params.filters.spamScoreGte;
21403
+ if (params.filters.spamScoreLt !== void 0) query.spam_score_lt = params.filters.spamScoreLt;
21404
+ if (params.filters.replyToSentEmailId) query.reply_to_sent_email_id = params.filters.replyToSentEmailId;
21405
+ if (params.filters.subject) query.subject = params.filters.subject;
21406
+ if (params.filters.to) query.to = params.filters.to;
21407
+ if (params.since) query.date_from = params.since;
21408
+ if (params.cursor) query.cursor = params.cursor;
21409
+ return query;
21410
+ }
21411
+ function encodeReceivedAtSearchCursor(email) {
21412
+ const raw = `r|${new Date(email.received_at).toISOString()}|${email.id}`;
21413
+ return Buffer.from(raw, "utf8").toString("base64url");
21414
+ }
21415
+ function cursorFromRows(rows) {
21416
+ const last = rows.at(-1);
21417
+ return last ? encodeReceivedAtSearchCursor(last) : null;
21418
+ }
21419
+ function cursorFromAcceptedRows(rows) {
21420
+ for (let i = rows.length - 1; i >= 0; i--) {
21421
+ const row = rows[i];
21422
+ if (row.status === "accepted" || row.status === "completed") return encodeReceivedAtSearchCursor(row);
21423
+ }
21424
+ return null;
21425
+ }
21426
+ function collectNewAcceptedEmails(rows, seenIds) {
21427
+ const fresh = [];
21428
+ for (const row of rows) {
21429
+ if (row.status !== "accepted" && row.status !== "completed") continue;
21430
+ if (seenIds.has(row.id)) continue;
21431
+ seenIds.add(row.id);
21432
+ fresh.push(row);
21433
+ }
21434
+ return fresh;
21435
+ }
21436
+ async function fetchEmailSearchPage(params) {
21437
+ const result = await searchEmails({
21438
+ client: params.apiClient.client,
21439
+ query: buildEmailSearchQuery({
21440
+ cursor: params.cursor,
21441
+ filters: params.filters,
21442
+ pageSize: params.pageSize,
21443
+ since: params.since
21444
+ }),
21445
+ responseStyle: "fields"
21446
+ });
21447
+ const wantsReplyState = Boolean(params.filters.awaiting) || queryUsesAwaiting(params.filters.q);
21448
+ const wantsAutomated = params.filters.automated !== void 0 || queryUsesAutomated(params.filters.q);
21449
+ if (result.error) {
21450
+ if (wantsReplyState && isAwaitingRejectedError(result.error)) throw awaitingRejectedError("GET /emails/search");
21451
+ if (wantsAutomated && isAutomatedRejectedError(result.error)) throw automatedRejectedError("GET /emails/search");
21452
+ return {
21453
+ ok: false,
21454
+ error: result.error,
21455
+ response: result.response
21456
+ };
21457
+ }
21458
+ const envelope = result.data;
21459
+ const rows = envelope?.data ?? [];
21460
+ if (wantsReplyState) {
21461
+ assertAwaitingFilterRows(rows, "GET /emails/search");
21462
+ if (rows.length === 0) await ensureSearchReportsReplyState(params.apiClient);
21463
+ }
21464
+ if (wantsAutomated) {
21465
+ assertAutomatedVerdict(rows, "GET /emails/search", expectedAutomatedVerdicts(params.filters.automated, params.filters.q));
21466
+ if (rows.length === 0) await ensureSearchReportsAutomated(params.apiClient);
21467
+ }
21468
+ return {
21469
+ ok: true,
21470
+ cursor: envelope?.meta.cursor ?? cursorFromRows(rows),
21471
+ rows
21472
+ };
21473
+ }
21474
+ function sleep(ms) {
21475
+ return new Promise((resolve) => setTimeout(resolve, ms));
21476
+ }
21477
+ //#endregion
21478
+ //#region src/oclif/transient-retry.ts
21479
+ /**
21480
+ * Transient API failures inside waits.
21481
+ *
21482
+ * A wait has a deadline. A rate limit (HTTP 429), a gateway or availability
21483
+ * failure (502, 503, 504) or a network error part way through it says
21484
+ * nothing about the thing being waited for, so the wait backs off and reads
21485
+ * again until its deadline instead of failing. Only idempotent reads go
21486
+ * through here; sends are never retried.
21487
+ *
21488
+ * The decision uses the HTTP status and headers of the generated client's
21489
+ * `responseStyle: "fields"` result, never the error text.
21490
+ */
21491
+ const BASE_BACKOFF_MS = 1e3;
21492
+ const MAX_BACKOFF_MS = 3e4;
21493
+ const HTTP_DATE = /^[A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/;
21494
+ /**
21495
+ * Milliseconds to wait from a Retry-After value: delay-seconds or an
21496
+ * HTTP-date. Undefined when the value is missing or malformed.
21497
+ */
21498
+ function parseRetryAfter(value, now = Date.now()) {
21499
+ const raw = value?.trim() ?? "";
21500
+ if (/^\d+$/.test(raw)) {
21501
+ const seconds = Number(raw);
21502
+ return Number.isSafeInteger(seconds) ? seconds * 1e3 : void 0;
21503
+ }
21504
+ if (HTTP_DATE.test(raw)) {
21505
+ const at = Date.parse(raw);
21506
+ if (Number.isFinite(at)) return Math.max(0, at - now);
21507
+ }
21508
+ }
21509
+ function responseOf(result) {
21510
+ if (!result || typeof result !== "object") return void 0;
21511
+ const response = result.response;
21512
+ return response && typeof response === "object" ? response : void 0;
21513
+ }
21514
+ /** The HTTP status of a generated-client result, when it has a response. */
21515
+ function responseStatus(result) {
21516
+ const status = responseOf(result)?.status;
21517
+ return typeof status === "number" ? status : void 0;
21518
+ }
21519
+ /**
21520
+ * Classify a generated-client result (`{ data, error, response }`). Null for
21521
+ * a success or a failure that retrying cannot fix.
21522
+ */
21523
+ function transientFailure(result) {
21524
+ if (!result || typeof result !== "object") return null;
21525
+ const error = result.error;
21526
+ const response = responseOf(result);
21527
+ const status = responseStatus(result);
21528
+ if (status === void 0) return error instanceof Error && error.name !== "AbortError" ? { reason: "network" } : null;
21529
+ if (status !== 429 && status !== 502 && status !== 503 && status !== 504) return null;
21530
+ const retryAfterMs = parseRetryAfter(response?.headers?.get?.("retry-after"));
21531
+ return {
21532
+ reason: status === 429 ? "rate_limited" : "unavailable",
21533
+ status,
21534
+ ...retryAfterMs === void 0 ? {} : { retryAfterMs }
21535
+ };
21536
+ }
21537
+ /** Exponential backoff with jitter, for a failure without a Retry-After. */
21538
+ function backoffDelay(attempt, random = Math.random) {
21539
+ const ceiling = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attempt);
21540
+ return Math.round(ceiling / 2 + random() * ceiling / 2);
21541
+ }
21542
+ function describeTransientFailure(failure) {
21543
+ if (failure.reason === "rate_limited") return "rate limited";
21544
+ if (failure.reason === "network") return "network error";
21545
+ return `API unavailable (HTTP ${failure.status})`;
21546
+ }
21547
+ function seconds(ms) {
21548
+ return `${Math.ceil(ms / 1e3)} s`;
21549
+ }
21550
+ /**
21551
+ * Print one notice and sleep before the next attempt, never past the
21552
+ * deadline. Resolves false when the deadline has passed.
21553
+ */
21554
+ async function pauseForTransientFailure(failure, attempt, options) {
21555
+ options.onTransientFailure?.(failure);
21556
+ const deadline = options.deadline ?? null;
21557
+ const remaining = deadline === null ? Number.POSITIVE_INFINITY : deadline - Date.now();
21558
+ if (remaining <= 0) return false;
21559
+ const wanted = failure.retryAfterMs ?? backoffDelay(attempt);
21560
+ const delay = Math.min(wanted, remaining);
21561
+ (options.notice ?? ((message) => process.stderr.write(`${message}\n`)))(delay < wanted ? `primitive: ${describeTransientFailure(failure)} (retry after ${seconds(wanted)}); this wait times out in ${seconds(delay)}.` : `primitive: ${describeTransientFailure(failure)}; retrying in ${seconds(delay)}.`);
21562
+ await sleep(delay);
21563
+ return deadline === null || Date.now() < deadline;
21564
+ }
21565
+ /**
21566
+ * Run an idempotent read, retrying transient failures until the deadline.
21567
+ * Resolves the first result that is not transient, or null when the
21568
+ * deadline passes first (or the read itself resolved null).
21569
+ */
21570
+ async function retryTransient(read, options) {
21571
+ for (let attempt = 0;; attempt += 1) {
21572
+ const result = await read();
21573
+ if (result === null) return null;
21574
+ const failure = options.deadline === void 0 ? null : transientFailure(result);
21575
+ if (!failure) return result;
21576
+ if (!await pauseForTransientFailure(failure, attempt, options)) return null;
21577
+ }
21578
+ }
21579
+ /** Thrown out of a wait's read when its deadline passed while backing off. */
21580
+ var WaitDeadlineReached = class extends Error {
21581
+ constructor() {
21582
+ super("The wait's deadline passed while retrying the API.");
21583
+ this.name = "WaitDeadlineReached";
21584
+ }
21585
+ };
21586
+ /**
21587
+ * Wrap a generated operation so that it retries transient failures.
21588
+ * `prepare` runs before every attempt, so an attempt can be fitted to the
21589
+ * time left (a long-poll's hold, say); returning null ends the wait.
21590
+ */
21591
+ function retryingOperation(operation, options, prepare) {
21592
+ return (async (input) => {
21593
+ const result = await retryTransient(() => {
21594
+ const attempt = prepare ? prepare(input) : input;
21595
+ return attempt === null ? Promise.resolve(null) : operation(attempt);
21596
+ }, options);
21597
+ if (result === null) throw new WaitDeadlineReached();
21598
+ return result;
21599
+ });
21600
+ }
21601
+ function clean(text, max) {
21602
+ let flat = "";
21603
+ for (const char of text) {
21604
+ const code = char.charCodeAt(0);
21605
+ flat += code < 32 || code === 127 ? " " : char;
21606
+ }
21607
+ flat = flat.replace(/\s+/g, " ").trim();
21608
+ return flat.length > max ? `${flat.slice(0, max - 3)}...` : flat;
21609
+ }
21610
+ /**
21611
+ * The API's own error code and message for a failed result, for a one-line
21612
+ * diagnostic: `not_found (Email not found)`, `HTTP 500`, or
21613
+ * `network error`.
21614
+ */
21615
+ function describeApiFailure(result) {
21616
+ const raw = result && typeof result === "object" ? result.error : void 0;
21617
+ const status = responseStatus(result);
21618
+ if (status === void 0 && raw instanceof Error) return "network error";
21619
+ let payload = raw;
21620
+ if (payload && typeof payload === "object" && "error" in payload && payload.error && typeof payload.error === "object") payload = payload.error;
21621
+ const record = payload && typeof payload === "object" ? payload : {};
21622
+ const code = typeof record.code === "string" && record.code ? clean(record.code, 80) : void 0;
21623
+ const message = typeof record.message === "string" && record.message ? clean(record.message, 200) : typeof payload === "string" && payload ? clean(payload, 200) : void 0;
21624
+ const label = code ?? (status === void 0 ? "api_error" : `HTTP ${status}`);
21625
+ return message ? `${label} (${message})` : label;
21626
+ }
21627
+ //#endregion
17624
21628
  //#region ../sdk-node/dist/repeats-BL7ZC-_6.js
17625
21629
  const UUID$3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
17626
21630
  const ATOM = "[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+";
@@ -18403,4 +22407,4 @@ function repeatStopCommand(emailId) {
18403
22407
  return `primitive repeat stop --id ${emailId.toLowerCase()}`;
18404
22408
  }
18405
22409
  //#endregion
18406
- export { __exportAll as S, WEBHOOK_EVENT_TYPES as _, REPEAT_IDLE_MAX_MINUTES as a, parseWebhookEvent as b, classifySignalContent as c, parseRepeatTick as d, preparePresenceAliveEmail as f, SENT_EMAIL_EVENT_TYPES as g, sendPreparedSignal as h, REPEAT_EVERY_MAX_MINUTES as i, parseInteractionEnvelope as l, repeatStopCommand as m, MAX_PRESENCE_ENVELOPE_BYTES as n, REPEAT_MAX_SENDS_MAX as o, prepareSignalEmail as p, PRESENCE_PROBE_TEXT as r, buildRepeatStopBody as s, MAX_INTERACTION_BYTES as t, parsePresenceEnvelope as u, isEmailReceivedEvent as v, parseFromHeader as x, isTrustedSender as y };
22410
+ export { AutomatedFilterUnsupportedError as $, listDomains as $t, sleep as A, setMemory as An, getAgentContactPolicy as At, hasReplyState as B, updateRepeatingSend as Bn, getMemory as Bt, collectNewAcceptedEmails as C, sdk_gen_exports as Cn, deleteWakeSchedule as Ct, filtersFromFlags as D, sendEmail as Dn, downloadSentAttachmentArchiveMember as Dt, fetchEmailSearchPage as E, semanticSearch as En, downloadEmailAttachmentPart as Et, assertAwaitingFilterRows as F, stopRepeatFromEmail as Fn, getEmail as Ft, WEBHOOK_EVENT_TYPES as G, verifyAgentSignup as Gn, getWakeSchedule as Gt, queryUsesAwaiting as H, updateWakeAuthorization as Hn, getRepeatingSend as Ht, awaitingRejectedError as I, testFunction as In, getFunction as It, parseWebhookEvent as J, listAgentContacts as Jt, isEmailReceivedEvent as K, __exportAll as Kn, inviteAgentConnection as Kt, ensureSearchReportsReplyState as L, unsetFunctionRoute as Ln, getFunctionRouting as Lt, AWAITING_VALUES as M, startAgentClaim as Mn, getConversation as Mt, REPLY_STATE_UNSUPPORTED_CODE as N, startAgentSignup as Nn, getCreditBalance as Nt, quoteDslValue as O, setFunctionRoute as On, downloadSentAttachmentByFilename as Ot, ReplyStateUnsupportedError as P, startCliLogin as Pn, getDefaultNetworkAgent as Pt, AUTOMATED_VALUES as Q, listDefaultNetworkMembers as Qt, formatAwaitingCell as R, updateDefaultNetworkMember as Rn, getFunctionTestRunTrace as Rt, transientFailure as S, runWakeSchedule as Sn, deleteWakeAuthorization as St, encodeReceivedAtSearchCursor as T, searchMemories as Tn, downloadEmailAttachmentByFilename as Tt, replyStateSurfaceForOperation as U, updateWakeSchedule as Un, getSentEmail as Ut, isAwaitingRejectedError as V, updateRoute as Vn, getOrgRoutingTopology as Vt, SENT_EMAIL_EVENT_TYPES as W, verifyAgentClaim as Wn, getThread as Wt, AUTOMATED_FILTER_UNSUPPORTED_CODE as X, listContacts as Xt, parseFromHeader as Y, listAgentNetworks as Yt, AUTOMATED_FLAG_DESCRIPTION as Z, listDefaultNetworkAgents as Zt, describeApiFailure as _, redeemCreditCode as _n, createWakeSchedule as _t, REPEAT_IDLE_MAX_MINUTES as a, listRepeatingSends as an, hasAutomatedVerdict as at, retryTransient as b, replyToEmail as bn, deleteMemory as bt, classifySignalContent as c, listSentEmails as cn, cancelSentEmail as ct, parseRepeatTick as d, listWakeSchedules as dn, cliLogout as dt, listEmailAttachmentArchiveMembers as en, assertAutomatedVerdict as et, preparePresenceAliveEmail as f, pollCliLogin as fn, completeWebhookEvent as ft, WaitDeadlineReached as g, putContact as gn, createWakeAuthorization as gt, sendPreparedSignal as h, putAgentContactPolicy as hn, createRoute as ht, REPEAT_EVERY_MAX_MINUTES as i, listFunctions as in, expectedAutomatedVerdicts as it, AWAITING_FLAG_DESCRIPTION as j, simulateRoute as jn, getContact as jt, sinceFromFlags as k, setFunctionSecret as kn, getAccount as kt, parseInteractionEnvelope as l, listWakeAuthorizations as ln, cancelSentEmailByIdempotencyKey as lt, repeatStopCommand as m, putAgentContact as mn, createFunction as mt, MAX_PRESENCE_ENVELOPE_BYTES as n, listEndpoints as nn, automatedSurfaceForOperation as nt, REPEAT_MAX_SENDS_MAX as o, listRoutes as on, isAutomatedRejectedError as ot, prepareSignalEmail as p, pullWebhookEvent as pn, createEndpoint as pt, isTrustedSender as q, listAgentConnections as qt, PRESENCE_PROBE_TEXT as r, listFunctionLogs as rn, ensureSearchReportsAutomated as rt, buildRepeatStopBody as s, listSentAttachmentArchiveMembers as sn, addDefaultNetworkMember as st, MAX_INTERACTION_BYTES as t, listEmails as tn, automatedRejectedError as tt, parsePresenceEnvelope as u, listWakeDispatches as un, checkDefaultNetworkContactAdmission as ut, parseRetryAfter as v, removeDefaultNetworkMember as vn, deleteAgentContact as vt, cursorFromAcceptedRows as w, searchEmails as wn, downloadEmailAttachmentArchiveMember as wt, retryingOperation as x, resendAgentSignupVerification as xn, deleteRoute as xt, pauseForTransientFailure as y, reorderRoutes as yn, deleteContact as yt, formatRepliesCell as z, updateFunction as zn, getInboxStatus as zt };