@agent-cards/sdk 0.23.28 → 0.24.1

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/PREFLIGHT.md +7 -1
  3. package/README.md +197 -102
  4. package/dist/aci.d.ts +52 -22
  5. package/dist/aci.js +79 -15
  6. package/dist/adyen-merchant-hosted.generated.d.ts +2 -2
  7. package/dist/adyen-merchant-hosted.generated.js +586 -55
  8. package/dist/agent-amount.generated.js +1 -1
  9. package/dist/agentcard.d.ts +4 -5
  10. package/dist/agentcard.js +4 -5
  11. package/dist/amadeus.d.ts +9 -3
  12. package/dist/amadeus.js +33 -4
  13. package/dist/api-module.d.ts +1 -7
  14. package/dist/api-module.js +3 -5
  15. package/dist/{voice-retry.js → api-retry.js} +1 -1
  16. package/dist/api-types.d.ts +53 -0
  17. package/dist/{voice-types.js → api-types.js} +7 -2
  18. package/dist/approvals.d.ts +166 -0
  19. package/dist/approvals.js +213 -0
  20. package/dist/aurus.d.ts +33 -0
  21. package/dist/aurus.js +75 -0
  22. package/dist/builtin-registry.generated.js +1 -1
  23. package/dist/buy.d.ts +20 -101
  24. package/dist/buy.js +19 -74
  25. package/dist/capabilities.generated.js +1 -1
  26. package/dist/card-fields.generated.js +2864 -249
  27. package/dist/cardlink-vpos.d.ts +43 -0
  28. package/dist/cardlink-vpos.js +90 -0
  29. package/dist/cdp.d.ts +3 -13
  30. package/dist/cdp.js +244 -175
  31. package/dist/checkout-com.generated.js +5 -1
  32. package/dist/client.d.ts +170 -22
  33. package/dist/client.js +281 -40
  34. package/dist/creditguard.generated.d.ts +4 -4
  35. package/dist/cybersource-flex.generated.d.ts +39 -1
  36. package/dist/cybersource-flex.generated.js +100 -11
  37. package/dist/datatrans.generated.js +22 -1
  38. package/dist/eghl.d.ts +40 -0
  39. package/dist/eghl.js +72 -0
  40. package/dist/elavon-converge.generated.js +5 -3
  41. package/dist/gmo.generated.js +7 -2
  42. package/dist/hold.d.ts +8 -0
  43. package/dist/hold.js +43 -2
  44. package/dist/hosted-entry.js +4 -0
  45. package/dist/index.d.ts +9 -15
  46. package/dist/index.js +6 -10
  47. package/dist/lifecycle.d.ts +9 -61
  48. package/dist/lifecycle.js +24 -10
  49. package/dist/merchant-card-endpoints.generated.d.ts +6 -1
  50. package/dist/merchant-card-endpoints.generated.js +344 -19
  51. package/dist/merchant-hosted.d.ts +8 -1
  52. package/dist/nike-order.d.ts +51 -0
  53. package/dist/nike-order.js +81 -0
  54. package/dist/oceanpayment.d.ts +38 -0
  55. package/dist/oceanpayment.js +70 -0
  56. package/dist/paddle-tokenex.generated.js +111 -11
  57. package/dist/payplug.d.ts +41 -0
  58. package/dist/payplug.js +71 -0
  59. package/dist/payrails.generated.js +33 -8
  60. package/dist/pre-claim.d.ts +11 -0
  61. package/dist/pre-claim.js +130 -7
  62. package/dist/preflight-capabilities.generated.d.ts +0 -4
  63. package/dist/preflight-capabilities.generated.js +0 -5
  64. package/dist/preflight-catalog.json +200 -6
  65. package/dist/preflight-playwright.d.ts +2 -2
  66. package/dist/preflight-playwright.js +63 -14
  67. package/dist/preflight-schemas.json +18 -0
  68. package/dist/preflight.generated.d.ts +5 -4
  69. package/dist/preflight.generated.js +63 -3
  70. package/dist/preparation.d.ts +7 -0
  71. package/dist/preparation.js +21 -0
  72. package/dist/prepared-processor.d.ts +18 -5
  73. package/dist/prepared-processor.js +48 -8
  74. package/dist/primer.generated.js +2889 -268
  75. package/dist/processout.generated.d.ts +61 -0
  76. package/dist/processout.generated.js +577 -0
  77. package/dist/requests.js +1 -1
  78. package/dist/shiji-sts.generated.js +111 -11
  79. package/dist/stripe-checkout.generated.js +2761 -319
  80. package/dist/substitutions.generated.js +553 -26
  81. package/dist/tap-payments.generated.js +111 -11
  82. package/dist/twoc2p.generated.js +111 -11
  83. package/dist/url-masks/bluesnap.d.ts +2 -0
  84. package/dist/url-masks/bluesnap.js +15 -0
  85. package/dist/url-masks/oceanpayment.d.ts +2 -0
  86. package/dist/url-masks/oceanpayment.js +13 -0
  87. package/dist/url-masks/payplug.d.ts +2 -0
  88. package/dist/url-masks/payplug.js +13 -0
  89. package/dist/url-masks/vtex_payments.d.ts +2 -0
  90. package/dist/url-masks/vtex_payments.js +12 -0
  91. package/dist/url-masks.generated.d.ts +1 -1
  92. package/dist/url-masks.generated.js +6 -2
  93. package/dist/verifone.generated.js +42 -2
  94. package/dist/vtex-payments.generated.d.ts +127 -0
  95. package/dist/vtex-payments.generated.js +544 -0
  96. package/dist/webhooks.d.ts +2 -2
  97. package/dist/webhooks.js +2 -2
  98. package/examples/preflight/kernel-native/inventory.json +1 -1
  99. package/package.json +6 -8
  100. package/dist/languages.d.ts +0 -23
  101. package/dist/languages.js +0 -76
  102. package/dist/voice-pkce.d.ts +0 -49
  103. package/dist/voice-pkce.js +0 -147
  104. package/dist/voice-stream.generated.d.ts +0 -118
  105. package/dist/voice-stream.generated.js +0 -170
  106. package/dist/voice-types.d.ts +0 -735
  107. package/dist/voice.d.ts +0 -373
  108. package/dist/voice.js +0 -815
  109. package/readme.test.mjs +0 -53
  110. /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
