Skip to content

docs(routing): document optimistic provider queue (#1013) - #25

Open
chibie wants to merge 6 commits into
mainfrom
feat/paycrest-docs-update-f6b18c
Open

docs(routing): document optimistic provider queue (#1013)#25
chibie wants to merge 6 commits into
mainfrom
feat/paycrest-docs-update-f6b18c

Conversation

@chibie

@chibie chibie commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Documents the ranked provider queue resolved at order creation, from paycrest/aggregator#1013.

Important

Do not merge before aggregator#1013 merges. That PR is still open. Every literal "3" in these docs tracks utils.DefaultProviderQueueSize, and the validation error strings are fmt.Sprintf'd from it — if the constant or any wording changes before merge, these tables drift silently. Worth a re-diff against the merged SHA.

What changed

Specs

  • openapi-v2.yaml — new limit query param on the rates path (integer 1–3, default 3); V2RateQuoteSide.providerIds rewritten for ranked semantics, and rate now states it belongs to providerIds[0]; providerIds added to V2FiatDestination; third request example showing a queue passed through from a quote. Also filled in the missing description on V2CryptoDestination.providerId while in there.
  • openapi-v1.yamlproviderIds on PaymentOrderRecipient. v1 rates left untouched: a scalar data cannot carry a ranked list.

Prose

  • api-reference/general/get-token-rate.mdxlimit row and example, ranked response table + 3-element sample, new ### The provider queue section under Rate resolution.
  • implementation-guides/sender-api-integration.mdx — new ### Pin a provider queue with the rules table and all seven verbatim 400 messages; prefetch note and JS/Python samples now pull providerIds.
  • implementation-guides/smart-contract-interaction.mdx — new ### Routing fields plus a <Warning> on the tightened message-hash budget.
  • resources/troubleshooting.mdx, api-reference/errors.mdx, resources/changelog.mdx.

No docs.json change — no new pages, matching the precedent of #15 and #21.

Notes for reviewers

The byte-budget change is the one integrators will actually feel. Everything else here is additive. But the recipient encryption preflight now reserves room for a full 3-provider queue on every order — including orders that never send providerIds, because one may be resolved onto the order and rides in the message hash at gateway submit. That leaves ~49 fewer bytes (~41 when pinning a providerId) inside the 500-byte cap for accountIdentifier + accountName + memo + metadata. A payload that passed yesterday can start returning 400 "Recipient data too large for encryption" with no client-side change. It gets a <Warning>, a troubleshooting entry, and a Behavior change: lead in the changelog — soften that framing here if it reads too loud.

providerIds is marked writeOnly in both specs. The field is accepted on create but no response builder ever populates it — orders and webhooks return only the singular assigned providerId. Without writeOnly the generated playground would show it in create/GET/webhook response examples, which would be wrong. Note V2FiatDestination is $ref'd from three response schemas, and v1's PaymentOrderRecipient is reachable from a v1 GET response, so this applies to both.

Three places where the docs deliberately say something non-obvious:

  • Queue exhaustion is not an immediate refund — fallback assignment runs first, then the refund window. "3 tries then refund" is the natural wrong assumption, so it's stated explicitly in four places.
  • OTC quotes still return exactly one providerIds entry, same as pinned quotes.
  • An unusable queue inside an onchain message hash is dropped silently and the order routes as unpinned — no onchain rejection, no error webhook. Called out so onchain senders know to validate against a quote before encrypting.

Onramp is excluded throughout: V2CryptoDestination accepts only the singular providerId, and an onramp providerIds is silently ignored by binding.

Verification

  • Both specs parse; redocly lint findings are byte-identical to main (19 errors / 65 warnings, all pre-existing) — nothing new introduced.
  • mint broken-linksno broken links found, including the three new cross-page anchors.
  • Not yet verified against a running API — the feature isn't deployed. Once aggregator#1013 hits staging, worth confirming ?limit=0 / ?limit=4 return the documented 400 string verbatim, and that create/GET responses genuinely omit providerIds.

🤖 Generated with Claude Code

chibie and others added 6 commits August 12, 2026 00:37
Documents the ranked provider queue resolved at order creation
(paycrest/aggregator#1013).

- GET /v2/rates: new `limit` query param (1-3, default 3); `providerIds`
  now returns up to 3 ranked ids per side instead of 0 or 1
- Order creation: `destination.providerIds` (v2 offramp) and
  `recipient.providerIds` (v1), marked writeOnly since neither is echoed
  back in responses or webhooks; full validation-error table
- Onchain: `providerIds` in the encrypted recipient, plus a warning that
  the 500-byte message-hash budget is now ~49 bytes tighter on every
  order — payloads that previously passed can start failing
- Notes throughout that queue exhaustion falls through to fallback
  assignment, not an immediate refund

v1 rates left untouched: a scalar `data` cannot carry a ranked list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolves a changelog conflict: both sides prepended a Q3 2026 entry.
Kept both, newest first — optimistic provider routing (August) above
senderFeeAddress (July).

All other files auto-merged. Verified afterward that the network enums
picked up starknet/tron from main with the new `limit` param intact,
and that none of the three create-order examples carry a sender fee,
so none need the new `senderFeeAddress`.
Removes every mention of OTC across the docs, and rewrites the provider
queue prose to describe current behavior directly instead of contrasting
it with how routing used to work. The changelog keeps its before/after
framing, which is the point of that page.

Notable: `orderType` enums in openapi-v2.yaml drop `otc`, leaving
`enum: [regular]`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Stops steering readers to providerId as the workaround for restricted
and fallback providers, and reframes it as the backward-compatible
single-provider form throughout. A one-entry providerIds is now the
documented way to route to a single provider.

The eligibility constraint is still stated (it is a real 400), just
without pointing at providerId as the alternative.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The docs describe the production API, so naming which environments run
the recipient size check is noise for the reader and an internal detail
besides. The constraint itself is unchanged.
Amends the queue docs for the follow-up that gave providerIds full pin
parity (paycrest/aggregator#1020, merged).

- Restricted providers are queueable by the senders their list names,
  rather than rejected outright
- A fallback entry is accepted and ignored; the "cannot be queued
  explicitly" error is gone
- A one-entry queue is exactly a pin, which is what lets integrators
  use providerIds everywhere and never reach for providerId
- Onramp accepts destination.providerIds, capped at one entry
- New behaviour change: pinning an onramp order to a provider
  restricted to other senders now 400s, and this applies to the
  singular providerId too

Folded into the existing changelog entry rather than added as a second
one -- neither PR has shipped to readers, so there is no before/after
to describe, except the onramp authorization change, which existing
providerId users will feel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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