x-api-version header and upgrade on your own schedule — new versions are additive and opt-in.
Why versioning
The API evolves as Rhinestone adds chains, settlement layers, and new intent patterns. Versioning lets us ship those changes without forcing every integrator to migrate in lockstep. We use dated versions (YYYY-MM.name) rather than semver-style major versions. Semver majors tend to hoard changes into rare, big-bang releases — each bump looks like a migration project, so teams avoid shipping them. Dated versions normalise small, frequent bumps, so each one carries a small diff.
The .name suffix gives each release a human handle. We name versions after mountains, one per letter — alps, blanc, caucasus, and so on. It’s easier to say “switch to Caucasus” than “switch to 2026-09”.
Pinning a version
The direct HTTP guides use Caucasus. Pin it by sendingx-api-version on every request, including submission and reads:
YYYY-MM.name. Always send the header — requests without it fall back to the deprecated 2026-01.alps shape, and unknown or malformed values return 400 VALIDATION_ERROR.
Compatibility
What we can change without a new version
Within a version, we treat the response schema as open. These changes ship freely:- New optional request fields
- New response fields
- New enum variants in responses (e.g. a new
settlementLayer) - New endpoints
- Widened request validation
- Changed default values
What your client must do
To consume those changes safely:- Ignore unknown fields. If you use a strict JSON parser (Go’s
DisallowUnknownFields, Rustserde(deny_unknown_fields), Jackson’sFAIL_ON_UNKNOWN_PROPERTIES), disable it for our responses. - Handle unknown enum values gracefully. A
switchonsettlementLayerthat throws on default will break the day we add a new one. Treat unknown values as “not supported by this client” and fall back. - Preserve native signing payloads. On Caucasus, dispatch on each
signingRequests[].payload.kindand return proofs in the same order. For EIP-712, forward the suppliedtypedDatatowallet.signTypedData()without reconstructing its types. See signing requests and proofs. - Treat quote 404s as normal. Quoted intents are stored server-side with a short TTL. If a quote expires or the quote store restarts, you’ll see 404 on submit. Re-quote — don’t retry the submit.
- Take
routes[0]unless you have your own criteria. The array is server-ranked by a cost/speed tradeoff. Re-sorting client-side usually degrades route quality.
What triggers a new version
- Removing or renaming any field
- Adding a required request field
- Changing a field’s type
- Restructuring request or response shape
- Narrowing request validation
- Making a required response field optional or nullable
- Removing an endpoint
Deprecation lifecycle
Fields deprecated in version N remain present and documented as deprecated; they’re removed in N+1. Versions themselves are not routinely deprecated — each version is intended to stay live indefinitely so you never have to migrate on our clock. The one exception is2026-01.alps, which will be sunset after integrators migrate to blanc. The shape difference between the two is large enough that maintaining both long-term isn’t practical. Future version transitions will follow the standard per-field deprecation rule.
Versions
2026-09.caucasus
Caucasus introduces per-VM accounts, explicit source and destination assets, native execution, and ordered signing requests and proofs.
The endpoint paths stay the same:
POST /quotesPOST /quotes/estimatePOST /intentsGET /intents/{id}GET /intents
Migrating from Blanc
This section covers direct HTTP integrations, not changes to the SDK’s methods or configuration. Pin Caucasus on every request, including submission and reads:postBlanc, postCaucasus, getBlanc, and getCaucasus HTTP helpers. Each sends the corresponding version header and rejects non-2xx responses.
Restructure quote requests
Caucasus names one funding pair insource and one delivery asset in destination. Replace source allowlists and destination token arrays with explicit chain and token fields.
If your Blanc integration relied on automatic or multi-source funding, choose the source chain/token pair before requesting a Caucasus quote. Do not translate an allowlist by silently taking its first entry.
Amounts, caps, auxiliary funds, and EVM call values use decimal strings in their respective base units.
For binding quotes:
source.maxAmountoptionally caps the observed source balance available to the planner. It is not an exact-input amount.destination.amountspecifies the requested output. Omit it for max-out.- Omit
destination.tokenonly when there is no token delivery. source.amountbelongs to estimates, not binding quotes.
Configure accounts per VM
Replace the flat EVM account withaccount.evm. An address-only entry is a receiver, not a spending account: include type when the account must fund or execute the intent.
signatureMode remains a numeric enum, not a string such as "ECDSA". Simulation stubs and setup operations belong to ERC-7579 accounts.
Solana spending uses account.svm. For a standalone, already-created Swig:
address is the asset-holding wallet; swigAccount is the state account containing its roles. They are not interchangeable. P-256 authorities use kind: "secp256r1" with their compressed publicKey.
You can supply EVM and SVM entries together, but this does not authorize arbitrary wallet pairings. The orchestrator checks the supported pairing, account identity, and signing authority.
Move destination execution
Group execution with its destination:
For EVM calls:
to, value, and data. Preserve call order.
An explicit receiver is destination.recipient: { address }. Configured EVM recipients use the same lower-case account types and nested setup/delegation fields, but do not carry the spender’s signatureMode.
Solana delivery requires a recipient. Solana execution instead runs from the configured Swig: omit recipient and encode any payee in the instructions. Tron and Stellar destinations are delivery-only.
A request without source is restricted to no-delivery intents with effective sponsorship covering the applicable orchestrator costs. It cannot fall back to another account balance. Sponsorship does not fund arbitrary caller-authored EVM call value.
Read the quote plan and requirements
Blanc returns{ routes }. Caucasus returns { status: "quoted", routes }.
purpose:
execution: token delivery or execution.deployment: a separate account-creation intent.
plan.source, plan.destination, and plan.deployments before signing. Execution disclosures identify whether the account or a solver runs the caller’s calls. A plan describes intended behavior, not completed execution or every transaction-internal operation.
requirements[] replaces the chain-keyed tokenRequirements map:
erc20Approvalnames the account, chain, token, amount, and spender.wrapNativenames the account, chain, token, and amount.
status: "quoted" does not mean nonempty requirements are already fulfilled.
Route ranking, expiry, and the existing cost.input, cost.output, and cost.fees structure remain. Caucasus presents same-chain routes as SAME_CHAIN, including smart-account routes that Blanc labelled INTENT_EXECUTOR. When present, bridgeFill.destinationChainId is a chain-reference string.
Sign requests and submit ordered proofs
Replace role-specific signature slots with one ordered array:payload.
Do not sort, deduplicate, or omit requests—even when two payloads are identical. Proof count, order, and kind must match the selected route’s requests.
This example assumes preflight requirements are satisfied and every signing request uses the same EOA with EIP-712 signing, without EIP-7702 delegation:
payload.kind:
For WebAuthn, send
credentialId as base64url, authenticatorData as hex, the original UTF-8 clientDataJSON, and the P-256 signature as 64-byte hex r || s, not DER. Do not parse and serialize clientDataJSON again.
For an account-verified origin request that needs two signature encodings, Blanc’s { preClaimSig, notarizedClaimSig } becomes:
authorizations.sponsor and authorizations.recipient bags disappear. Answer the corresponding EIP-7702 requests in proofs[]. Caucasus requests concrete-chain authorizations; a configured delegation default is not an any-chain authorization proof.
Honor every returned validity constraint as well as route expiry. A Solana slot deadline can expire before route.expiresAt. Never reconstruct or rewrite native signing payloads: their chain values retain native formats, including numeric EIP-712 and EIP-7702 chain IDs.
Submission still returns { intentId }. That acknowledges submission, not completion. Poll the intent before starting a replacement when the submission outcome is uncertain.
Update sponsorship
Renameoptions.sponsorSettings to options.sponsorship:
false settings, and array order. Omit an absent source; use {} for absent options.
Do not reuse a Blanc digest. The approval-contract identifier is distinct from the HTTP version header and must match exactly.
See sponsorship for policy configuration.
Update intent reads
Continue pollingGET /intents/{intentId}. Add ?full=true for extended details. Overall statuses remain PENDING, COMPLETED, and FAILED.
For transaction links:
vm:
Known chain references use strings such as
eip155:8453 or solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp. Blanc quote requests already used chain-reference strings; its read/list projections used numeric chains.
Historical records that cannot be mapped to a known chain can retain numeric chain IDs and vm: "unknown". Do not invent an EVM chain reference for them.
Full details retain nonce in hex and add optional deployment summaries. Keep intentId as a string; it can exceed JavaScript’s safe integer range.
Treat missing historical accounts, authorities, executions, or deployment data as unavailable—not as empty data or proof that nothing happened. Execution details describe intended execution, not per-call results.
refunds: [] means no refund has been observed, not that a failed intent can never be refunded. A transaction reference alone is not proof of finality.
Recorded cost amounts remain integer micro-USD. details.cost.sponsored describes recognized sponsorship coverage and can be true while billed amounts are zero or absent.
Update intent lists
GET /intents keeps its { data, pagination } envelope.
value.side distinguishes planned output from retained input. The summary is not a wallet balance change, realized swap result, or proof of delivery. value is omitted when no single amount truthfully represents the intent, including deployment-only and historical multi-token cases.
Pass pagination.nextCursor back unchanged as cursor; it is not an intent ID. Caucasus lists can include non-EVM accounts that Blanc excludes, so identical pagination requests need not return identical records.
Migrate estimates
POST /quotes/estimate uses the same source/destination grouping, but its account descriptors are hypothetical. They contain account types, not wallet addresses or signing configuration.
For exact-out, remove the source amount and set the destination amount:
direction, amountIn, or amountOut. Supplying both amount sides—or neither—is invalid.
Estimate responses move financial fields into cost:
output likewise becomes cost.output[]. The response reports the account assumptions used.
source.assumptions.deployed applies to the source ERC-7579 account. Omission assumes undeployed; the field is ignored for EOA and Swig accounts.
Estimates do not accept quote-only caps, auxiliary funds, recipients, or execution. They do not apply actual destination-balance credit and return no executable intent ID or signing requests. Obtain a binding quote before signing or submitting.
Migrate HyperCore actions and outcomes
HyperCore is a native destination variant:actions[] array. A former singular options.hyperCore.action becomes a one-element array. Keep caller-authored HyperEVM calls in execution.settlement, separate from Core actions.
Preserve hypercore:spot versus hypercore:perp. Neither is interchangeable with HyperEVM’s eip155:999 settlement chain or a signing-domain chain ID. USDC delivery addressing and units remain unchanged.
On reads, replace hyperCore.outcome with the aggregate venue operation:
destinationChainId can name the HyperCore venue while value.chainId names HyperEVM.
accepted means the exchange accepted the action, not that an order filled completely. Reconcile unknown and partial outcomes against HyperCore before retrying; blindly repeating a batch can duplicate successful orders.
Respect capability boundaries
A schema variant does not guarantee an available route. Chain/token support, account authority, settlement providers, sponsorship, and environment configuration still apply.
A missing Swig needed for spending returns
SOLANA_ACCOUNT_NOT_CREATED. Quoting does not silently create it.
Separate sponsored Swig creation uses an ordinary status: "quoted" response with a purpose: "deployment" route. Rent is disclosed separately in deploymentCosts; signingRequests is empty and submission uses proofs: [].
This is not automatic creation-plus-spend or a deploymentRequired/re-quote response. Creation trusts the supplied root authority: verify it before creating or funding the wallet. Do not assume it is safe to fund an undeployed Swig.
Sponsored Swig authority changes are separate typed operations, not arbitrary caller instructions. Existing role permissions and lockout protections still apply.
Migration checklist
Before switching traffic:- Pin Caucasus on quote, estimate, submit, and read requests.
- Select one funding pair and preserve the intended balance-credit behavior.
- Review the route plan and fulfill preflight requirements.
- Handle supported signing kinds without changing payloads or proof order.
- Update intent-bound sponsorship bindings alongside request bodies.
- Parse native transaction references and tolerate unavailable historical data.
- Reconcile uncertain submissions and HyperCore outcomes before creating replacement intents.
2026-04.blanc
The previous contract used by Blanc integrations. Keep this header when continuing to use Blanc request and response shapes; follow the Caucasus migration to upgrade. The endpoint reference documents Caucasus; Blanc’s schema is in the published 2026-04.blanc OpenAPI document.
What changed:
- Flat
routes[]array. Each route carries its ownintentId,cost,signData, andtokenRequirements(EOAs only — smart accounts handle approvals internally). Pre-ranked;routes[0]is recommended. - CAIP-2 chain ids. Every chain id on the wire is now an
eip155:<chainId>string —1becomes"eip155:1". Affects scalar fields, arrays, and chain-keyed maps. Path parameters are unchanged. - EIP-712 typed data in the response. Forward
signData.origin[]andsignData.destinationdirectly towallet.signTypedData(). No more client-side type reconstruction. - Server-stored intents.
POST /quotesreturns anintentId; the full intent stays server-side. Submit viaPOST /intentswith{ intentId, signatures }— no more round-trippingintentOp. - Resource-style endpoints.
POST /quotes(was/intents/route),POST /intents(was/intent-operations),GET /intents/:id(was/intent-operation/:id),POST /intents/splits(was/intents/split). - Flattened cost structure. One
costobject per route withinput,output, andfees: { total, breakdown }. Replaces scatteredtokensSpent/tokensReceived/feeBreakdownUSD/gasCost/sponsorFee. - Submit response collapsed.
POST /intentsreturns just{ intentId }(was{ result: { id, status } }). The synthesisedstatus: "FAILED"is gone — simulation failures now surface as 4xx with the unified error envelope. - Field renames. Notable:
destinationGasUnits→destinationGasLimit,sponsorSettings.{gas,bridgeFees,swapFees}Sponsored→{gas,bridgeFees,swapFees},userAddress→accountAddress. Portfolio token shape usessymbol(wastokenName),chains(wastokenChainBalance), and per-chainaddress/decimals(weretokenAddress/tokenDecimals). Timestamps move fromBigIntLikestrings to integer Unix seconds. - Unified error envelope. All non-2xx responses share
{ code, message, traceId, details? }. Switch from message-pattern matching tocode-based dispatch. - Schema trimming.
Account.mockSignatureis gone — use the per-chainAccount.mockSignaturesmap.AccountType.SMART_ACCOUNTis gone — useERC7579. TheaccountAccessListflat-array variant is gone — use the structured shape. - Compact / resource locks removed. No blanc equivalent for
topupCompact,emissaryConfig,MultichainCompactorigin signatures, or the/withdrawalsendpoints.
Migrating from alps
Quote and submit
PRECONFIRMED is gone; if your client branches on it, drop that case.
Splits endpoint
POST /intents/split → POST /intents/splits. Request and response shapes follow the same blanc-wide rules (CAIP-2 chain ids, unified error envelope).
Chain ids
CAIP-2 strings (eip155:<chainId>) replace numeric chain ids on every field that carries one — chainId, sourceChainId, destinationChainId, chainIds, allChainIds, and chain-keyed maps like auxiliaryFunds, preClaimExecutions, chainTokens, and tokenRequirements. Path parameters are unchanged.
tokens keyed as chain:address:
Timestamps move from
BigIntLike strings ("1700000000") to integer Unix seconds (1700000000).
Sponsor settings
AccountType.SMART_ACCOUNT is gone — use ERC7579. The flat accountAccessList array shape is gone — use the structured shape. Mock signatures move from a single Account.mockSignature to a per-chain Account.mockSignatures map.
Retry-After on 429 TOO_MANY_REQUESTS.
Error codes
The list is extensible — add unknown codes to a generic fallback path.
Things you can’t migrate
The Compact / resource-lock surface has no blanc equivalent. If your integration depends ontopupCompact, emissaryConfig, the /withdrawals endpoints, or MultichainCompact origin signatures, stay on alps until a replacement ships.
2026-01.alps
The original release. Intents are round-tripped through the client, signed via client-reconstructed EIP-712, and submitted with the full intentOp attached to signedIntentOp. The Compact / resource-lock surface (topupCompact, emissaryConfig, /withdrawals, MultichainCompact signatures) is only available on this version — stay on alps if you depend on it.