@@ -1,735 +0,0 @@
1
- /**
2
- * Wire shapes of the voice and vault modules. Spellings are the API's
3
- * (snake_case), so a response can be handed through untouched.
4
- * `@agent-cards/voice` keeps a structurally identical copy for the phone;
5
- * `PausedRequest` is the checkout client's own.
6
- */
7
- import type { PausedRequest } from './client.js';
8
- import type { Substitutions } from './substitute.js';
9
- import type { Language } from './languages.js';
10
- export type { Language } from './languages.js';
11
- /** @deprecated A language is a BCP 47 tag (`Language`); this name stays for one release. */
12
- export type Lang = Language;
13
- /**
14
- * How the Vault treats voice set-up on a connect link: `required` makes it a
15
- * step the person cannot skip; `offered` shows it and lets them pass. An app
16
- * that approves purchases by voice asks for `required`.
17
- */
18
- export type VoiceAsk = 'required' | 'offered';
19
- /**
20
- * How purchases are approved inside your product, chosen once per customer.
21
- * `sheet`: the person approves on Agentcard's own page,
22
- * opened in the in-app browser for one moment, with a credential Agentcard
23
- * verifies (the voice key or the passkey); a browser your app cannot script or
24
- * read. `in_app`: hold-to-talk in your app, judged on the phone and by
25
- * Agentcard, signed by a key in your app (`VoiceHost` in
26
- * `@agent-cards/voice`). Named in the server constructor; no default.
27
- */
28
- export type ApprovalPosture = 'sheet' | 'in_app';
29
- /**
30
- * One structured action the app's bot drafted from what the person said.
31
- * Agentcard takes the numbers, never the words: its voice reads the action
32
- * back in full, the person confirms it with the secure passphrase and the
33
- * one-time key word, and the endpoint that already exists for it runs.
34
- * `amount` is an integer in the currency's smallest unit (2000 for $20).
35
- */
36
- export type Action = {
37
- kind: 'rule.on';
38
- amount: number;
39
- days: number;
40
- } | {
41
- kind: 'rule.off';
42
- } | {
43
- kind: 'rule.change';
44
- amount: number;
45
- days: number;
46
- };
47
- /**
48
- * What a business asks to be allowed on a connect link, in the shape of OAuth's
49
- * `authorization_details` (RFC 9396): the card, the voice, the rule. Stored at
50
- * mint and enforced from then on: `agentcard_card` for the exchange's
51
- * connection credential, purchases and the card read; `rule` for action links;
52
- * each term also decides whether `card`, `voice` and `rule` are read back (a
53
- * term not asked for reads null at the API, `false` / `[]` here). The SDK asks
54
- * for all three unless you name fewer.
55
- */
56
- export type AuthorizationDetail = {
57
- type: 'agentcard_card' | 'voice' | 'rule';
58
- [key: string]: unknown;
59
- };
60
- export interface ConnectInput {
61
- /** `required` for an app that approves by voice; `offered` otherwise. */
62
- voice?: VoiceAsk;
63
- /**
64
- * The link is an OAuth authorization grant by default: the
65
- * client mints `state` and a PKCE challenge, the return link carries
66
- * `code` and `state`, and the result is collected once with `exchange` (or
67
- * `completeConnect`). `pkce: false` mints the older polling shape, read with
68
- * `awaitConnected`; deprecated, kept for one release. A call with no return
69
- * link (a messaging bot) polls whatever this says: there is no link to carry
70
- * the code.
71
- */
72
- pkce?: boolean;
73
- /**
74
- * The terms this link asks to be allowed (`[{ type: 'agentcard_card' }, { type: 'voice' }]`), enforced
75
- * from then on (see `AuthorizationDetail`). On a grant, absent means all three, sent explicitly.
76
- */
77
- authorization_details?: AuthorizationDetail[];
78
- /** Where the Vault sends the person back: an app link (`yourapp://connected`) or https. Must be exactly one of your registered redirect links; a prefix or a bare scheme is not registered. */
79
- return_url?: string;
80
- /** Your own id for the person; comes back on the linked session. */
81
- external_user_id?: string;
82
- /** Pre-fill the person's email on the sign-in step. */
83
- email?: string;
84
- /** The language your app speaks, a BCP 47 tag Agentcard lists (`voice.languages()`). The Vault opens in it and the voice key it sets up is the one for that language. */
85
- lang?: Language;
86
- /**
87
- * Where the signed-in person lands instead of the connect steps. `voice_options`: the Vault's Voice
88
- * options page (the voice key, its reset, the language, the passkey it rests on, the devices), for an
89
- * app's own settings row. Nothing is collected: the link polls (`grant: 'poll'`), and the person closes
90
- * the sheet when done; read `vault.people.get` afterwards for what changed.
91
- */
92
- landing?: 'voice_options';
93
- }
94
- export interface ConnectResult {
95
- /** Open this in the in-app browser sheet. */
96
- url: string;
97
- /** The session: `completeConnect` and `exchange` name it; with `grant: 'poll'`, `awaitConnected` polls it. */
98
- session_id: string;
99
- voice?: VoiceAsk;
100
- /** The customer's approval posture, as the server was constructed; the app half learns where the passphrase is spoken from here. Absent on a client built without `voice`. */
101
- approval?: ApprovalPosture;
102
- /**
103
- * How the result is collected. `exchange`: the return link carries `code`
104
- * and `state`; hand it to `completeConnect`, or its parts to `exchange`,
105
- * once, within 60 seconds. `poll`: read it with `awaitConnected`.
106
- */
107
- grant: 'exchange' | 'poll';
108
- /** The request handle Agentcard answers this link under (`areq_…`); on the webhooks too. */
109
- request_id: string | null;
110
- /** The opaque value the client minted; the return link carries it back and `exchange` checks it. */
111
- state?: string;
112
- /**
113
- * The PKCE verifier behind the challenge this link was minted with. The
114
- * client keeps it for `exchange`; it is here only so a server with several
115
- * instances can persist it and pass it back as `code_verifier` from the
116
- * instance the return link reaches. Never send it to the app.
117
- */
118
- code_verifier?: string;
119
- /** As asked at mint; echoed at exchange. */
120
- authorization_details?: AuthorizationDetail[] | null;
121
- }
122
- /**
123
- * The linked session: who connected and what the app may use. Each of `card`,
124
- * `voice` and `rule` is read only where the grant asked for its term
125
- * (`authorization_details`); a term not asked for reads `false` / `[]` here.
126
- */
127
- export interface Connected {
128
- user_id: string;
129
- /** A card is stored and this app may charge it. */
130
- card: boolean;
131
- /** Languages with a voice key (`['en']`); empty when none. */
132
- voice: string[];
133
- /** An auto-approval rule covers the card: purchases under it need no passphrase. */
134
- rule: boolean;
135
- /** A live Vault passkey on the account: what a voice reset needs. Read with the `voice` term. */
136
- passkey: boolean;
137
- /** Your own id for the person, as `connect` named it; null when it named none. */
138
- external_user_id?: string | null;
139
- /**
140
- * The link's diary: the last step the Vault's page reached (`opened`, `signed_in`, `voice_refused`,
141
- * `stopped`, `left`, `reset_done`, …) and the last reason it recorded (`rejected`, `no_voice_key`,
142
- * `skipped`, …), so a link that came back with `voice: []` says why. Null when the page reported none;
143
- * absent from an API older than the diary.
144
- */
145
- last_step?: VaultSessionStep | null;
146
- reason?: string | null;
147
- }
148
- /** What `exchange` (or `completeConnect`) returns: the connected person, plus the grant's own fields. */
149
- export interface Exchanged extends Connected {
150
- session_id: string;
151
- request_id: string | null;
152
- /** The `state` as minted, echoed by Agentcard. */
153
- state: string | null;
154
- authorization_details: AuthorizationDetail[] | null;
155
- /** The action the link carried, when it carried one (see `actions.propose`). */
156
- action: {
157
- kind: Action['kind'];
158
- confirmed: boolean;
159
- done: boolean;
160
- } | null;
161
- linked_at: string | null;
162
- /**
163
- * What the return link said about a voice reset, when it carried `voice_reset` (the Vault appends
164
- * `voice_reset=done|unchanged|failed` when the visit reset the person's voice key): `done`, the key was
165
- * cleared and set up again; `unchanged`, nothing was reset; `failed`, the reset did not go through. Only
166
- * `completeConnect` fills it, from the link; `exchange` with the parts in hand leaves it null.
167
- */
168
- voice_reset?: VoiceResetOutcome | null;
169
- /**
170
- * The grant's connection credential, when the grant asked for
171
- * `agentcard_card` and the ceremony verified the person's own contact; null
172
- * otherwise. Access-only: `refresh_token` is always null, it lives
173
- * `expires_in` seconds (an hour), and `scope` names the terms it is good for
174
- * (`vault_grant agentcard_card voice`). `disconnect` revokes it. Most
175
- * products need nothing from it: the client-credentials token already serves
176
- * every call in this module.
177
- */
178
- connection: {
179
- access_token: string;
180
- refresh_token: null;
181
- token_type: 'Bearer';
182
- expires_in: number;
183
- scope: string;
184
- } | null;
185
- }
186
- export interface ExchangeInput {
187
- /** From the return link. */
188
- code: string;
189
- /** From the return link; must equal the `state` the client minted for this session (or `expected_state`). */
190
- state?: string;
191
- /** The session `connect` returned; finds the verifier and the state the client holds. */
192
- session_id?: string;
193
- /** Only when another instance minted the link: the `code_verifier` that `connect` returned there. */
194
- code_verifier?: string;
195
- /**
196
- * Only when another instance minted the link: the `state` that `connect`
197
- * returned there, persisted beside the verifier. Compared with the link's
198
- * `state` here, before any call; without it a cross-instance exchange is
199
- * refused (`state_mismatch`).
200
- */
201
- expected_state?: string;
202
- }
203
- /** `disconnect`: the connection this session made is revoked. */
204
- export interface Revoked {
205
- session_id: string;
206
- revoked: boolean;
207
- revoked_at: string;
208
- /** Whether a token minted by the exchange was revoked with it. */
209
- token_revoked: boolean;
210
- }
211
- /**
212
- * A returning person, read before any link is minted: what they already have
213
- * with this business. Store `user_id` after the first `awaitConnected`; on a
214
- * later launch ask here, and open the Vault only for what is missing.
215
- */
216
- export interface Person {
217
- user_id: string;
218
- /** A card is stored and this app may charge it. */
219
- card: boolean;
220
- /** Languages with a voice key this app may use (`['en']`); empty when none. */
221
- voice: string[];
222
- /** An auto-approval rule covers the card: purchases under it need no passphrase. */
223
- rule: boolean;
224
- /**
225
- * A live Vault passkey on the account. A voice reset (`voice.reset`) needs one: with
226
- * `passkey: false` the Vault's reset page asks the person to add one first, so a bot can say so before
227
- * it opens the link. Read with the `voice` term.
228
- */
229
- passkey: boolean;
230
- /**
231
- * One of your own team: the person's Agentcard account email is a member's or an admin's of your organization.
232
- * The email itself is never returned.
233
- */
234
- team_member: boolean;
235
- }
236
- /** A proposed action: the Vault link, the session to await, and the hash the read-back is bound to. */
237
- export interface Proposed {
238
- url: string;
239
- session_id: string;
240
- /** sha256 of the action's canonical form: what Agentcard's voice reads back and what the key word challenge is bound to. */
241
- action_hash: string | null;
242
- }
243
- /** Where an action stands once the sheet closes. */
244
- export interface Done {
245
- /** The world agrees with the action (a rule is on for rule.on, none for rule.off). */
246
- done: boolean;
247
- /** The person's voice confirmed the action; the endpoint may still be running. */
248
- confirmed: boolean;
249
- /** A rule covers the card now. */
250
- rule: boolean;
251
- /**
252
- * The last step the Vault's page reached on the link: `opened`, `signed_in`, `challenge_minted`,
253
- * `voice_refused`, `confirmed`, `stopped`, `left`; null when the page never reported one (the link
254
- * was not opened). With `done: false`, where the handover ended.
255
- */
256
- last_step: VaultSessionStep | null;
257
- /**
258
- * The last reason the page recorded, a plain code: the judge's refusal (`rejected`, `need_more`,
259
- * `resting`, `cancelled`, `stale_challenge`, `verification_failed`), or why the page could go no
260
- * further (`no_voice_key`, `no_card`, `unavailable`, `already`, `none`, `no_rule`). Null when none.
261
- */
262
- reason: string | null;
263
- }
264
- /** One read of an action's link (`voice.actions.get`): where it stands, with no wait. */
265
- export interface ActionState extends Done {
266
- session_id: string;
267
- status: 'pending' | 'linked' | 'expired';
268
- /** The action the link carries, when the read says. */
269
- kind: Action['kind'] | string | null;
270
- }
271
- /** The steps a Vault link's page reports (`Done.last_step`). */
272
- export type VaultSessionStep = 'opened' | 'signed_in' | 'challenge_minted' | 'voice_refused' | 'confirmed' | 'stopped' | 'left' | 'reset_done';
273
- /** What a return link says about a voice reset made on the visit (`voice_reset=` on the link). */
274
- export type VoiceResetOutcome = 'done' | 'unchanged' | 'failed';
275
- /**
276
- * A return link, read: the grant's `code` and `state` (null on a link minted to poll: a reset, an action) and the
277
- * `voice_reset` outcome when the visit reset the person's voice key. `readReturnLink(url)` fills it, from the
278
- * query alone; the scheme may be an app's own (`yourapp://connected?code=…`).
279
- */
280
- export interface ReturnLink {
281
- code: string | null;
282
- state: string | null;
283
- voice_reset: VoiceResetOutcome | null;
284
- }
285
- /**
286
- * A Vault session as the business reads it (`voice.sessions.get`), without exchanging anything: where the
287
- * link stands, how its result is collected, and the diary. On a linked grant the connected result (`user_id`,
288
- * `card`, `voice`, `rule`, `passkey`, `action`) is withheld until `completeConnect`/`exchange` and reads null
289
- * here with `exchange_required: true`; on a polling mint it reads as `awaitConnected` would give it.
290
- */
291
- export interface SessionState {
292
- session_id: string;
293
- request_id: string | null;
294
- status: 'pending' | 'linked' | 'expired';
295
- /** `exchange`: the return link carries the code; `poll`: this read is the result. */
296
- grant: 'exchange' | 'poll';
297
- /** True on a linked grant this read did not disclose; hand the return link to `completeConnect`. */
298
- exchange_required: boolean;
299
- /** The diary: the last step the page reached and the last reason it recorded; null when none. */
300
- last_step: VaultSessionStep | null;
301
- reason: string | null;
302
- /** Your own id for the person, as the mint named it; null when it named none. */
303
- external_user_id: string | null;
304
- user_id: string | null;
305
- card: boolean | null;
306
- voice: string[] | null;
307
- rule: boolean | null;
308
- passkey: boolean | null;
309
- action: {
310
- kind: Action['kind'];
311
- confirmed: boolean;
312
- done: boolean;
313
- } | null;
314
- linked_at: string | null;
315
- expires_at: string | null;
316
- }
317
- export interface CreateAuthorizationInput {
318
- /** The person who approves: the `user_id` the connect exchange returned. Required, so a server serving many people never charges the wrong one. */
319
- user_id: string;
320
- merchant: string;
321
- /** An integer in the currency's smallest unit (599 for $5.99), the one word the checkout client's `authorizations.create` uses too. */
322
- amount: number;
323
- /** Lowercase ISO code, `usd`. */
324
- currency: string;
325
- /**
326
- * The processor's card request the purchase pauses on: one a browser purchase paused on, one
327
- * `checkout.requests.build` made, or `'sandbox'`, the first-run form that names no processor and that
328
- * only a sandbox client may send (`sandbox_request_in_live` otherwise).
329
- */
330
- request: PausedRequest | 'sandbox';
331
- /** The processor the request belongs to, as the recognisers name it (`stripe`, `braintree`, `mercado_pago`, …). Default `stripe`. */
332
- psp?: string;
333
- /** How the card reaches the processor. Absent means `token`; `cse` and `hosted_form` are checked against the recogniser by the API. */
334
- mode?: 'token' | 'cse' | 'hosted_form';
335
- /** Your own key for this create; the same key creates once. The SDK sends a fresh one when you name none. */
336
- idempotency_key?: string;
337
- /** The link the approval page sends the person back to, sent with the create and stored on the request; defaults to the client's `returnUrl`. Exactly one of your registered links. */
338
- return_url?: string;
339
- /**
340
- * The exact https origin your app or checkout page pays from (`https://yourapp.example`): what an
341
- * auto-approval rule the person confirmed needs to take the purchase. Agentcard stores no `origin` header
342
- * from the paused request, so without this a rule never applies and the create answers
343
- * `execution_reason: 'unverified_origin'`. Absent, the SDK sends the paused request's `origin` header when
344
- * it is such an origin (`stripePaymentIntentConfirm(origin, …)` sets one).
345
- */
346
- checkout_origin?: string;
347
- /**
348
- * Pins the card that pays: one of the person's stored cards (`voice.authorizations.get(id).cards`, or the
349
- * card list). Absent, the person's recommended card pays under their smart routing, else their only card,
350
- * and `card` on the answer says which (decision 213).
351
- */
352
- card_id?: string;
353
- }
354
- export type AuthorizationStatus = 'awaiting_approval' | 'approved' | 'declined' | 'expired' | 'cancelled' | 'completed' | 'timeout';
355
- /**
356
- * The business's own words for withdrawing a purchase it watches, while the person is still deciding: the person
357
- * closed the sheet, the person changed their mind, or a reason of the business's own. `voice.authorizations.cancel`
358
- * stamps one; it is the request's `terminal_reason` from then on.
359
- */
360
- export type CancelReason = 'person_closed_sheet' | 'person_changed_mind' | 'business_cancelled';
361
- /**
362
- * How the approval request ended, as CIBA names it. Null while it awaits the person. `cancelled` is the runtime's
363
- * withdrawal or a processor refusal; the three `CancelReason` words are the business's own withdrawal. A purchase
364
- * withdrawn before a decision reads `status: 'cancelled'` (since 2026-09-25); its terminal reason says who withdrew it.
365
- */
366
- export type TerminalReason = 'approved' | 'declined_by_person' | 'expired' | 'refused_by_rule' | 'approval_changed' | 'cancelled' | CancelReason;
367
- /** What `voice.authorizations.cancel` answers: the purchase is withdrawn, and how the request reads from now on. */
368
- export interface Cancelled {
369
- id: string;
370
- status: 'cancelled';
371
- /** The reason as stamped; `terminal_reason` is the same word on every later read and on the `checkout_authorization.cancelled` webhook. */
372
- reason: CancelReason;
373
- terminal_reason: TerminalReason;
374
- request_id: string | null;
375
- }
376
- /** Where the approval reached the person: the approval link, the app's sheet, the app-held approval, or (reserved) a push. */
377
- export type DeliveryChannel = 'app_sheet' | 'in_app' | 'link' | 'push';
378
- /** One piece of what approved the request: its kind, when, and an internal id. Never the material itself. */
379
- export interface InteractionEvidence {
380
- type: 'voice_proof' | 'passkey_assertion' | 'rescoring' | 'rule' | 'platform_interaction';
381
- at: string;
382
- ref: string;
383
- }
384
- /** The portable rendering of what the person approves; the field names are Agentcard's, versioned beside it. */
385
- export interface Intent {
386
- who: string;
387
- what: string;
388
- how_much: {
389
- amount: number | null;
390
- currency: string | null;
391
- };
392
- for_whom: string | null;
393
- until: string;
394
- request_hash: string;
395
- nonce: string;
396
- version: string;
397
- }
398
- /** The approval request's fields, on the create and on every read. */
399
- export interface ApprovalRequestFields {
400
- /** The request handle (`areq_…`); the webhooks carry it too. */
401
- request_id?: string | null;
402
- /** Your own id for the person, as the connect named it; on every event for them too. */
403
- external_user_id?: string | null;
404
- /** Seconds between two reads; `awaitResult` polls no faster. */
405
- interval?: number;
406
- /** The same interval in milliseconds, exactly as the request was configured. */
407
- poll_interval_ms?: number;
408
- /** The canonical hash the voice proof binds: the authorization's id, merchant, amount and currency with the intent's request hash, nonce and version. */
409
- intent_hash?: string | null;
410
- expires_at?: string;
411
- delivery_channel?: DeliveryChannel | null;
412
- /** How the request ended; null while it awaits the person. */
413
- terminal_reason?: TerminalReason | null;
414
- /** What approved it, typed and capped at eight entries. */
415
- interaction_evidence?: InteractionEvidence[];
416
- /** The portable rendering of what the person approves; null on rows written before it existed. */
417
- intent?: Intent | null;
418
- intent_version?: string | null;
419
- }
420
- export interface Authorization extends ApprovalRequestFields {
421
- id: string;
422
- status: AuthorizationStatus;
423
- /** `user_approval`: the person approves, by voice here. `autopilot`: the person's rule took it, no approval step. */
424
- execution_mode?: 'user_approval' | 'autopilot' | string;
425
- /**
426
- * Why no rule took the purchase when the business could mend it: `unverified_origin`, the create named no
427
- * `checkout_origin`. `execution_detail` says so in a sentence. Absent otherwise.
428
- */
429
- execution_reason?: 'unverified_origin' | string;
430
- execution_detail?: string;
431
- /**
432
- * The purchase's own approval page on the Vault, while it awaits a person.
433
- * It offers whichever doors the device has: voice, Face ID, Touch ID, the
434
- * master password. Open it in the sheet (`approve` from the app half), or
435
- * send it to a person with no microphone or no screen in front of your bot.
436
- * The link is id-only; where the page sends the person afterwards is the
437
- * `return_url` stored on the request (`return_url` on the create, or the
438
- * client's `returnUrl`), which the page reads from Agentcard, never from
439
- * the link.
440
- */
441
- approval_url?: string;
442
- /** The registered link the approval page ends on, as stored on the request. */
443
- return_url?: string;
444
- /**
445
- * The card that pays (decision 213): the one your create pinned, else the person's recommended card under
446
- * their smart routing, else their only card; null when several could pay and none is chosen yet. Absent from
447
- * an API older than the field.
448
- */
449
- card?: PayingCard | null;
450
- /** Every card the person may pay with instead, while the purchase awaits a decision; `authorizations.setCard` picks one. */
451
- cards?: ChoosableCard[];
452
- }
453
- /** A voice-only link: the Vault runs voice set-up alone; with `reset`, it forgets the device key and revokes the enrolment first. */
454
- export interface VoiceResetInput {
455
- return_url?: string;
456
- /** The language your app speaks; the Vault opens in it (see `ConnectInput.lang`). */
457
- lang?: Language;
458
- }
459
- /**
460
- * The card a purchase pays with, as every read and every key word challenge names it (decision 213). Under the
461
- * person's smart routing the recommended card pays when your app pinned none, and `reason` is the
462
- * recommendation's sentence for it ("American Express Gold: 4x on food delivery, about $2.20 in points on
463
- * this order."); `reason` is null when your app pinned the card or the person chose another. Null when the
464
- * person has several cards and none is chosen yet.
465
- */
466
- export interface PayingCard {
467
- id: string;
468
- /** How the card is named on screen and out loud: its product, else its label, else "Visa ····4242". */
469
- name: string;
470
- last4: string | null;
471
- brand: string | null;
472
- reason: string | null;
473
- }
474
- /**
475
- * One of the cards the person may pay with instead, for "another card": the recommendation's reason where it
476
- * scored the card, whether it is the recommended one, and whether an auto-approval rule on it pays without
477
- * asking. `voice.authorizations.setCard(id, card.id)` makes it the paying card.
478
- */
479
- export interface ChoosableCard extends PayingCard {
480
- recommended: boolean;
481
- auto_approve?: boolean;
482
- }
483
- /**
484
- * The key word challenge as `voice.challenge` returns it, every field typed. `word`, `say` and `say_private`
485
- * are what the bot says and shows; `challenge` and `intent` are what the app's hosted frame signs its proof
486
- * over; `verifier_url` and `answer_token` are where and with what the phone streams the answer. The four host
487
- * fields are typed as the API returns them and read as optional until the API release that mints them;
488
- * `challengeForHost` refuses a challenge that lacks the nonce or the intent.
489
- */
490
- export interface VoiceChallenge {
491
- id: string;
492
- /** The purchase this key word belongs to; set by `voice.challenge`, so the challenge alone can open a stream. */
493
- authorization_id?: string;
494
- /** The one-time key word the person says after their secure passphrase. */
495
- word: string;
496
- /** The language the challenge was minted in, as asked. */
497
- lang?: Language;
498
- /** The sentence your bot says, by language tag, with the key word in it: for a person wearing headphones. */
499
- say: Record<Language, string>;
500
- /**
501
- * The same sentence without the word, pointing at the screen: for a phone playing through its speaker, or
502
- * a route the app cannot read. Show the word on the screen in every case; the route decides only which of
503
- * the two lines is spoken. Absent from an API older than this field.
504
- */
505
- say_private?: Record<Language, string>;
506
- /**
507
- * The card that pays, with the recommendation's reason when it picked it (decision 213). Both lines name it
508
- * before the key word: hearing the card and the reason, then speaking the passphrase, is the confirmation.
509
- * Null when no card is known yet; absent from an API older than the field.
510
- */
511
- card?: PayingCard | null;
512
- /** Agentcard's own voice saying the line, when your organisation turned that on; `audio_delivery` says which form the link carries. */
513
- audio_url?: string;
514
- audio_delivery?: 'spoken' | 'screen';
515
- /**
516
- * The nonce the app's hosted frame signs its proof over. Present on every challenge the API mints;
517
- * `VoiceHost.approve` needs it.
518
- */
519
- challenge?: string;
520
- /** The payment's canonical hash and its kind, signed with the nonce. */
521
- intent?: {
522
- kind: string;
523
- hash: string;
524
- };
525
- /**
526
- * The verifier's address for this answer: the phone streams there itself, and a business hosts no door.
527
- * Absent from an API older than the field; the app half then needs the deprecated `stream_url`.
528
- */
529
- verifier_url?: string;
530
- /**
531
- * A short-lived credential scoped to this one challenge, for the verifier's stream. The app hands it on the
532
- * first frame and never carries your bearer. Absent from an API older than the field.
533
- */
534
- answer_token?: string;
535
- /**
536
- * The verifier's sealing key, P-256 SPKI as base64url (WP115): the hosted frame seals the take's audio to it and the
537
- * app relays ciphertext it cannot read. Absent from an API older than the field, or when the API could not read the
538
- * verifier; the frame then refuses the take and the app takes the approval page.
539
- */
540
- verifier_public_key?: string;
541
- /**
542
- * The authorization's price in the currency's smallest unit (3999 for $39.99) and its ISO code, lower case, for
543
- * the app's screen. Nobody says it: the approval is the passphrase and the key word (2026-10-01, reversing
544
- * decision 245). Absent from an API older than the fields, or on a template that carries no amount.
545
- */
546
- amount_minor?: number;
547
- currency?: string;
548
- expires_at: string;
549
- }
550
- /**
551
- * What the business forwards to the app, unread, for `VoiceHost.approve`: one sealed object from
552
- * `voice.challengeForHost`, so a business cannot assemble it wrong. The frame signs over `challenge` and
553
- * `intent`; the phone streams to `verifier_url` with `answer_token` when the API minted them.
554
- */
555
- export interface HostApprovalBundle {
556
- /** The challenge's own id (`vch_…`): named on the stream's first frame and on the frame's verdict. */
557
- challenge_id: string;
558
- authorization_id: string;
559
- word: string;
560
- /** The language the challenge was minted in. */
561
- lang?: Language;
562
- say: Record<Language, string>;
563
- say_private?: Record<Language, string>;
564
- /** The card that pays and why, as the lines say it (decision 213); the app shows it beside the word. */
565
- card?: PayingCard | null;
566
- audio_url?: string;
567
- audio_delivery?: 'spoken' | 'screen';
568
- /** The nonce the hosted frame signs over. */
569
- challenge: string;
570
- intent: {
571
- kind: string;
572
- hash: string;
573
- };
574
- /** Where the phone streams; absent until the API release that mints it. */
575
- verifier_url?: string;
576
- /** The credential for that stream; absent until the API release that mints it. */
577
- answer_token?: string;
578
- /** The verifier's sealing key the frame seals the audio to (WP115); absent until the API release that carries it. */
579
- verifier_public_key?: string;
580
- /** The authorization's price for the app's screen, smallest unit and ISO code; nobody says it (2026-10-01, reversing decision 245); absent until the API release that carries them. */
581
- amount_minor?: number;
582
- currency?: string;
583
- expires_at: string;
584
- }
585
- /** What the frame says its app voice key is, relayed by `VoiceHost` for `voice.appKeys.register`. */
586
- export interface AppVoiceKeyDescription {
587
- credential_id: string;
588
- /** The signing half, P-256 SPKI as base64url. The agreement half the app copy is sealed for is never registered here (WP115): the person's vault proves it during the set-up inside the app. */
589
- public_key: string;
590
- kind: 'app_voice_key';
591
- alg: 'ES256';
592
- proof_version: 1;
593
- lang?: Language;
594
- device_label?: string;
595
- /**
596
- * The phone's hardware key, attested for this app voice key (WP199): `VoiceHost` 1.9.8 puts it on the description it
597
- * hands your `register` when the phone attested one, and `voice.appKeys.register` sends it on as `hardware`. Absent
598
- * from a phone that registered a software key.
599
- */
600
- hardware?: HardwareAttestation;
601
- }
602
- /**
603
- * The hardware key the phone binds to its app voice key at registration (WP199): the key's id, the platform's
604
- * attestation of it (Android's certificate chain as base64url DER, one string a certificate, or iOS App Attest's
605
- * attestation object as one base64url string), the challenge the attestation answers (`SHA-256(credential_id + "." +
606
- * public_key)`, as the phone computed it; Agentcard recomputes and compares), and on iOS the App ID the build runs
607
- * under (`<team id>.<bundle id>`), which Agentcard checks the attestation's `rpIdHash` against. Opaque to the SDK: it
608
- * is sent as `hardware` on the registration and Agentcard checks it.
609
- */
610
- export interface HardwareAttestation {
611
- platform: 'android' | 'ios';
612
- key_id: string;
613
- attestation: string[] | string;
614
- challenge: string;
615
- app_id?: string;
616
- }
617
- /** The registered app voice key, with the phone's scoped credential (one hour; register again for a fresh one). */
618
- export interface RegisteredAppVoiceKey {
619
- id: string;
620
- credential_id: string;
621
- kind: 'app_voice_key';
622
- alg: 'ES256';
623
- proof_version: 1;
624
- lang?: string;
625
- device_label?: string;
626
- created_at: string;
627
- revoked: boolean;
628
- /** The phone's bearer for its two calls (the sealed copy and the proof). Hand it to `VoiceHost`'s `register`; nothing else goes to the phone. */
629
- credential: {
630
- token: string;
631
- token_type: 'Bearer';
632
- expires_in: number;
633
- };
634
- /** Whether Agentcard verified a hardware key bound to this app voice key (WP199); absent from an API from before it. */
635
- hardware_proven?: boolean;
636
- /** Where the proven hardware key lives: Android StrongBox or TEE, or Apple's Secure Enclave. */
637
- hardware_level?: 'strongbox' | 'tee' | 'secure_enclave';
638
- /** Which hardware key is proven, by its id, so the phone compares it with the key it holds (WP199). Present only when proven. */
639
- hardware_key_id?: string;
640
- }
641
- /** `voice.appKeys.revoke`: the key is revoked and nothing else is. */
642
- export interface RevokedAppVoiceKey {
643
- id: string;
644
- revoked: boolean;
645
- revoked_at: string | null;
646
- }
647
- /**
648
- * Whether the charge settled, read back from the processor by Agentcard itself after the purchase finished: the
649
- * same object the `checkout_authorization.approved` webhook carries at finish and the `settled` /
650
- * `settlement_unconfirmed` webhook carries once the read lands. `status` is `settled` (the processor holds a
651
- * succeeded payment), `not_settled` (no charge was made: `reason` says why), or `unknown` (`reason` names what
652
- * was seen last, `check_pending` while Agentcard is still reading). `final: false` means one of the two
653
- * settlement webhooks follows; `true` means Agentcard will not check again. `settled_amount` and
654
- * `settled_currency` are what the processor reports collected, in the currency's smallest unit; `message` is
655
- * the answer in one sentence.
656
- */
657
- export interface Settlement {
658
- status: 'settled' | 'not_settled' | 'unknown';
659
- reason: string;
660
- final: boolean;
661
- processor_reference: string | null;
662
- processor_status: string | null;
663
- processor_error_code: string | null;
664
- settled_amount: number | null;
665
- settled_currency: string | null;
666
- checked_at: string | null;
667
- resolved_at: string | null;
668
- message: string;
669
- }
670
- export interface AuthorizationResult extends ApprovalRequestFields {
671
- /** The purchase's id (`cauth_…`), as read; absent only on `timeout`, which is the SDK's own answer. */
672
- id?: string;
673
- /**
674
- * `approved`, `declined` (the person said no: `terminal_reason: 'declined_by_person'`, or a rule or the
675
- * processor refused), `cancelled` (withdrawn before a decision: the business's `voice.authorizations.cancel`
676
- * with its `CancelReason` as `terminal_reason`, or the runtime's `cancelled`), `expired`, or `timeout` at the
677
- * deadline. `cancelled` is the API's own status for a withdrawn purchase (since 2026-09-25); the SDK reads it as
678
- * the API says it.
679
- */
680
- status: AuthorizationStatus;
681
- /** The purchase's approval page while it awaits a person (see `Authorization.approval_url`); absent otherwise. */
682
- approval_url?: string;
683
- /**
684
- * Whether the charge settled, on a finished purchase: present on `approved` (and on an `expired` purchase a
685
- * device may have paid), `null` when there is nothing to read back (the request tokenized a card the merchant
686
- * charges itself), absent while the purchase is open or on `timeout`. `final: false` means the
687
- * `checkout_authorization.settled` or `settlement_unconfirmed` webhook follows; read the purchase again later
688
- * for the answer without waiting on it.
689
- */
690
- settlement?: Settlement | null;
691
- /** `voice` after a challenge; `passkey` or `bearer` otherwise; empty when a rule took the purchase. */
692
- approved_with?: 'voice' | 'passkey' | 'bearer' | string;
693
- execution_mode?: 'user_approval' | 'autopilot' | string;
694
- /** Why no rule took it, when the business can mend that (`unverified_origin`); see `Authorization`. */
695
- execution_reason?: 'unverified_origin' | string;
696
- execution_detail?: string;
697
- /**
698
- * How the card reached the processor (`token`, `cse`, `hosted_form`), and the processor's answer on an
699
- * approved `token` purchase: what `controller.resume(result)` replays into a browser purchase that
700
- * `attachToCdp(…, { pauseOnly: true })` paused. `substitutions` is the ciphertext of a `cse`
701
- * purchase, `submitted_at` the device's stamp on a `hosted_form` one. Absent while the purchase is open.
702
- */
703
- mode?: 'token' | 'cse' | 'hosted_form' | string;
704
- response?: {
705
- status: number;
706
- headers: Record<string, string>;
707
- body: string;
708
- };
709
- substitutions?: Substitutions;
710
- submitted_at?: string;
711
- /** The card that pays, or paid (decision 213); see `Authorization.card`. */
712
- card?: PayingCard | null;
713
- /** Every card the person may pay with instead, while the purchase awaits a decision; absent once it is decided. */
714
- cards?: ChoosableCard[];
715
- }
716
- /** The verifier's answer to one recording. */
717
- export interface Verdict {
718
- /** The passphrase, the key word and the voice all held: the purchase is approved. */
719
- accepted: boolean;
720
- /** The challenge is used up; ask for a fresh key word before the next try. False when nothing was heard. */
721
- spent: boolean;
722
- approved_with: string | null;
723
- }
724
- export declare class AgentcardError extends Error {
725
- /** The API's error code (`invalid_return_url`, `action_unavailable`, `voice_not_enrolled`, `slow_down`, `invalid_grant`), or the client's own (`unreachable`, `connect_timeout`, `oauth_failed`, `state_mismatch`). */
726
- readonly code: string;
727
- readonly status?: number | undefined;
728
- /** The rest of the API's error envelope: `slow_down` carries `interval`, `grant_requires_exchange` carries `request_id`. */
729
- readonly details: Record<string, unknown>;
730
- constructor(
731
- /** The API's error code (`invalid_return_url`, `action_unavailable`, `voice_not_enrolled`, `slow_down`, `invalid_grant`), or the client's own (`unreachable`, `connect_timeout`, `oauth_failed`, `state_mismatch`). */
732
- code: string, message: string, status?: number | undefined,
733
- /** The rest of the API's error envelope: `slow_down` carries `interval`, `grant_requires_exchange` carries `request_id`. */
734
- details?: Record<string, unknown>);
735
- }