Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,22 @@ All notable changes to this project are documented here. The format is based on

## [Unreleased]

### Fixed

- **`X402PaymentRequired.error_detail` nesting** (`openapi.yaml`): `error_detail` referenced the
`Error` envelope (`{ error: { code, ... } }`), but the gateway nests the bare error object
directly under `error_detail` (`{ code, message, ... }`), with no inner `error` wrapper. The
inner object is now extracted as the `ErrorBody` component schema (referenced by `Error`, so
every other response is unchanged) and `error_detail` composes `ErrorBody` instead, matching
the wire shape so generated types no longer expect a nonexistent `error_detail.error` member.

### Added

- **`X402PaymentRequired.error_detail.payment_rejected`** (`openapi.yaml`) — documents the
additive `{ reason, rail }` deny verdict the gateway now publishes on a 402 when a submitted
payment was REJECTED, so generated types and docs can discover the diagnostic field. Optional
and conditional: absent on an ordinary unpaid challenge.

- **MoQ join-token mint surface** (`openapi.yaml`) — the Media over QUIC product had no spec at
all, so no SDK or CLI could be generated for it. Adds the `MoQ` tag and both mint operations:
- `POST /moq/publish/{ns}/{track}` (`mintMoqPublishToken`, scope `moq:write`) and
Expand Down
96 changes: 63 additions & 33 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1931,39 +1931,47 @@ components:
required: [error]
properties:
error:
$ref: '#/components/schemas/ErrorBody'

ErrorBody:
type: object
description: >
The normalized WAVE error object itself — the value of the `Error` envelope's
`error` member. Referenced directly by bodies that carry the error object under
a different key (the 402 x402 challenge nests it under `error_detail` without
the envelope wrapper).
required: [code, message]
properties:
code:
type: string
description: Stable machine-readable error code.
message:
type: string
description: Human-readable explanation, safe to surface to end users.
details:
type: object
required: [code, message]
properties:
code:
type: string
description: Stable machine-readable error code.
message:
type: string
description: Human-readable explanation, safe to surface to end users.
details:
type: object
additionalProperties: true
description: >
Optional structured context (e.g. failing field, retry limit,
requested scopes) — never raw upstream payloads.
suggestions:
type: array
description: >
Actionable next steps, ordered most→least likely to resolve the
error. Written to be acted on by a human OR an agent.
items:
type: string
did_you_mean:
type: array
description: >
Closest valid alternatives when the caller likely made a typo or
wrong choice (e.g. an unknown scope, product, or route).
items:
type: string
doc_url:
type: string
format: uri
description: Documentation link for this error.
additionalProperties: true
description: >
Optional structured context (e.g. failing field, retry limit,
requested scopes) — never raw upstream payloads.
suggestions:
type: array
description: >
Actionable next steps, ordered most→least likely to resolve the
error. Written to be acted on by a human OR an agent.
items:
type: string
did_you_mean:
type: array
description: >
Closest valid alternatives when the caller likely made a typo or
wrong choice (e.g. an unknown scope, product, or route).
items:
type: string
doc_url:
type: string
format: uri
description: Documentation link for this error.

Pagination:
type: object
Expand Down Expand Up @@ -3544,7 +3552,29 @@ components:
items:
$ref: '#/components/schemas/X402Accepts'
error_detail:
$ref: '#/components/schemas/Error'
allOf:
- $ref: '#/components/schemas/ErrorBody'
- type: object
Comment on lines 3554 to +3557

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Refactor changes the generated type for error_detail (breaking for existing consumers)

The extraction of ErrorBody leaves every other response byte-identical (the Error envelope now just $refs the extracted object), but error_detail itself changes shape: it used to generate as { error: { code, message, ... } } and now generates as { code, message, ..., payment_rejected? }. Consumers that already generated types from the previous spec and read error_detail.error.code will break at their next regeneration. The CHANGELOG records this under "Fixed" (CHANGELOG.md:9-16), which is reasonable if the old spec was wrong on the wire, but the claim that the gateway nests the bare error object is unverifiable from this repo — worth confirming against an actual 402 body before release, since it is effectively a breaking change for SDK consumers.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

properties:
payment_rejected:
type: object
description: >-
Present ONLY when a submitted payment was REJECTED (as opposed to no payment
having been made at all): the sanitized deny verdict, so a paying caller can
tell a rejected payment apart from an unpaid challenge and correct the named
field. `reason` is a lowercase snake_case token from the gateway's closed deny
vocabulary (e.g. `invalid_permit_header`, `session_expired`, `duplicate`,
`rate_limited`); internal detail that cannot be published verbatim collapses
to the generic `payment_rejected`. `rail` names the payment rail that denied
(e.g. `base-usdc`, `tempo-pathusd`), or `unknown`.
required: [reason, rail]
properties:
reason:
type: string
description: Sanitized machine-readable rejection reason token.
rail:
type: string
description: The payment rail the rejection occurred on.
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
next_action:
type: object
additionalProperties: true
Expand Down
Loading