docs(api): comprehensive consistency audit pass#15
Merged
marioalvial merged 5 commits intomainfrom Apr 29, 2026
Merged
Conversation
Sweeps the three OpenAPI specs (fx-account, fx-payment, fx-webhook), the
guide pages, and the journey docs to align them with each other and with
the live source. Most schema/wire-format changes need backend follow-up
(see list below) — the docs now describe the target state.
# Highlights
## Pagination unified
- Single `PageMetadata` schema across all three specs (fields:
`previousCursor`, `nextCursor`, `total`)
- All list endpoints expose `limit`, `cursor`, `direction`, `sortOrder`,
`filters` parameters
- `listUbos` and `listFundingInstructions` wrapped in `{data, meta}`
- fx-payment default limit aligned to 10
- `totalMatches` and `PaginationIncludeTotalMatches` removed (per direction
to drop these from the public surface)
## Money shape switched to decimal strings everywhere
- `Amount.value` is now a decimal string in the asset's canonical scale
- Dropped the `decimalValue` field (single source of truth)
- Aligned to the industry pattern used by Coinbase, PayPal, Circle, Binance
for hybrid fiat+crypto APIs
- `money.mdx` rewritten + `BigDecimal/Decimal` library guidance
## Asset enum unified
- One `Asset` enum with 20 values across all three specs (was three
separate enums with 7 / 16 / 20 values, two named `Currency` and one
named `Asset`)
## Idempotency
- `X-Idempotency-Key` is `required: true` in all three specs (was only
required in fx-payment)
- Added the parameter to `updateUbo` PATCH (was missing entirely)
## Terminology sweep
- "partner" → "customer" across webhook spec descriptions, account spec,
subscribe.mdx (per the rule in CLAUDE.md)
- "users" → "account owners" in index.mdx and environments.mdx
- `FeeSource` enum value renamed `PARTNER` → `CUSTOMER`
- `INSUFFICIENT_OWNERSHIP` error message rephrased
- `CONTRIBUTING.md` removed (rules consolidated into CLAUDE.md)
## Webhook event types
- All event type strings standardized to `dot.lowercase` per the
Stripe / Svix industry convention
- Beneficiary events renamed `beneficiary.paymentInstruction.*`
(was bare `instruction`)
- Operation event scope explicitly limited to creation only (lifecycle
transitions tracked via polling — documented in journeys and overview)
- `EventType` enum values updated; MDX files renamed; docs.json updated
- `atTime` semantics documented (distinct from resource `createdAt`)
## TaxId aligned across services
- Beneficiary `TaxId` shape switched from `{type, number}` to
`{value, type, country}` to match account-owner shape
- Split into `TaxIdRequest` / `TaxIdResponse` schemas
## State.reason cleanup
- `OperationState.reason` and `InstructionState.reason` no longer required
(and no longer nullable); fields are simply omitted on success/non-terminal
states
## Withdrawal journey example fixed
- PIX field names corrected (`dictKey/dictKeyType`, not `pixKey/pixKeyType`)
- TaxId nested as object, not bare string
- Required `relationshipType` added
- PIX `asset` field added
## Cross-cutting docs improvements
- `X-Request-Id` header documented on every response (header component +
~92 inline references)
- 401 UnauthorizedError responses added to all secured fx-webhook ops
- `readOnly: true` on `id`, `createdAt`, `updatedAt`, `status` in response
schemas (better SDK codegen)
- Datetime examples aligned to live API format (no `.000Z` suffix)
- "Auth0 JWT" replaced with provider-agnostic wording in security scheme
descriptions
- OpenAPI version unified to 3.1.1
- `DepositFundingInstructionInput` renamed to `DepositFundingInstructionRequest`
- `filters` LHS-bracket syntax now exposed on every list endpoint per the
filtering principle
- 5 unused snippets deleted (only `money-format` retained)
# Backend follow-ups required
The docs are ahead of the live API on:
1. Money: `value` becomes decimal string, `decimalValue` field removed
2. `X-Idempotency-Key` enforced on all POST/PUT/PATCH (currently only fx-payment)
3. `FeeSource` emits `CUSTOMER` instead of `PARTNER`
4. `INSUFFICIENT_OWNERSHIP` error message text
5. `X-Event-Type` header emits dot.lowercase
6. Beneficiary events renamed `beneficiary.paymentInstruction.*`
7. `*State.reason` omitted on success (no longer `null`)
8. `direction`/`sortOrder`/`filters` parsing on listOperations,
listBeneficiaries, listUbos, listFundingInstructions
9. `{data, meta}` envelope on listUbos and listFundingInstructions
10. Beneficiary TaxId becomes `{value, type, country}`
11. Asset enum unified to 20 values across all services
12. `filters` LHS-bracket parser everywhere
13. `X-Request-Id` response header on every response
14. `PaginationIncludeTotalMatches` / `totalMatches` removed from public surface
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
The audit pass standardized X-Event-Type to dot.lowercase per Stripe/Svix convention. Reverting to match the live backend's existing pattern (ACCOUNT_ASSET_ACTIVATED, BENEFICIARY_PAYMENT_INSTRUCTION_*, OPERATION_REQUESTED) and the project's own enum-naming rule in .claude/rules/openapi.md. Updates the EventType enum and webhook keys in apis/fx-webhook/openapi.yml, the five MDX event reference pages (titles + openapi refs), the three webhooks narrative pages (overview, subscribe, verify-signatures), and the three journey pages.
Drops `country` from TaxIdRequest and TaxIdResponse in both fx-account and fx-payment. The `type` field already implies the country (CPF/CNPJ are Brazilian, CUIT/CUIL are Argentine, RUT_CL is Chilean, etc.), so country was redundant. Updates the schemas, the eight affected examples, the TaxIdType description, and the "country/type-specific validator" / "type and country" error prose. Also fixes a pre-existing YAML bug in fx-payment around line 2197 where a `description: >` block was emptied and the actual description text had slipped under `headers:`, breaking `mint validate`.
The text-formatting eval flagged the `Filters` parameter description in all three specs because `description: |` (literal block) preserves soft wraps as visible breaks in Mintlify. Switching to `>` (folded scalar) collapses the soft wraps to spaces and renders as one paragraph.
- fx-webhook: drop 401 responses from outbound webhook handlers (semantic bug — those POSTs are Trace→customer and never return Trace's auth envelope); update beneficiary event summaries to "Beneficiary payment instruction"; AmountEvent.asset now $refs Asset. - fx-payment: add TaxIdType enum (mirrors fx-account); switch TaxIdRequest/Response.type and four PaymentInstruction asset fields to $ref; add OperationList and BeneficiaryList; rewrite redundant getOperation description. - fx-account: add AccountList, FundingInstructionList, UBOList; rewrite inline list responses as $ref; copy Asset precision-table description from fx-payment. - journeys/withdrawal: drop country from taxId example (field was removed from the spec). - guides/principles/datetime: bump 2025 example to 2026. - .claude/rules/openapi.md: remove stale CONTRIBUTING.md reference.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sweeps the three OpenAPI specs (fx-account, fx-payment, fx-webhook), the guides, and the journey docs to align them with each other and with the live source. Most schema/wire-format changes need backend follow-up — the docs now describe the target state.
This PR resolves 22 distinct findings from a deep audit covering: pagination contract, money shape, terminology, idempotency, webhook event catalog, event-type naming, TaxId structure, state.reason contradictions, filtering principle, X-Request-Id documentation, readOnly annotations, and more.
Highlights
Pagination unified
PageMetadataschema across all three specs (previousCursor,nextCursor,total)limit,cursor,direction,sortOrder,filterslistUbosandlistFundingInstructionswrapped in{data, meta}envelopelimitaligned to 10totalMatchesandPaginationIncludeTotalMatchesdropped from public surfaceMoney switched to decimal strings everywhere
Amount.valueis now a decimal string in the asset's canonical scaledecimalValuefield (single source of truth)money.mdxrewritten withBigDecimal/Decimallibrary guidanceAsset enum unified
Assetenum, 20 values, across all three specs (was three separate enums with 7 / 16 / 20 values, two namedCurrencyand oneAsset)Idempotency
X-Idempotency-Keyisrequired: truein all three specs (was only fx-payment)updateUboPATCHTerminology sweep
FeeSourceenum:PARTNER→CUSTOMERINSUFFICIENT_OWNERSHIPerror message rephrasedCONTRIBUTING.mddeleted (rules consolidated intoCLAUDE.md)Webhook events
dot.lowercase(Stripe/Svix industry convention)beneficiary.paymentInstruction.*(was bareinstruction)atTimesemantics documented vscreatedAtTaxId
{type, number}to{value, type, country}to match account-ownerTaxIdRequest/TaxIdResponseState.reason cleanup
Withdrawal journey example fixed
The example was unusable: wrong PIX field names, bare-string TaxId, missing required fields. All four issues fixed.
Cross-cutting docs improvements
X-Request-Idresponse header documented (component + ~92 references)readOnly: trueon server-generated fields (id,createdAt,updatedAt,status).000Z)DepositFundingInstructionInput→DepositFundingInstructionRequestfiltersLHS-bracket syntax exposed per filtering principleBackend follow-ups required
The docs are now ahead of the live API on:
valuebecomes decimal string,decimalValueremovedX-Idempotency-Keyenforced on all POST/PUT/PATCH (currently only fx-payment)FeeSourceemitsCUSTOMERinstead ofPARTNERINSUFFICIENT_OWNERSHIPerror message textX-Event-Typeheader emits dot.lowercase stringsbeneficiary.paymentInstruction.**State.reasonomitted on success (no longernull)direction/sortOrder/filtersparsing on listOperations, listBeneficiaries, listUbos, listFundingInstructions{data, meta}envelope on listUbos and listFundingInstructions{value, type, country}filtersLHS-bracket parser everywhereX-Request-Idresponse header on every responsePaginationIncludeTotalMatches/totalMatchesremoved from public surfaceTest plan
mint validatepasses on all three OpenAPI specsmint broken-linkspassesmint accessibilitypassesmint devrenders the changed pages without errorsX-Request-Idappears on every operation response in rendered API reference pagesbeneficiary.paymentInstruction.*event type names