Skip to main content

Integrator Fees and Payouts

With an integrator key you can charge your own fee on the trades your users make through you, then claim what you have earned. The fee is taken inside the trade, every settled trade records it, and you pay yourself out in USDC, on demand, to an address Treasures registers for you.

How it works​

  1. Treasures configures your fee. Your key carries a default fee and a ceiling, both agreed with your Treasures contact.
  2. You quote with your key. Every quote you request with X-API-Key charges your default fee. Send integrator_fee_bps to use a different fee on one quote.
  3. The trade pays it. The fee is stacked into the same on-chain fee as Treasures' own, so the quoted output already allows for it. Nothing extra is signed.
  4. You submit with the same key. A quote that carries your fee can only be submitted with the key that requested it.
  5. Settled trades record it. Each trade's fee appears in GET /settlements as an integrator_fee entry.
  6. You claim it. POST /payouts sends everything you are owed to your registered address.

Setting your fee​

integrator_fee_bps is accepted on POST /quote/buy, POST /quote/sell and POST /quote/preview. It is your fee on that quote in net basis points (0 to 10000), up to your ceiling.

  • Omit it to charge your configured default. Send 0 to charge nothing on that quote.
  • It needs your key. A non-zero value without X-API-Key is refused.
  • It is net. On Solana the execution venue keeps half of the fee it collects, so the trader is charged twice your figure there and you net the figure you sent.
  • The quote shows it. Every leg reports cost_breakdown_bps.integrator_fee_bps beside treasures_fee_bps, and estimated_output_* is already net of both. It reads 0 on an anonymous quote, and on a leg whose venue could not collect a fee.
  • Submit with the same key. A quote with a non-zero fee on any leg must be submitted to POST /trade/submit with the key that quoted it. Anything else is refused and nothing is broadcast. Zero-fee quotes have no such rule.
ResponseWhenWhat to do
400 invalid_integrator_feeThe fee is above your ceiling (max_bps says what it is), or a venue on the route cannot carry it; reason is then fee_above_maximum, fee_below_minimum or fee_unavailableLower the fee, send 0, or omit the field. Treat reason as an open set
400 integrator_fee_requires_api_keyA non-zero integrator_fee_bps without X-API-KeySend your tik_ key, or drop the field
403 quote_integrator_mismatchA fee-carrying quote submitted without the key that quoted it, or with a different keyResubmit with the key that quoted it
503 integrator_fee_misconfiguredYour configured fee no longer fits a venue Treasures routes through. A Treasures-side issue that retrying soon will not clearContact Treasures, or send integrator_fee_bps: 0 to quote without your fee

What you have earned​

Every settled trade that carried your fee has an integrator_fee entry in its fee_costs on GET /settlements:

{ "name": "integrator_fee", "percentage": "0.0020", "amount_usd": "0.500840", "included": true, "payout_id": null }

payout_id is null while the fee is still owed to you, and names the payout it went out in once one claims it. Two filters on the same route reconcile the two sides:

  • payout_status=unpaid lists exactly the fees no payout has claimed yet. They sum to amount_usd on GET /payouts/accrued.
  • payout_id=ipo_… lists exactly the trades one payout covered. Their integrator_fee amounts sum to that payout's amount_usd.

payout_status=processing and payout_status=paid follow the status of the payout that claimed each fee. A read-only trk_ reporting key can use these filters, which makes /settlements the place to hand an accountant; the payout routes themselves need your general tik_ key.

Claiming a payout​

Check what is owed​

GET /payouts/accrued returns what you are owed right now and whether you can claim it:

FieldMeaning
amount_usd, trade_countWhat you are owed now and how many trades it came from. Fees earned on every chain are pooled into one USD figure (USDC and USDG count 1:1)
payout_chain, payout_addressWhere payouts go: USDC on Solana (sol) or Base (base). null until Treasures registers an address for you
previous_payout_address, payout_address_updated_atThe address the last change replaced and when, so an unexpected change is visible to you
payouts_enabledWhether POST /payouts is open
minimum_usd, maximum_usdThe smallest and largest payout the route makes. Above the maximum, Treasures pays on request
next_eligible_atUnix seconds before which a claim is refused (a cooldown after your last payout, or a hold after an address change); null when nothing is waiting

Only Treasures can set or change your payout address; ask your contact. There is no API to change it, by design.

Claim it​

POST /payouts sends all of what you are owed to your registered address. You choose nothing: the body is empty (or {}), the amount is your accrued balance, and the destination is your registered address.

  • Idempotency-Key is required, and a key is yours forever. Repeating one returns the payout it first created (200), whatever its status, including failed. To try again after a failure, send a new key.
  • One payout at a time, at least minimum_usd, at most maximum_usd, one per cooldown window, and none for a while after your address changes.
  • 202 means the transfer was sent or is being sent. Poll GET /payouts/{payoutId} until it is final.
Payout statusMeaning
processingCreated or sent, not yet final. On Solana tx_hash is known as soon as the transfer is sent; on Base, once it lands
paidFinal. tx_hash is the transfer and paid_at is set
failedThe transfer did not happen. Its fees are owed to you again; claim with a new Idempotency-Key
cancelledWithdrawn before sending. Its fees went back into what you are owed

GET /payouts lists every payout, newest first; page with cursor, reading next_cursor and has_more. To see the trades one payout covered, call GET /settlements?payout_id=….

When a claim is refused​

ResponseMeaningWhat to do
409 payout_in_progressAnother payout is still in flight; payout_id names itWait for it to finish
409 payout_cooldown, 409 address_holdToo soon after your last payout, or after an address changeRetry after retry_after (Unix seconds; also a Retry-After header)
409 payout_address_missingNo payout address is registeredAsk Treasures to register one
409 nothing_to_payNothing is owed right nowNothing to do
422 below_minimumWhat you are owed is under minimum_usdWait until it grows
422 requires_reviewWhat you are owed is over maximum_usdAsk Treasures, who pays balances this large on request
503 payouts_unavailablePayouts are paused or cannot be made right nowRetry later
403 insufficient_scopeA trk_ reporting key on a payout routeUse your tik_ key
404 payout_not_foundNo such payout of yours. Another organisation's payout id answers the same wayCheck the id

Every field is in the API Reference.