@codespar/sdk 0.16.6 → 0.16.8

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.
@@ -45,6 +45,70 @@ export interface paths {
45
45
  patch?: never;
46
46
  trace?: never;
47
47
  };
48
+ "/.well-known/codespar-receipt-keys.json": {
49
+ parameters: {
50
+ query?: never;
51
+ header?: never;
52
+ path?: never;
53
+ cookie?: never;
54
+ };
55
+ /**
56
+ * Receipt verification keys (JWKS)
57
+ * @description The public half of the key that signs agentic receipts, so a party with no CodeSpar credential can check one. An agentic receipt carries two seals: `receipt_sig`, an HMAC under the consumer's own secret, which proves the payment to whoever holds that secret and to nobody else; and `receipt_sig_ed25519`, made with the key published here.
58
+ *
59
+ * To verify: take `receipt_sig_kid` from the receipt, find the key with that `kid` below, build `codespar-receipt:v1:<receipt_id>:<chain>` and check the base64url signature over those UTF-8 bytes with any Ed25519 verifier. `x` is the raw 32-byte public key, base64url (RFC 8037).
60
+ *
61
+ * Keys ROTATE and a retired key stays listed — that is what keeps an old receipt verifiable. A revoked key is removed entirely: its private half is assumed compromised, so signatures it made are worth nothing. An empty `keys` means this deployment publishes none, which is consistent with its receipts carrying a null `receipt_sig_kid`.
62
+ *
63
+ * Every `kid` names the DEPLOYMENT that minted it — `<did>#<namespace>-<n>`, and `key_namespace` repeats the namespace this document serves. A `receipt_sig_kid` that is ABSENT here therefore means the receipt came from another environment (a sandbox receipt checked against production, most often), which is `unknown_key` and NOT a tampered receipt. Before ent#1641 the id was `<did>#<n>` in every environment, so receipts sealed then carry an id that more than one document may claim; they keep verifying against the document of the environment that issued them and nowhere else.
64
+ */
65
+ get: {
66
+ parameters: {
67
+ query?: never;
68
+ header?: never;
69
+ path?: never;
70
+ cookie?: never;
71
+ };
72
+ requestBody?: never;
73
+ responses: {
74
+ /** @description OK */
75
+ 200: {
76
+ headers: {
77
+ [name: string]: unknown;
78
+ };
79
+ content: {
80
+ "application/json": {
81
+ issuer: string;
82
+ /** @description The deployment whose keys this document serves, and the namespace every `kid` below carries. A kid from another namespace is unknown here, not forged. */
83
+ key_namespace: string;
84
+ algorithm: string;
85
+ /** @description The template of the bytes a signature covers, stated so a verifier needs nothing else from us. */
86
+ signing_string: string;
87
+ keys: {
88
+ kid: string;
89
+ kty: string;
90
+ crv: string;
91
+ x: string;
92
+ alg: string;
93
+ use: string;
94
+ /** @description `active` or `retired`. A retired key signs nothing new. */
95
+ status: string;
96
+ created_at: string;
97
+ retired_at: string | null;
98
+ }[];
99
+ };
100
+ };
101
+ };
102
+ };
103
+ };
104
+ put?: never;
105
+ post?: never;
106
+ delete?: never;
107
+ options?: never;
108
+ head?: never;
109
+ patch?: never;
110
+ trace?: never;
111
+ };
48
112
  "/.well-known/oauth-authorization-server": {
49
113
  parameters: {
50
114
  query?: never;
@@ -1388,6 +1452,7 @@ export interface paths {
1388
1452
  content: {
1389
1453
  "application/json": {
1390
1454
  name: string;
1455
+ /** @description The event type to subscribe to. Matching is EXACT string equality — there is no prefix and no wildcard, so `commerce.payment.succeeded` does not receive `commerce.payment.received`. A name outside the list below is accepted and recorded (`trigger.event_unknown`) rather than refused, so you can subscribe ahead of a release; until something emits it the subscription simply never fires. What this build emits: approval.decided, approval.pending, commerce.account_launch_in.received, commerce.account_launch_out.received, commerce.account_status.changed, commerce.cashout.confirmed, commerce.charge.cancelled, commerce.charge.created, commerce.charge.expired, commerce.charge.expiry_notified, commerce.charge.paid, commerce.charge.payment_notified, commerce.dict_claim.cancelled, commerce.dict_claim.completed, commerce.dict_claim.confirmed, commerce.dict_claim.opened, commerce.dict_claim.waiting, commerce.internal_transfer_in.received, commerce.internal_transfer_out.received, commerce.mandate.granted, commerce.mandate.paused, commerce.mandate.resumed, commerce.mandate.revoked, commerce.onboarding.backgroundcheck_approved, commerce.onboarding.backgroundcheck_pending, commerce.onboarding.backgroundcheck_rejected, commerce.onboarding.documentscopy_approved, commerce.onboarding.documentscopy_pending, commerce.onboarding.documentscopy_processing, commerce.onboarding.documentscopy_rejected, commerce.onboarding.proposal_approved, commerce.onboarding.proposal_processing_documentscopy, commerce.onboarding.proposal_rejected, commerce.organization.paused, commerce.organization.resumed, commerce.payment.failed, commerce.payment.pending, commerce.payment.received, commerce.payment.refunded, commerce.payment.succeeded, commerce.payment.updated, commerce.pix_out.failed, commerce.pix_out.succeeded, commerce.pix_out.unconfirmed, commerce.pix_reversal_in.received, commerce.pix_reversal_out.received, commerce.rinne.observed, commerce.spend.failed, commerce.spend.settled, commerce.ted_in.succeeded, dda.boleto.registered, dda.subscription.activated, dda.subscription.failed, proxy_call.failed, proxy_call.succeeded, session.closed, system.health.degraded, system.health.recovered, tool_call.failed, tool_call.succeeded, trigger.paused_automatically, trigger.test_fire, user.signed_up. */
1391
1456
  event: string;
1392
1457
  server_id?: string;
1393
1458
  /** Format: uri */
@@ -1505,6 +1570,7 @@ export interface paths {
1505
1570
  content: {
1506
1571
  "application/json": {
1507
1572
  name: string;
1573
+ /** @description The event type to subscribe to. Matching is EXACT string equality — there is no prefix and no wildcard, so `commerce.payment.succeeded` does not receive `commerce.payment.received`. A name outside the list below is accepted and recorded (`trigger.event_unknown`) rather than refused, so you can subscribe ahead of a release; until something emits it the subscription simply never fires. What this build emits: approval.decided, approval.pending, commerce.account_launch_in.received, commerce.account_launch_out.received, commerce.account_status.changed, commerce.cashout.confirmed, commerce.charge.cancelled, commerce.charge.created, commerce.charge.expired, commerce.charge.expiry_notified, commerce.charge.paid, commerce.charge.payment_notified, commerce.dict_claim.cancelled, commerce.dict_claim.completed, commerce.dict_claim.confirmed, commerce.dict_claim.opened, commerce.dict_claim.waiting, commerce.internal_transfer_in.received, commerce.internal_transfer_out.received, commerce.mandate.granted, commerce.mandate.paused, commerce.mandate.resumed, commerce.mandate.revoked, commerce.onboarding.backgroundcheck_approved, commerce.onboarding.backgroundcheck_pending, commerce.onboarding.backgroundcheck_rejected, commerce.onboarding.documentscopy_approved, commerce.onboarding.documentscopy_pending, commerce.onboarding.documentscopy_processing, commerce.onboarding.documentscopy_rejected, commerce.onboarding.proposal_approved, commerce.onboarding.proposal_processing_documentscopy, commerce.onboarding.proposal_rejected, commerce.organization.paused, commerce.organization.resumed, commerce.payment.failed, commerce.payment.pending, commerce.payment.received, commerce.payment.refunded, commerce.payment.succeeded, commerce.payment.updated, commerce.pix_out.failed, commerce.pix_out.succeeded, commerce.pix_out.unconfirmed, commerce.pix_reversal_in.received, commerce.pix_reversal_out.received, commerce.rinne.observed, commerce.spend.failed, commerce.spend.settled, commerce.ted_in.succeeded, dda.boleto.registered, dda.subscription.activated, dda.subscription.failed, proxy_call.failed, proxy_call.succeeded, session.closed, system.health.degraded, system.health.recovered, tool_call.failed, tool_call.succeeded, trigger.paused_automatically, trigger.test_fire, user.signed_up. */
1508
1574
  event: string;
1509
1575
  server_id?: string;
1510
1576
  /** Format: uri */
@@ -4241,6 +4307,165 @@ export interface paths {
4241
4307
  patch?: never;
4242
4308
  trace?: never;
4243
4309
  };
4310
+ "/v1/audit-events/verify": {
4311
+ parameters: {
4312
+ query?: never;
4313
+ header?: never;
4314
+ path?: never;
4315
+ cookie?: never;
4316
+ };
4317
+ get?: never;
4318
+ put?: never;
4319
+ /**
4320
+ * Verify the chain over an interval
4321
+ * @description Walks your chain across the interval and answers with a verdict: `verified`, `broken` with the first violated sequence, or `unverified` when a stretch of it could not be checked at all.
4322
+ *
4323
+ * Before this existed a client had to COMPOSE that answer — list the interval, read `watermark_sequence` off `/v1/audit-events/health`, and call the interval verified when every sequence sat at or below it. The deduction is sound and conservative, and it is still the client asserting something this server never said. This operation says it. It runs the same walk as the background verifier: the same link check, the same hash recompute, the same tombstone-witness rule, over the same rows.
4324
+ *
4325
+ * `unverified` is NOT a weaker `verified` and NOT a `broken`. It means part of the interval has no verifiable link — rows are missing, or the first row has no predecessor to measure against — so nothing here certifies that stretch either way. `unverified_segments` names them, capped at 20 entries while `unverified_segment_count` stays the true total.
4326
+ *
4327
+ * THE INTERVAL IS STATED IN TIME AND THE CHAIN IS ORDERED BY SEQUENCE. `from`/`to` select rows by `happened_at`; the walk then covers the contiguous sequence span those rows occupy, reported as `sequence_range`, because a link can only be checked against the row immediately before it. That span can hold more rows than the window does, which is why `events_walked` is reported next to `events_in_interval`.
4328
+ *
4329
+ * BOUNDED BY ROWS, not by days: at most 50,000 rows in the span, or the request is refused with 413 `interval_too_large` and the count, so you can split it. A day count would bound nothing — `happened_at` is written by whoever appended the event, so an hour-wide window can hold an entire chain.
4330
+ *
4331
+ * Unlike `GET /v1/audit-events/health`, this read has NO side effects. It opens no incident, records no unverifiable segment and moves no watermark; poll it as often as you like.
4332
+ */
4333
+ post: {
4334
+ parameters: {
4335
+ query?: never;
4336
+ header?: never;
4337
+ path?: never;
4338
+ cookie?: never;
4339
+ };
4340
+ requestBody?: {
4341
+ content: {
4342
+ "application/json": {
4343
+ /** @description Start of the interval, inclusive. ISO 8601, read against `happened_at`. */
4344
+ from: string;
4345
+ /** @description End of the interval, inclusive. ISO 8601, read against `happened_at`. */
4346
+ to: string;
4347
+ };
4348
+ };
4349
+ };
4350
+ responses: {
4351
+ /** @description OK */
4352
+ 200: {
4353
+ headers: {
4354
+ [name: string]: unknown;
4355
+ };
4356
+ content: {
4357
+ "application/json": {
4358
+ /**
4359
+ * @description `verified` — every row in the span linked to the one before it and hashed to its stored `entry_hash`. `broken` — a row was caught lying, named by `first_violation`. `unverified` — nothing was caught, and part of the span has no verifiable link, so it is certified neither way.
4360
+ * @enum {string}
4361
+ */
4362
+ status: "verified" | "unverified" | "broken";
4363
+ interval: {
4364
+ /** Format: date-time */
4365
+ from: string;
4366
+ /** Format: date-time */
4367
+ to: string;
4368
+ };
4369
+ /** @description The contiguous sequence span the interval's rows occupy, and what was walked. */
4370
+ sequence_range: {
4371
+ from: number;
4372
+ to: number;
4373
+ };
4374
+ /** @description Rows whose `happened_at` falls inside the interval. */
4375
+ events_in_interval: number;
4376
+ /** @description Rows inside `sequence_range`. At least `events_in_interval`, and larger when rows written with a `happened_at` outside the window sit between them. */
4377
+ events_walked: number;
4378
+ /** @description Rows that passed both checks. Below `events_walked` when the walk stopped at a break. */
4379
+ events_verified: number;
4380
+ /** @description The last sequence that verified. null when the very first row of the span did not, which is also the shape of a break at `sequence_range.from`. */
4381
+ verified_through_sequence: number | null;
4382
+ /** @description The FIRST violated sequence. The walk stops there; later rows are not reported. */
4383
+ first_violation: {
4384
+ sequence_number: number;
4385
+ /**
4386
+ * @description Which check fired. `chain_link_break_detected` — this row's `prev_hash` does not match the previous row's `entry_hash`, which is the only cross-row binding there is. `chain_integrity_break_detected` — the row's own fields no longer hash to its stored `entry_hash`. `tombstone_witness_missing` — an anonymized row with no live witness vouching for it, which would otherwise buy silence for free.
4387
+ * @enum {string}
4388
+ */
4389
+ check: "chain_link_break_detected" | "chain_integrity_break_detected" | "tombstone_witness_missing";
4390
+ detail: string;
4391
+ } | null;
4392
+ /** @description A sample, capped at 20. `unverified_segment_count` is the total. */
4393
+ unverified_segments: {
4394
+ /** @description Last sequence verified before the hole; 0 when there was no anchor at all. */
4395
+ from_sequence: number;
4396
+ /** @description First sequence observed after the hole. */
4397
+ to_sequence: number;
4398
+ /** @enum {string} */
4399
+ reason: "sequence_gap" | "no_anchor";
4400
+ detail: string;
4401
+ }[];
4402
+ unverified_segment_count: number;
4403
+ /**
4404
+ * Format: date-time
4405
+ * @description When this walk ran. The verdict is about the rows as they stood then.
4406
+ */
4407
+ checked_at: string;
4408
+ };
4409
+ };
4410
+ };
4411
+ /** @description Bad Request. `invalid_body` when `from` or `to` is missing or not a string, `invalid_iso_8601` when either is not a date this server can parse, `from_after_to` when the interval is inverted. */
4412
+ 400: {
4413
+ headers: {
4414
+ [name: string]: unknown;
4415
+ };
4416
+ content: {
4417
+ "application/json": {
4418
+ /** @enum {string} */
4419
+ error: "invalid_body" | "invalid_iso_8601" | "from_after_to";
4420
+ };
4421
+ };
4422
+ };
4423
+ /** @description The sequence span covered by the interval holds more rows than one request will walk. Split the interval; `row_count` and `limit` say by how much. */
4424
+ 413: {
4425
+ headers: {
4426
+ [name: string]: unknown;
4427
+ };
4428
+ content: {
4429
+ "application/json": {
4430
+ /** @enum {string} */
4431
+ error: "interval_too_large";
4432
+ remediation: string;
4433
+ row_count: number;
4434
+ limit: number;
4435
+ sequence_range: {
4436
+ from: number;
4437
+ to: number;
4438
+ };
4439
+ };
4440
+ };
4441
+ };
4442
+ /** @description The interval holds no audit events, so there is no verdict to give. Deliberately NOT a `verified` 200: a walk over nothing trivially finds nothing wrong, and a clean verdict for a period the chain says nothing about is the one claim a proof bundle must not carry — a mistyped date and an intact month would read identically. */
4443
+ 422: {
4444
+ headers: {
4445
+ [name: string]: unknown;
4446
+ };
4447
+ content: {
4448
+ "application/json": {
4449
+ /** @enum {string} */
4450
+ error: "interval_empty";
4451
+ remediation: string;
4452
+ interval: {
4453
+ /** Format: date-time */
4454
+ from: string;
4455
+ /** Format: date-time */
4456
+ to: string;
4457
+ };
4458
+ };
4459
+ };
4460
+ };
4461
+ };
4462
+ };
4463
+ delete?: never;
4464
+ options?: never;
4465
+ head?: never;
4466
+ patch?: never;
4467
+ trace?: never;
4468
+ };
4244
4469
  "/v1/audit-events/incidents": {
4245
4470
  parameters: {
4246
4471
  query?: never;
@@ -9499,7 +9724,7 @@ export interface paths {
9499
9724
  * Read graded dependency health, as this credential's tenant sees it
9500
9725
  * @description Six dependency checks and the schema version, graded into one `status`. The checks run in parallel behind a three-second budget each; one that throws or times out is reported in its own failed shape with `message` carrying the reason, and the response still carries the other five. So the operation is expected back in under four seconds however badly the database is behaving.
9501
9726
  *
9502
- * GRADE ON `status`, AND READ THE RULE BEFORE WRITING THE ALERT, because the rule is narrower than "anything off nominal". `down` means `db.ok` or `vault.ok` is false. `degraded` means one of exactly four things: `embeddings.status` is `empty`, `fx_rates.status` is anything other than `fresh`, `telemetry.status` is `stale`, or `connections.status` is `none`. Everything else grades `healthy`.
9727
+ * GRADE ON `status`, AND READ THE RULE BEFORE WRITING THE ALERT, because the rule is narrower than "anything off nominal". `down` means `db.ok` or `vault.ok` is false. `degraded` means one of exactly four things: `embeddings.status` is `empty`, `fx_rates.status` is anything other than `usable`, `telemetry.status` is `stale`, or `connections.status` is `none`. Everything else grades `healthy`.
9503
9728
  *
9504
9729
  * THREE NON-NOMINAL VALUES DO NOT MOVE THE GRADE, and an alert that wants them has to read the field rather than the grade: `embeddings.status` `low` (fewer than half the tool rows carry an embedding), `connections.status` `partial` (one or two connections rather than three or more), and `telemetry.status` `idle` (a quiet hour that still had traffic inside the day). All three come back `healthy` at the top level, on purpose — none of them stops a call from being served.
9505
9730
  *
@@ -9526,7 +9751,7 @@ export interface paths {
9526
9751
  content: {
9527
9752
  "application/json": {
9528
9753
  /**
9529
- * @description `down` iff the database or the vault check failed. `degraded` iff embeddings are empty, FX is not fresh, telemetry is stale, or the tenant has no connection. `healthy` otherwise — which includes embeddings `low`, connections `partial` and telemetry `idle`.
9754
+ * @description `down` iff the database or the vault check failed. `degraded` iff embeddings are empty, the FX rate is not usable, telemetry is stale, or the tenant has no connection. `healthy` otherwise — which includes embeddings `low`, connections `partial` and telemetry `idle`.
9530
9755
  * @enum {string}
9531
9756
  */
9532
9757
  status: "healthy" | "degraded" | "down";
@@ -9562,16 +9787,16 @@ export interface paths {
9562
9787
  fx_rates: {
9563
9788
  /**
9564
9789
  * Format: date-time
9565
- * @description When the USD/BRL rate was last fetched. Null when no rate has ever been stored, and null when the check itself failed.
9790
+ * @description The market timestamp BCB stamped on the newest USD/BRL PTAX close we hold — NOT the time our fetcher last ran. BCB publishes Mon-Fri, so on a Monday this is routinely Friday. Null when no rate has ever been stored, and null when the check itself failed.
9566
9791
  */
9567
9792
  last_fetched_at: string | null;
9568
- /** @description Age of that fetch in hours, to one decimal. */
9793
+ /** @description Age of that close in hours, to one decimal. */
9569
9794
  hours_old: number | null;
9570
9795
  /**
9571
- * @description `stale` past 72 hours, which is the age at which the router stops normalizing across currencies. `missing` when there is no row, or when the check failed. Anything other than `fresh` grades the response `degraded`.
9796
+ * @description Whether the router will normalize on this rate, derived from `hours_old`: `usable` inside 72 hours, `stale` past it — which is the age at which the router stops normalizing across currencies. `missing` when there is no row, or when the check failed. Anything other than `usable` grades the response `degraded`. The value deliberately says nothing about recency: a `usable` rate can be three days old over a weekend, and nothing here reports whether the fetcher ran.
9572
9797
  * @enum {string}
9573
9798
  */
9574
- status: "fresh" | "stale" | "missing";
9799
+ status: "usable" | "stale" | "missing";
9575
9800
  /** @description Present only when the check failed or timed out. */
9576
9801
  message?: string;
9577
9802
  };
@@ -9668,6 +9893,12 @@ export interface paths {
9668
9893
  name: string;
9669
9894
  /** Format: date-time */
9670
9895
  created_at: string;
9896
+ /** @description Set while the organization's kill switch is pressed and every agent money door refuses `org_paused` (ent#1648); null otherwise. The full state, and pressing or releasing it, is `/v1/orgs/{orgId}/pause`. */
9897
+ spend_pause: {
9898
+ /** Format: date-time */
9899
+ paused_at: string | null;
9900
+ reason: string | null;
9901
+ } | null;
9671
9902
  };
9672
9903
  };
9673
9904
  };
@@ -14413,6 +14644,17 @@ export interface paths {
14413
14644
  * - `partner` — your server submits. `attestation` is REQUIRED (400 `attestation_required`): the IP and user-agent recorded are your server's, so the only statement about the human is yours. It is signed into the mandate as `consent_attestation` and cannot be edited afterwards without breaking the signature.
14414
14645
  *
14415
14646
  * `attestation.method` says how the human authorized: `partner_session` (an authenticated session in your product), `in_person`, `verified_code` (a code YOU issued and verified), or `partner_biometric` (YOU ran a biometric check at the moment of the act). `partner_biometric` is not a flavour of `partner_session`: in a dispute a session says someone was logged in and a biometric says a body was present. We capture and verify no biometric ourselves — this records what YOU assert, sealed by the mandate signature so it cannot be edited afterwards; the evidence behind it stays with you. `asserted_at` is the instant you say they authorized, in Unix seconds. `reference` is your own record id, `[A-Za-z0-9_-]{1,120}`, and never personal data — it is joined into the signed string, so the character set is the schema's, not a suggestion.
14647
+ *
14648
+ * `attestation.evidence` (optional) is what you OBSERVED of the act, signed with the rest of the mandate. `channel` is required and decides which other keys may be present, because a value a channel cannot expose was inferred, and an inferred value inside a signed record reads exactly like an observed one:
14649
+ *
14650
+ * - `whatsapp`, `sms`, `email`, `llm_chat` — `contact`, `message_id`, `session_id`, `provider_ts`. These hand you a conversation, not a connection.
14651
+ * - `web_chat` — the above plus `ip`, `user_agent`, `geo`. A browser has no install, so no `device_id_hash`.
14652
+ * - `app` — the above plus `device_id_hash`.
14653
+ * - `other` — everything, because we cannot say what a channel we have not named exposes. An auditor reading `other` knows exactly that.
14654
+ *
14655
+ * A key outside its channel's set, or a key the object does not declare, is a 400 `attestation_evidence_invalid` with `details.key` naming it — never a silent drop. `contact` is the e-mail or E.164 phone the consumer acted from; it is hashed server-side into the signed `contact_hash` and never stored in the clear. `device_id_hash` you hash yourself (64 hex characters). `geo` is `{country, region, city}` and refuses coordinates.
14656
+ *
14657
+ * `method: "verified_code"` additionally REQUIRES `evidence.contact` to carry a contact verification we ran for this consumer in the last 24h (`POST /v1/consumers/{consumerId}/contact-verifications`), or the submit is refused with 409 `contact_verification_required` and the token is left unspent. A rung that is only asserted is not stronger than the one below it.
14416
14658
  */
14417
14659
  post: {
14418
14660
  parameters: {
@@ -14436,6 +14678,23 @@ export interface paths {
14436
14678
  method: "partner_session" | "in_person" | "verified_code" | "partner_biometric";
14437
14679
  asserted_at: number;
14438
14680
  reference?: string;
14681
+ evidence?: {
14682
+ /** @enum {string} */
14683
+ channel: "whatsapp" | "web_chat" | "app" | "llm_chat" | "sms" | "email" | "other";
14684
+ message_id?: string;
14685
+ session_id?: string;
14686
+ provider_ts?: number;
14687
+ /** Format: ip */
14688
+ ip?: string;
14689
+ user_agent?: string;
14690
+ device_id_hash?: string;
14691
+ geo?: {
14692
+ country: string;
14693
+ region?: string;
14694
+ city?: string;
14695
+ };
14696
+ contact?: string;
14697
+ };
14439
14698
  };
14440
14699
  };
14441
14700
  };
@@ -14460,7 +14719,7 @@ export interface paths {
14460
14719
  };
14461
14720
  };
14462
14721
  };
14463
- /** @description The body did not match the schema (`invalid_body`, with the Zod issues in `details.issues`), or the attestation does not match the token's surface: `attestation_required` on `partner` without one, `attestation_not_accepted` on `hosted` with one. */
14722
+ /** @description The body did not match the schema (`invalid_body`, with the Zod issues in `details.issues`), the attestation does not match the token's surface (`attestation_required` on `partner` without one, `attestation_not_accepted` on `hosted` with one), or the evidence carries a key its channel cannot expose or one the object does not declare (`attestation_evidence_invalid`, `details.key`). */
14464
14723
  400: {
14465
14724
  headers: {
14466
14725
  [name: string]: unknown;
@@ -14469,7 +14728,7 @@ export interface paths {
14469
14728
  "application/json": {
14470
14729
  error: {
14471
14730
  /** @enum {string} */
14472
- code: "invalid_body" | "attestation_required" | "attestation_not_accepted";
14731
+ code: "invalid_body" | "attestation_required" | "attestation_not_accepted" | "attestation_evidence_invalid";
14473
14732
  message: string;
14474
14733
  details?: {
14475
14734
  [key: string]: unknown;
@@ -14500,7 +14759,7 @@ export interface paths {
14500
14759
  };
14501
14760
  };
14502
14761
  };
14503
- /** @description The token was already submitted, or a concurrent submit won the race. Nothing was created twice: the loser rolls back whole. */
14762
+ /** @description The token was already submitted, or a concurrent submit won the race (nothing was created twice: the loser rolls back whole); or `method: "verified_code"` was claimed without a contact verification for this consumer in the last 24h, in which case nothing was created at all and the token is still pending. */
14504
14763
  409: {
14505
14764
  headers: {
14506
14765
  [name: string]: unknown;
@@ -14509,7 +14768,7 @@ export interface paths {
14509
14768
  "application/json": {
14510
14769
  error: {
14511
14770
  /** @enum {string} */
14512
- code: "consent_already_resolved" | "consent_race";
14771
+ code: "consent_already_resolved" | "consent_race" | "contact_verification_required";
14513
14772
  message: string;
14514
14773
  details?: {
14515
14774
  [key: string]: unknown;
@@ -14595,6 +14854,7 @@ export interface paths {
14595
14854
  attempt_id?: string;
14596
14855
  ted?: components["schemas"]["TedDestination"];
14597
14856
  quote?: components["schemas"]["SpendQuote"];
14857
+ actor?: components["schemas"]["PaymentActor"];
14598
14858
  };
14599
14859
  };
14600
14860
  };
@@ -14608,7 +14868,7 @@ export interface paths {
14608
14868
  "application/json": components["schemas"]["SpendOutcome"];
14609
14869
  };
14610
14870
  };
14611
- /** @description The body did not match the schema. */
14871
+ /** @description The body did not match the schema (`invalid_body`), or `actor.on_behalf_of` names a consumer other than the one this mandate belongs to (`actor_consumer_mismatch`). Nothing was read, held or sent in either case. */
14612
14872
  400: {
14613
14873
  headers: {
14614
14874
  [name: string]: unknown;
@@ -14617,7 +14877,7 @@ export interface paths {
14617
14877
  "application/json": {
14618
14878
  error: {
14619
14879
  /** @enum {string} */
14620
- code: "invalid_body";
14880
+ code: "invalid_body" | "actor_consumer_mismatch";
14621
14881
  message: string;
14622
14882
  details?: {
14623
14883
  [key: string]: unknown;
@@ -14820,6 +15080,7 @@ export interface paths {
14820
15080
  attempt_id?: string;
14821
15081
  ted?: components["schemas"]["TedDestination"];
14822
15082
  quote?: components["schemas"]["SpendQuote"];
15083
+ actor?: components["schemas"]["PaymentActor"];
14823
15084
  };
14824
15085
  };
14825
15086
  };
@@ -14833,7 +15094,7 @@ export interface paths {
14833
15094
  "application/json": components["schemas"]["SpendOutcome"];
14834
15095
  };
14835
15096
  };
14836
- /** @description The body did not match the schema. */
15097
+ /** @description The body did not match the schema (`invalid_body`), or `actor.on_behalf_of` names a consumer other than the one this mandate belongs to (`actor_consumer_mismatch`). Nothing was read, held or sent in either case. */
14837
15098
  400: {
14838
15099
  headers: {
14839
15100
  [name: string]: unknown;
@@ -14842,7 +15103,7 @@ export interface paths {
14842
15103
  "application/json": {
14843
15104
  error: {
14844
15105
  /** @enum {string} */
14845
- code: "invalid_body";
15106
+ code: "invalid_body" | "actor_consumer_mismatch";
14846
15107
  message: string;
14847
15108
  details?: {
14848
15109
  [key: string]: unknown;
@@ -14997,6 +15258,7 @@ export interface paths {
14997
15258
  attempt_id?: string;
14998
15259
  ted?: components["schemas"]["TedDestination"];
14999
15260
  quote?: components["schemas"]["SpendQuote"];
15261
+ actor?: components["schemas"]["PaymentActor"];
15000
15262
  };
15001
15263
  };
15002
15264
  };
@@ -15010,7 +15272,7 @@ export interface paths {
15010
15272
  "text/event-stream": string;
15011
15273
  };
15012
15274
  };
15013
- /** @description The body did not match the schema. */
15275
+ /** @description The body did not match the schema (`invalid_body`), or `actor.on_behalf_of` names a consumer other than the one this mandate belongs to (`actor_consumer_mismatch`). Nothing was read, held or sent in either case. */
15014
15276
  400: {
15015
15277
  headers: {
15016
15278
  [name: string]: unknown;
@@ -15019,7 +15281,7 @@ export interface paths {
15019
15281
  "application/json": {
15020
15282
  error: {
15021
15283
  /** @enum {string} */
15022
- code: "invalid_body";
15284
+ code: "invalid_body" | "actor_consumer_mismatch";
15023
15285
  message: string;
15024
15286
  details?: {
15025
15287
  [key: string]: unknown;
@@ -17796,6 +18058,18 @@ export interface paths {
17796
18058
  receipt_id: string;
17797
18059
  /** @enum {string} */
17798
18060
  state: "paid" | "delivered" | "exception" | "voided";
18061
+ /** @description WHO triggered the spend, as the caller declared it at payment time. Null when they declared none, and null is the honest answer rather than a gap to fill: it is never inferred from `mandate.scope` or from the agent the mandate was signed for. A null here means nobody said, not that an agent did it. */
18062
+ actor: {
18063
+ /** @enum {string} */
18064
+ type: "agent";
18065
+ id: string;
18066
+ on_behalf_of: string;
18067
+ } | {
18068
+ /** @enum {string} */
18069
+ type: "human";
18070
+ id: string;
18071
+ channel?: string;
18072
+ } | null;
17799
18073
  mandate: {
17800
18074
  id: string;
17801
18075
  nonce: string;
@@ -17849,6 +18123,10 @@ export interface paths {
17849
18123
  } | null;
17850
18124
  chain: string;
17851
18125
  receipt_sig: string;
18126
+ /** @description base64url Ed25519 signature over `codespar-receipt:v1:<receipt_id>:<chain>`, made with the platform issuer key. Verifiable by anyone: fetch `/.well-known/codespar-receipt-keys.json` (no credential), take the key whose `kid` is the one below, and check the signature over that string. Null on a receipt sealed before this existed, and on one sealed while the key could not be resolved — `receipt_sig` is the HMAC seal either way and is unaffected. */
18127
+ receipt_sig_ed25519: string | null;
18128
+ /** @description Which published key signed it, `<did:web:...>#<namespace>-<n>`. Keys rotate and a retired key stays published, so an old receipt names its own key rather than leaving a verifier to try each one. The namespace names the DEPLOYMENT that minted the key (ent#1641), so a kid absent from the key document you fetched means the receipt came from another environment — `unknown_key`, not a tampered receipt. */
18129
+ receipt_sig_kid: string | null;
17852
18130
  exceptions: {
17853
18131
  code: string;
17854
18132
  detail: string;
@@ -17903,6 +18181,18 @@ export interface paths {
17903
18181
  receipt_id: string;
17904
18182
  /** @enum {string} */
17905
18183
  state: "paid" | "delivered" | "exception" | "voided";
18184
+ /** @description WHO triggered the spend, as the caller declared it at payment time. Null when they declared none, and null is the honest answer rather than a gap to fill: it is never inferred from `mandate.scope` or from the agent the mandate was signed for. A null here means nobody said, not that an agent did it. */
18185
+ actor: {
18186
+ /** @enum {string} */
18187
+ type: "agent";
18188
+ id: string;
18189
+ on_behalf_of: string;
18190
+ } | {
18191
+ /** @enum {string} */
18192
+ type: "human";
18193
+ id: string;
18194
+ channel?: string;
18195
+ } | null;
17906
18196
  mandate: {
17907
18197
  id: string;
17908
18198
  nonce: string;
@@ -17956,6 +18246,10 @@ export interface paths {
17956
18246
  } | null;
17957
18247
  chain: string;
17958
18248
  receipt_sig: string;
18249
+ /** @description base64url Ed25519 signature over `codespar-receipt:v1:<receipt_id>:<chain>`, made with the platform issuer key. Verifiable by anyone: fetch `/.well-known/codespar-receipt-keys.json` (no credential), take the key whose `kid` is the one below, and check the signature over that string. Null on a receipt sealed before this existed, and on one sealed while the key could not be resolved — `receipt_sig` is the HMAC seal either way and is unaffected. */
18250
+ receipt_sig_ed25519: string | null;
18251
+ /** @description Which published key signed it, `<did:web:...>#<namespace>-<n>`. Keys rotate and a retired key stays published, so an old receipt names its own key rather than leaving a verifier to try each one. The namespace names the DEPLOYMENT that minted the key (ent#1641), so a kid absent from the key document you fetched means the receipt came from another environment — `unknown_key`, not a tampered receipt. */
18252
+ receipt_sig_kid: string | null;
17959
18253
  exceptions: {
17960
18254
  code: string;
17961
18255
  detail: string;
@@ -19865,6 +20159,18 @@ export interface paths {
19865
20159
  receipt_id: string;
19866
20160
  /** @enum {string} */
19867
20161
  state: "paid" | "delivered" | "exception" | "voided";
20162
+ /** @description WHO triggered the spend, as the caller declared it at payment time. Null when they declared none, and null is the honest answer rather than a gap to fill: it is never inferred from `mandate.scope` or from the agent the mandate was signed for. A null here means nobody said, not that an agent did it. */
20163
+ actor: {
20164
+ /** @enum {string} */
20165
+ type: "agent";
20166
+ id: string;
20167
+ on_behalf_of: string;
20168
+ } | {
20169
+ /** @enum {string} */
20170
+ type: "human";
20171
+ id: string;
20172
+ channel?: string;
20173
+ } | null;
19868
20174
  mandate: {
19869
20175
  id: string;
19870
20176
  nonce: string;
@@ -19918,6 +20224,10 @@ export interface paths {
19918
20224
  } | null;
19919
20225
  chain: string;
19920
20226
  receipt_sig: string;
20227
+ /** @description base64url Ed25519 signature over `codespar-receipt:v1:<receipt_id>:<chain>`, made with the platform issuer key. Verifiable by anyone: fetch `/.well-known/codespar-receipt-keys.json` (no credential), take the key whose `kid` is the one below, and check the signature over that string. Null on a receipt sealed before this existed, and on one sealed while the key could not be resolved — `receipt_sig` is the HMAC seal either way and is unaffected. */
20228
+ receipt_sig_ed25519: string | null;
20229
+ /** @description Which published key signed it, `<did:web:...>#<namespace>-<n>`. Keys rotate and a retired key stays published, so an old receipt names its own key rather than leaving a verifier to try each one. The namespace names the DEPLOYMENT that minted the key (ent#1641), so a kid absent from the key document you fetched means the receipt came from another environment — `unknown_key`, not a tampered receipt. */
20230
+ receipt_sig_kid: string | null;
19921
20231
  exceptions: {
19922
20232
  code: string;
19923
20233
  detail: string;
@@ -20126,7 +20436,7 @@ export interface paths {
20126
20436
  };
20127
20437
  /**
20128
20438
  * Read one consumer allowance
20129
- * @description The same 14-field projection the listing returns, by id, from the same table and under the same organization predicate.
20439
+ * @description The same 14-field projection the listing returns, by id, from the same table and under the same organization predicate, plus `org_paused` / `org_paused_at`: whether the organization's kill switch is pressed (ent#1648).
20130
20440
  *
20131
20441
  * This path has NO alias. Its four siblings are registered twice each, under `/v1/mandates/...` and `/v1/consumers/mandates/...`; this one is registered once, because point reads of an allowance did not exist before it and there was no older spelling to keep alive.
20132
20442
  */
@@ -20177,6 +20487,13 @@ export interface paths {
20177
20487
  expires_at: string;
20178
20488
  /** Format: date-time */
20179
20489
  created_at: string;
20490
+ /** @description True while the organization has paused ALL agent spend (the kill switch, ent#1648). `status` is still this allowance's own stored state: a pause changes no mandate. While this is true every spend under this allowance is refused `org_paused`, so a caller that checks before executing should treat it as "do not execute" whatever `status` says. */
20491
+ org_paused: boolean;
20492
+ /**
20493
+ * Format: date-time
20494
+ * @description When the organization paused. Null when `org_paused` is false.
20495
+ */
20496
+ org_paused_at: string | null;
20180
20497
  };
20181
20498
  };
20182
20499
  };
@@ -24512,7 +24829,7 @@ export interface paths {
24512
24829
  "application/json": {
24513
24830
  /** @description `did:web:` derived from the org and the handle. */
24514
24831
  agent_did: string;
24515
- /** @description `<agent_did>#<n>`. */
24832
+ /** @description `<agent_did>#<namespace>-<n>` — the namespace names the deployment that minted the key (ent#1641). */
24516
24833
  kid: string;
24517
24834
  /** @description Raw 32-byte Ed25519 public key, base64. */
24518
24835
  pubkey: string;
@@ -24725,7 +25042,7 @@ export interface paths {
24725
25042
  *
24726
25043
  * Takes no body. Unlike rotation, this is the verb that stops a key from counting: the mandate spend gate resolves the key an existing mandate was signed with and refuses the spend once that key is revoked, so revoking reaches BACKWARDS into mandates already issued.
24727
25044
  *
24728
- * `{kid}` is a full key id of the form `<did:web:...>#<n>`, and its `#` MUST be percent-encoded as `%23` to survive as one path segment. This revokes ONE key; it does not revoke the agent identity.
25045
+ * `{kid}` is a full key id of the form `<did:web:...>#<namespace>-<n>`, and its `#` MUST be percent-encoded as `%23` to survive as one path segment. This revokes ONE key; it does not revoke the agent identity.
24729
25046
  *
24730
25047
  * Revoking an already-revoked key is 409 rather than a no-op, so a retry after a timeout is distinguishable from a first call.
24731
25048
  */
@@ -24737,7 +25054,7 @@ export interface paths {
24737
25054
  orgId: string;
24738
25055
  /** @description The registration handle, not the `did:web`. */
24739
25056
  agentId: string;
24740
- /** @description `<did:web:...>#<n>`, with the `#` percent-encoded as `%23`. */
25057
+ /** @description `<did:web:...>#<namespace>-<n>`, with the `#` percent-encoded as `%23`. */
24741
25058
  kid: string;
24742
25059
  };
24743
25060
  cookie?: never;
@@ -24932,7 +25249,7 @@ export interface paths {
24932
25249
  * Issue an org-side mandate (off by default, see the 501)
24933
25250
  * @description OFF BY DEFAULT, AND THE FIRST THING THIS ROUTE DOES IS CHECK THAT. Unless the deployment has explicitly enabled org-side issuance, every call is 501 `not_implemented` before any row is written. On a default deployment that 501 is the expected answer, not an outage.
24934
25251
  *
24935
- * TAKE THE FLAG AS THE GATE, NOT THE 501's SENTENCE AS THE STATE. The message on that 501 says the aggregate spend cap 'is not yet enforced by any spend path'. That sentence is older than the wallet gate and no longer describes the system: `POST /v1/wallets/{id}/execute` charges a mandate before the payment is attempted, decrements `remaining_amount` under a guard that refuses an over-cap spend, and writes the consumption row this document returns from `GET /v1/orgs/{orgId}/mandates/{id}`. So a mandate issued here is enforceable; whether it can be issued at all is the deployment's flag.
25252
+ * The 501 is about offering issuance, not about enforcement: `POST /v1/wallets/{id}/execute` charges a mandate before the payment is attempted, decrements `remaining_amount` under a guard that refuses an over-cap spend, and writes the consumption row this document returns from `GET /v1/orgs/{orgId}/mandates/{id}`. So a mandate issued here is enforceable; whether it can be issued at all is the deployment's flag.
24936
25253
  *
24937
25254
  * When enabled, issuance is gated by the org's policy rules for `codespar:mandate:issue`, evaluated before any write. The three non-allowed outcomes are distinct on purpose: 403 `policy_denied` is a rule refusing, 413 `payload_too_large` is an input too big to evaluate, and 503 `policy_engine_error` means the engine could NOT evaluate. The 503 is infrastructure and is retriable; the 403 is not.
24938
25255
  *
@@ -25336,6 +25653,194 @@ export interface paths {
25336
25653
  patch?: never;
25337
25654
  trace?: never;
25338
25655
  };
25656
+ "/v1/orgs/{orgId}/pause": {
25657
+ parameters: {
25658
+ query?: never;
25659
+ header?: never;
25660
+ path?: never;
25661
+ cookie?: never;
25662
+ };
25663
+ /**
25664
+ * Read the organization kill switch
25665
+ * @description Whether the organization has paused ALL agent spend. While `paused` is true every agent money door of the organization refuses with `org_paused` (403): consumer payments and spends under a mandate, payment links, consumer withdrawals and transfers, card authorizations, the money-moving meta-tool actions, the org programmable wallet, an inbound Pix devolution, and raw tools the deny-list classifies as a fund transfer. Reads, inbound charges, mandate revoke/pause and x402-in keep running. `GET /v1/mandates/{id}` carries the same flag as `org_paused`.
25666
+ */
25667
+ get: {
25668
+ parameters: {
25669
+ query?: never;
25670
+ header?: never;
25671
+ path: {
25672
+ orgId: string;
25673
+ };
25674
+ cookie?: never;
25675
+ };
25676
+ requestBody?: never;
25677
+ responses: {
25678
+ /** @description OK */
25679
+ 200: {
25680
+ headers: {
25681
+ [name: string]: unknown;
25682
+ };
25683
+ content: {
25684
+ "application/json": {
25685
+ org_id: string;
25686
+ paused: boolean;
25687
+ /** Format: date-time */
25688
+ paused_at: string | null;
25689
+ /** @description Why it was paused; null when not paused. */
25690
+ reason: string | null;
25691
+ /** @description The admin's user id, or `key:<id>` for a bearer key. Null when not paused. */
25692
+ paused_by: string | null;
25693
+ /** @enum {string|null} */
25694
+ paused_by_source: "bearer_key" | "user_token_verified" | "header_asserted" | null;
25695
+ /**
25696
+ * Format: date-time
25697
+ * @description The last resume, kept after a new pause.
25698
+ */
25699
+ resumed_at: string | null;
25700
+ /** @description Increases by one on every pause and every resume. */
25701
+ generation: number;
25702
+ };
25703
+ };
25704
+ };
25705
+ /** @description The `{orgId}` in the path is not the authenticated org. */
25706
+ 404: {
25707
+ headers: {
25708
+ [name: string]: unknown;
25709
+ };
25710
+ content: {
25711
+ "application/json": {
25712
+ error: {
25713
+ /** @enum {string} */
25714
+ code: "not_found";
25715
+ message: string;
25716
+ details?: {
25717
+ [key: string]: unknown;
25718
+ };
25719
+ };
25720
+ /** @description Echoes the `X-Request-Id` header when the request carried one. */
25721
+ request_id: string | null;
25722
+ };
25723
+ };
25724
+ };
25725
+ };
25726
+ };
25727
+ put?: never;
25728
+ /**
25729
+ * Pause all agent spend of the organization (kill switch)
25730
+ * @description Stops every agent money door of the organization, test and live projects alike, until a person resumes it. Once this call answers, no new reservation is taken: a spend that already reserved its funds finishes, like an in-flight hold on a frozen wallet.
25731
+ *
25732
+ * A bearer key needs the `organizations:pause` scope; the dashboard path needs an admin. Idempotent: pausing a paused organization answers `changed: false` and keeps the original pause. Resuming is NOT an API-key operation: it is done from the dashboard by a verified admin. Publishes `commerce.organization.paused` to every project of the organization and appends `org_spend_paused` to its audit chain.
25733
+ *
25734
+ * Card authorizations are refused at the issuer that waits for our answer (Pomelo). Bridge decides before we hear of it: freeze those cards at the issuer as well.
25735
+ */
25736
+ post: {
25737
+ parameters: {
25738
+ query?: never;
25739
+ header?: never;
25740
+ path: {
25741
+ orgId: string;
25742
+ };
25743
+ cookie?: never;
25744
+ };
25745
+ requestBody?: {
25746
+ content: {
25747
+ "application/json": {
25748
+ reason?: string;
25749
+ };
25750
+ };
25751
+ };
25752
+ responses: {
25753
+ /** @description OK */
25754
+ 200: {
25755
+ headers: {
25756
+ [name: string]: unknown;
25757
+ };
25758
+ content: {
25759
+ "application/json": {
25760
+ /** @description False when the organization was already in the requested state. */
25761
+ changed: boolean;
25762
+ pause: {
25763
+ org_id: string;
25764
+ paused: boolean;
25765
+ /** Format: date-time */
25766
+ paused_at: string | null;
25767
+ /** @description Why it was paused; null when not paused. */
25768
+ reason: string | null;
25769
+ /** @description The admin's user id, or `key:<id>` for a bearer key. Null when not paused. */
25770
+ paused_by: string | null;
25771
+ /** @enum {string|null} */
25772
+ paused_by_source: "bearer_key" | "user_token_verified" | "header_asserted" | null;
25773
+ /**
25774
+ * Format: date-time
25775
+ * @description The last resume, kept after a new pause.
25776
+ */
25777
+ resumed_at: string | null;
25778
+ /** @description Increases by one on every pause and every resume. */
25779
+ generation: number;
25780
+ };
25781
+ };
25782
+ };
25783
+ };
25784
+ /** @description The body did not parse. */
25785
+ 400: {
25786
+ headers: {
25787
+ [name: string]: unknown;
25788
+ };
25789
+ content: {
25790
+ "application/json": {
25791
+ error: {
25792
+ /** @enum {string} */
25793
+ code: "invalid_body";
25794
+ message: string;
25795
+ details?: {
25796
+ [key: string]: unknown;
25797
+ };
25798
+ };
25799
+ /** @description Echoes the `X-Request-Id` header when the request carried one. */
25800
+ request_id: string | null;
25801
+ };
25802
+ };
25803
+ };
25804
+ /** @description The dashboard path named no admin, or a token that did not verify. Bare `{ error, remediation }` body. */
25805
+ 403: {
25806
+ headers: {
25807
+ [name: string]: unknown;
25808
+ };
25809
+ content: {
25810
+ "application/json": {
25811
+ error: string;
25812
+ remediation?: string;
25813
+ };
25814
+ };
25815
+ };
25816
+ /** @description The `{orgId}` in the path is not the authenticated org. */
25817
+ 404: {
25818
+ headers: {
25819
+ [name: string]: unknown;
25820
+ };
25821
+ content: {
25822
+ "application/json": {
25823
+ error: {
25824
+ /** @enum {string} */
25825
+ code: "not_found";
25826
+ message: string;
25827
+ details?: {
25828
+ [key: string]: unknown;
25829
+ };
25830
+ };
25831
+ /** @description Echoes the `X-Request-Id` header when the request carried one. */
25832
+ request_id: string | null;
25833
+ };
25834
+ };
25835
+ };
25836
+ };
25837
+ };
25838
+ delete?: never;
25839
+ options?: never;
25840
+ head?: never;
25841
+ patch?: never;
25842
+ trace?: never;
25843
+ };
25339
25844
  "/v1/paywalls": {
25340
25845
  parameters: {
25341
25846
  query?: never;
@@ -32801,7 +33306,7 @@ export interface paths {
32801
33306
  content: {
32802
33307
  "application/json": {
32803
33308
  agent_did: string;
32804
- /** @description `<did>#<n>`, where n is the key's ordinal. */
33309
+ /** @description `<did>#<namespace>-<n>`: the namespace names the deployment that minted the key (ent#1641), n is its ordinal. */
32805
33310
  kid: string;
32806
33311
  /** @description base64. */
32807
33312
  pubkey: string;
@@ -33697,7 +34202,7 @@ export interface paths {
33697
34202
  *
33698
34203
  * It also changes what counterparties can see. The published `did:web` document lists the identity's keys where status is not `revoked`, so a REVOKED key disappears from it while a RETIRED one stays and keeps verifying its own past issuance. Revoking is the verb for a key you believe is compromised; rotating is the verb for hygiene.
33699
34204
  *
33700
- * `{kid}` is a full kid (`<did>#<n>`), and its `#` MUST be percent-encoded as `%23` so the whole kid arrives as one path segment.
34205
+ * `{kid}` is a full kid (`<did>#<namespace>-<n>`), and its `#` MUST be percent-encoded as `%23` so the whole kid arrives as one path segment.
33701
34206
  *
33702
34207
  * Idempotency is NOT offered: revoking an already-revoked key is 409, not a repeat of the 200.
33703
34208
  */
@@ -36108,6 +36613,22 @@ export interface components {
36108
36613
  session_id?: string;
36109
36614
  at?: string;
36110
36615
  };
36616
+ /** @description WHO triggered this spend, recorded on the receipt and read back from it. Optional, and absence is a real answer: a spend that sends no actor records `null`, and nothing is ever inferred from `agent_id` — that field names the agent the mandate was SIGNED for, which is an authority, not an event. A person acting through WhatsApp under an agent's mandate and the agent acting unattended are the same row without this field. */
36617
+ PaymentActor: {
36618
+ /** @enum {string} */
36619
+ type: "agent";
36620
+ /** @description The agent's own identifier. */
36621
+ id: string;
36622
+ /** @description The consumer the agent is acting for. It must be the consumer this mandate belongs to; any other value is refused with `actor_consumer_mismatch` before anything is read, held or sent. */
36623
+ on_behalf_of: string;
36624
+ } | {
36625
+ /** @enum {string} */
36626
+ type: "human";
36627
+ /** @description The person's identifier — a user id, not a name. */
36628
+ id: string;
36629
+ /** @description Where the person acted from: `whatsapp`, `dashboard`, `cli`. */
36630
+ channel?: string;
36631
+ };
36111
36632
  };
36112
36633
  responses: never;
36113
36634
  parameters: never;