GET /v2/merchant/x402-earnings returns the authenticated merchant’s rollup of
x402 settlement events: per-row settlement detail, totals envelope (settlement
amount + count), and pagination. This endpoint is the data source for the
merchant x402 Earnings page in the dashboard.
This endpoint requires:
- Merchant JWT — any authenticated merchant role (
OWNER,MEMBER,PRODUCER)
sub claim. There is no
merchantId query parameter. If a client passes one anyway it is silently
ignored — the response is always scoped to the JWT-bound merchant.GET /v2/merchant/x402-earnings
Authentication
| Guard | Requirement |
|---|---|
| JWT | Required, any authenticated merchant role |
| Scope | merchantId derived from JWT sub — not from query / body |
POST /merchant/admin/login — see
Authentication.
Query parameters
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | 1-indexed page number. |
limit | integer | No | 20 | Rows per page. |
startDate | ISO-8601 string | No | — | Filter to settlements with settledAt >= startDate. Omit for no lower bound. |
endDate | ISO-8601 string | No | — | Filter to settlements with settledAt <= endDate. Omit for no upper bound. |
Example
Response — 200 OK
Fields
| Field | Type | Nullable | Description |
|---|---|---|---|
rows | array | No | One entry per x402 settlement event matching the filter. Empty array until X402_ENABLED is flipped on, or when the merchant has no settlements in the filter window. |
rows[].settlementId | string | No | X402SettlementLog row _id. |
rows[].settledAt | ISO-8601 string | No | Settlement timestamp (UTC) — when the x402 settlement event was captured on chain and recorded. |
rows[].amountUsdCents | integer | No | Settlement amount in USD cents, integer. x402 settles natively in USDC on Base; the read path snapshots the FX at settlement time. |
rows[].productId | string | Yes | Source product _id if the settlement is tied to a specific product. null for storefront-wide payouts. |
rows[].orderId | string | Yes | Source order _id if available. null for legacy rows. |
rows[].txHash | string | Yes | Base transaction hash. null for legacy rows pre-dating chain-hash capture. |
totalSettlementsUsdCents | integer | No | Sum of amountUsdCents for the merchant across the filter window (not just the current page). |
totalCount | integer | No | Total settlement count for the merchant across the filter window. |
asOf | ISO-8601 string | No | Snapshot timestamp (server clock, UTC). |
pagination | object | No | Pagination envelope. |
pagination.page | integer | No | Echoed page query param (1-indexed). |
pagination.limit | integer | No | Echoed limit query param. |
pagination.total | integer | No | Total number of settlement rows matching the filter (across pages). Equal to totalCount. |
Errors
| Status | Body | When |
|---|---|---|
401 | { "statusCode": 401, "status": "failed", "data": { "message": "Unauthorized" } } | Missing or invalid JWT |
5xx | { "statusCode": 500, "status": "failed", ... } | Hard backend failure — see Notes below for the fail-open contract |
Notes
X402_ENABLEDgating. Until the platform flagX402_ENABLEDis set totrue,X402SettlementLogaccepts no writes and this endpoint always returnsrows: [],totalSettlementsUsdCents: 0,totalCount: 0. The endpoint itself is always reachable — the gate is at the write path, not the read path. Merchants safely linkable to the page before the flip; it renders an empty-state.- Auth scope. The endpoint reads
merchantIdfrom the JWTsubclaim only. Any?merchantId=is silently ignored. A merchant cannot read another merchant’s settlements through this endpoint — even with a syntactically valid query parameter pointing at the target. - Fail-open semantics. If the underlying
X402SettlementLogaggregation throws, the endpoint returns the empty-state envelope (rows: [], totals0) with200 OKrather than propagating the error. Inspect server logs / Sentry for the underlying failure. - Currency. All monetary fields are USD cents, integer — same contract
as the admin x402-earnings rollup.
Divide by
100for major-unit display. - Pagination.
totalandtotalCountcount settlement rows, not products / orders. A merchant with 50 settlements across 3 products reportstotal: 50,totalCount: 50. - Date filter semantics.
startDateandendDateare inclusive bounds onsettledAt. Omit either to leave that side of the window unbounded; omit both for the full per-merchant history (capped at the merchant’s earliest settlement).
Related
- Billing Invoices (Merchant) — companion merchant-facing billing history (trailing 365 days, paid subscription invoices).
- x402 Earnings (Admin) — admin-side per-merchant x402 settlement rollup (network-wide view).
- Platform Fee Summary (Admin) — network-wide MRR / ARR / 30d / 365d rollup that includes x402 in
revenue30dUsdCents/revenue365dUsdCents.