BUILDER_FEE; revenue-share credits use
REVENUE_SHARE. Claiming moves the reserved balance into a spendable trading
balance.
A claim is a ledger-only move: it debits the payout bucket and credits the
payout wallet’s trading balance under the authenticated application. There is no
on-chain transaction and no gas, and the credited funds are immediately
tradeable. To take the money off the exchange, claim it and then use the
ordinary withdrawal flow.
For taker-side attribution, how the revenue share is reported, and
payout-address rotation behavior, see the
BuilderCodes developer guide.
All BuilderCodes methods require an authenticated, non-delegated session. No program switch gates reads or claims, so a balance already credited stays claimable;
setBuilderFee needs the revenue share or builder fees switched
on. Application-level reads derive
the application from the session and require the authenticated wallet to match
its configured payout address; no method accepts a caller-selected application
or payout wallet.
() => Promise<GetBuildercodesConfigResponse>
Read the authenticated frontend’s current BuilderCodes state.Returns:
applicationId: string — authenticated application UUIDenrolled: boolean — whether the application is currently enrolledpayoutAddress?: string | null — the configured payout wallet. A string is the address: use it.nullandundefinedare the two spellings of “none configured” and are the pair to normalize together — never fold a returned string in with them. In practice a successful response always carries an address, because this endpoint authorizes the caller as that wallet and refuses with403when none is set; the type admits the absent forms so a nullable wire shape cannot throwbuildercodesEnabled: boolean — whether the revenue share is on. This read is not gated by it, so a successful response can reportfalsebuildercodesBudgetBps: number — the configured target share of Monaco’s protocol fee on each taker fill, in basis points from0to10000. It is what the application is configured to earn, not what any given trade paid out — a payout row’sappliedBpsis the realized rate for that fill and may be lowerbuilderFeeEnabled: boolean — whether stored builder fees are currently activebuilderFeeBps: number — the stored builder fee in basis points, including while builder fees are disabledbuilderFeeCapBps: number — the current maximum accepted fee, never above100changesRemaining: number —BUILDERchanges still available in the rolling 24-hour window, from0to2nextChangeAllowedAt?: string | null — RFC 3339 time for the next allowed change when none remain
401 (not authenticated), 403 (a delegated session, or a wallet that is not the application’s payout address), 404 (application not found), 429 (enforced read budget exhausted), or 500 (internal error).(params: SetBuilderFeeParams) => Promise<SetBuilderFeeResponse>
Set the authenticated frontend’s builder fee.
bps is required, an integer from 0 through 100; a real change must also be at or below the current builderFeeCapBps. Explicit 0 clears the fee.The application must be enrolled with a payout address. At most two frontend changes are allowed in a rolling 24 hours; Monaco administrator changes do not count. Setting the current value succeeds without a log row, email or consumed change, even when changesRemaining is 0 or the live cap is below that stored value. A value may be stored while builderFeeEnabled is false as long as the revenue share is on; the call is refused only while both are off. Charging is capped at the live cap and requires enrollment. A newly stored fee reaches order requests within seconds. Sequencer ordering is authoritative for the builder-fee gate and enrollment: an order processed before one of those sequenced changes uses the earlier state, and a later order uses the new state. Builder fees are charged on taker fills only, so a resting remainder that later fills as maker pays none. Each positive charged fee is credited to the application’s payout balance as a BUILDER_FEE payout.Returns: builderFeeBps, previousBuilderFeeBps, changesRemaining, and nullable/absent nextChangeAllowedAt.Throws: 400 for missing/invalid bps or a real change above the cap; 401 without valid authentication; 403 when neither the revenue share nor builder fees are switched on, the session is delegated, or the caller is not the application’s payout wallet (including when none is configured); 404 when the application is absent; 409 when enrollment is incomplete after ownership passes or the change limit is exhausted; 500 on an internal failure. A limit response carries details.reason: "builder_fee_change_limit" and details.nextChangeAllowedAt. Server keys are not accepted. A maintenance block returns 503 before the write.(params?: ListBuilderFeeChangesParams) => Promise<ListBuilderFeeChangesResponse>
List builder-fee changes newest first.
pageSize? defaults to 20 and is at most 100; pass an opaque pageToken? from the prior nextPageToken to continue.Returns: changes, each with actorType ("BUILDER" or "ADMIN"), actor, oldBps, newBps, and RFC 3339 createdAt, plus nextPageToken (empty at the end). For BUILDER, actor is the payout wallet. For ADMIN, it is the Monaco operator’s email address.Throws: 400 for invalid pagination; 401 without valid authentication; 403 for a delegated session or a caller that is not the application’s payout wallet; 404 when the application is absent; 429 when the enforced read budget is exhausted; 500 on an internal failure. Server keys are not accepted.(params?: ListBuildercodePayoutsParams) => Promise<ListBuildercodePayoutsResponse>
List the authenticated application’s per-trade credits, newest first across persistor batches — see the ordering note below for what that does and does not guarantee inside one batch.Parameters:
pageSize? defaults to 20 and is at most 1000, and the server rejects a value out of range with 400 rather than clamping it. pageToken? is an opaque cursor: omit it (or send "") to start from the newest credit, then pass the prior response’s nextPageToken to continue. Page-number pagination was removed: there is no page, the SDK rejects a leftover one before a request is sent, and the server answers 400. kind? is "REVENUE_SHARE" or "BUILDER_FEE" and filters the list; omit it for every credit. The SDK rejects any other value before a request is sent, and the server returns 400 for one.Ordering change. The cursor walks (createdAt, id) descending. That key is total and stable — a page can neither skip nor duplicate a credit — but it is not chronological inside one persistor batch: createdAt defaults to the transaction-start NOW(), so every credit one batch writes shares a timestamp, and the id tie-break is a random UUID. Within a batch the order is therefore arbitrary, and a later fill can appear ahead of an earlier one. The removed page-number order led with the durable-log sequence and its ordinal precisely because those carry the engine’s fill order, and one entry routinely holds several credits (a taker sweeping several makers, or a flattened batch create). Across batches the order is still newest-first.Throws: 400 (invalid pagination or kind), 401 (not authenticated), 403 (a delegated session, or a wallet that is not the application’s payout address), 404 (application not found), 429 (read budget exhausted), or 500 (internal error).Returns: payouts, the opaque nextPageToken (empty once the walk is exhausted — it is one ordered read, so a short page is definitive), plus numeric total, pageSize and totalPages fields; with kind, the counts cover that kind only. Each payout contains tradeId, the payoutAddress at credit time, token, RAW atomic-unit amount, appliedBps, RFC 3339 createdAt, and kind. For BUILDER_FEE, appliedBps is the normalized builder-fee rate charged to the taker. For REVENUE_SHARE, it is the realized truncated whole-bps rate for that fill and may be lower than buildercodesBudgetBps.() => Promise<GetBuildercodePayoutSummaryResponse>
Summarize earnings without combining unlike tokens.Returns: numeric
totalPayouts, nullable/absent lastCreditedAt, byToken, and byTokenAndKind. Each byToken total contains token, RAW atomic-unit totalAmount, numeric payoutCount, and RFC 3339 lastCreditedAt, summed across both payout kinds. byTokenAndKind splits the same totals by kind (REVENUE_SHARE or BUILDER_FEE), one row per token and kind with at least one credit; a token’s rows add up to its byToken total. With no payouts, totalPayouts is 0, both lists are empty, and lastCreditedAt is null/absent.() => Promise<GetBuildercodeRewardsBalanceResponse>
Read the authenticated wallet’s reserved BuilderCodes balances. The bucket is derived server-side from that wallet; current enrollment is not required, so a former payout wallet can still inspect and claim what it accrued.Returns:
balances, one { token, available } entry per token with a non-zero available RAW atomic-unit balance, or an empty array.(params: ClaimBuildercodeRewardsParams) => Promise<ClaimBuildercodeRewardsResponse>
Move accrued BuilderCodes payout balance out of your reserved payout bucket and into a
trading balance.Requires authentication. The payout bucket is resolved server-side from the authenticated
caller’s own wallet address — it is never taken from the request body — so a caller can
only ever claim their own accrued balance.Parameters:
ClaimBuildercodeRewardsParams:token: string — payout token contract address (0x-prefixed). BuilderCodes shares accrue in the quote token of the traded pair.amount: string — amount to claim, in RAW atomic units of the token. Must be a positive integer and no greater than the accrued balance; an over-claim is rejected rather than partially filled.
ClaimBuildercodeRewardsResponse:payoutBalance: string — your payout-bucket balance after the claim, RAW atomic unitstradingBalance: string — your trading balance for the token after the claim, RAW atomic units
403when the session is a delegated agent — a permanently unsupported session type for claims, not a rollout state.409when the payout balance is insufficient for the requested amount — including when the wallet has never accrued a share429when the per-user movement budget the claim shares with withdrawals and collateral transfers is enforced and spent. It is refused before the claim reaches the sequencer, so nothing committed and it is safe to retry afterretryAfter503when the matching engine is unreachable, restarting, or slow to answer — and, more broadly, any untagged5xxor a transport failure that returned no response at all. The outcome is unknown, not a rejection — the claim is admitted before its reply is sent, so it may still commit, and with no idempotency key a blind retry can claim twice. Do not retry automatically, and do not settle it with a balance read — an admitted claim may still be queued, so an unchanged balance does not prove it will not commit. Treat the claim as pending and reconcile before issuing another. The SDK backs that up: it clearsretryableon every failure whose outcome it cannot decide — any status at or above500, and a failure with no status at all because the response was never seen — against its usual “every 5xx is retryable” rule, so retry logic driven off that flag cannot claim twice.- Two exceptions stay retryable, because both are refused before the claim can be admitted and so committed nothing: a maintenance block (
error: "OPERATIONS_BLOCKED") and a sequencer overload (code: "OVERLOADED"). An overload is the one 503 that positively wants a retry with backoff. Every4xxalso keeps its own classification, being a decided outcome.
Who can claim
The claim is authorized for the payout wallet itself, and it moves only that wallet’s balance. Three consequences are worth knowing before you integrate:-
The payout wallet may be an EOA or a smart-contract wallet. An EOA answers
Monaco’s signature challenge directly. A multisig such as a Safe holds no
private key and authenticates by EIP-1271 contract signature instead, with
Monaco asking the wallet contract whether it accepts the challenge. That path
is offered only to a wallet holding a BuilderCodes payout bucket, only while
contract_wallet_auth_enabledis on, and only where the deployment has a chain RPC endpoint configured; while any of those is unmet, login is EOA-only and a contract payout wallet can call neither this endpoint nor the withdrawal flow that follows. While that path is enabled, challenges stay valid for 30 minutes rather than 5 — for every address, not only eligible ones, so the unauthenticated challenge response cannot reveal which addresses hold a payout bucket — since collecting owner approvals takes longer than a single click. - A wallet that never earned a share has nothing to claim. There is no separate “not enrolled” error; an empty bucket and a bucket that never existed both report an insufficient balance, because in both cases there is no balance to move.
- Payout-address changes are not retroactive, and claiming follows that. When a frontend changes its configured payout address, future shares accrue to the new wallet while everything already accrued stays with the old one. Claiming deliberately does not require current enrollment, so the previous wallet can still claim what it earned while it was the payout address.

