Skip to content

docs(api): comprehensive consistency audit pass#15

Merged
marioalvial merged 5 commits intomainfrom
docs/api-audit-pass
Apr 29, 2026
Merged

docs(api): comprehensive consistency audit pass#15
marioalvial merged 5 commits intomainfrom
docs/api-audit-pass

Conversation

@marioalvial
Copy link
Copy Markdown
Contributor

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

  • Single PageMetadata schema across all three specs (previousCursor, nextCursor, total)
  • All list endpoints now expose limit, cursor, direction, sortOrder, filters
  • listUbos and listFundingInstructions wrapped in {data, meta} envelope
  • fx-payment default limit aligned to 10
  • totalMatches and PaginationIncludeTotalMatches dropped from public surface

Money switched to decimal strings everywhere

  • Amount.value is now a decimal string in the asset's canonical scale
  • Dropped decimalValue field (single source of truth)
  • Aligned to industry pattern (Coinbase, PayPal, Circle, Binance) for hybrid fiat+crypto APIs
  • money.mdx rewritten with BigDecimal/Decimal library guidance

Asset enum unified

  • One Asset enum, 20 values, across all three specs (was three separate enums with 7 / 16 / 20 values, two named Currency and one Asset)

Idempotency

  • X-Idempotency-Key is required: true in all three specs (was only fx-payment)
  • Added missing parameter to updateUbo PATCH

Terminology sweep

  • "partner" → "customer" across webhook spec, account spec, subscribe.mdx
  • "users" → "account owners" in index/environments
  • FeeSource enum: PARTNERCUSTOMER
  • INSUFFICIENT_OWNERSHIP error message rephrased
  • CONTRIBUTING.md deleted (rules consolidated into CLAUDE.md)

Webhook events

  • Event type strings standardized to dot.lowercase (Stripe/Svix industry convention)
  • Beneficiary events renamed beneficiary.paymentInstruction.* (was bare instruction)
  • Operation event scope explicitly limited to creation only; lifecycle = polling
  • atTime semantics documented vs createdAt

TaxId

  • Beneficiary TaxId switched from {type, number} to {value, type, country} to match account-owner
  • Split into TaxIdRequest / TaxIdResponse

State.reason cleanup

  • Reason no longer required (no longer nullable); omitted on success/non-terminal states

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-Id response header documented (component + ~92 references)
  • 401 responses on all secured fx-webhook ops
  • readOnly: true on server-generated fields (id, createdAt, updatedAt, status)
  • Datetime examples aligned to live format (no .000Z)
  • "Auth0 JWT" replaced with provider-agnostic wording
  • OpenAPI version unified to 3.1.1
  • DepositFundingInstructionInputDepositFundingInstructionRequest
  • filters LHS-bracket syntax exposed per filtering principle
  • 5 unused snippets deleted

Backend follow-ups required

The docs are now ahead of the live API on:

  1. Money: value becomes decimal string, decimalValue 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 strings
  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 services
  12. filters LHS-bracket parser everywhere
  13. X-Request-Id response header on every response
  14. PaginationIncludeTotalMatches / totalMatches removed from public surface

Test plan

  • mint validate passes on all three OpenAPI specs
  • mint broken-links passes
  • mint accessibility passes
  • mint dev renders the changed pages without errors
  • Spot-check the rewritten withdrawal create-beneficiary example matches the OpenAPI schema exactly
  • Spot-check that X-Request-Id appears on every operation response in rendered API reference pages
  • Confirm event MDX pages render with the renamed beneficiary.paymentInstruction.* event type names
  • Confirm pagination response examples render uniformly for listAccounts / listOperations / listSubscriptions

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
@mintlify
Copy link
Copy Markdown

mintlify Bot commented Apr 29, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
tracefinance 🟢 Ready View Preview Apr 29, 2026, 1:36 PM

💡 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.
@marioalvial marioalvial merged commit c8f00c2 into main Apr 29, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant