Prerequisites
- An API key from the Bags Developer Portal.
- The wallet entitled to the fees and a signer for it.
- The base token mint when claiming a specific token.
- SOL for any rent, reimbursement, or transaction costs assigned to your wallet. Sponsorship does not make every claim cost-free.
- A client that can execute Transaction Plans. The examples request v0.
https://public-api-v2.bags.fm/api/v1 with the x-api-key header. Replace uppercase placeholders before sending.
1. Discover Balances
For one token, call Get Custom Quote Claimable Position for a Token:response.items, response.complete, and response.issues. HTTP 200 can still contain unavailable sources. An unavailable amount is null, not zero; preserve restricted entries and explain their availability.reason.
Each item carries its exact asset.mint, asset.tokenProgram, and raw amount string. Use BigInt(item.rawAmount) only after checking for null; do not convert raw amounts to JavaScript numbers. Decimals can be unknown, and display multipliers require separate evidence. Missing valuation does not prevent an otherwise valid claim.
2. Choose What to Claim
You can also request
source: { "kind": "position" } (or omit source) to build the recipient flow across applicable pool fees, pair entitlement, and a holding balance. This is useful for a current config recipient. Use the explicit holding source to withdraw after removal from a config.
Do not submit both a whole-position claim and separate claims from its old discovery results. Confirm the chosen plan, then fetch balances again before building further claims. A pool-specific claim also settles the wallet’s pair entitlement; it is not a second independent income source.
3. Build and Execute the Claim Plan
Call Create Custom Quote Claim Plan:source with:
response, not response.plan. Follow Transaction Plans for signed fee ceilings, setup stages, co-signing, and confirmation. Do not send the JSON response itself to an RPC endpoint.
A direct recipient claim settles the gross entitlement. The wallet receives the net amount after any token withholding. A force-to-holding operation has already settled that pair entitlement; withdrawing the holding balance later is neither another settlement nor newly earned fees. Holding withdrawals pay the available balance and remain possible after the user leaves the recipient list.
4. Claim Partner and Deployer Balances
Use arole_balance entry from wallet discovery with the existing Claim DAMM v2 Vault endpoint. Despite its path name, this endpoint withdraws the shared role vault used by both custom-quote Fee Share receipts and custody receipts.
kind: "deployer" for a deployer balance. Supplying transactionFormat or feeLimits opts into bounded construction; omitting both preserves the existing endpoint behavior.
This endpoint returns the existing response.transaction base58 string and response.claimable, not a staged plan. Extended requests also return format/encoding metadata and claimable.claimableAmountRaw. For v0, decode with VersionedTransaction.deserialize(bs58.decode(response.transaction)), co-sign with the owner wallet while retaining the sponsor signature, then submit and confirm. Do not use the base64 plan decoder for this response.
Shared vault balances can contain Fee Share receipts, custody receipts, and unsolicited transfers. One withdrawal can pay all of them; it cannot establish how much each source earned. Treat withdrawals as balance movement, not additional revenue. The destination remains the role owner’s token account.
5. Handle Unavailable or Interrupted Claims
For a claim-all interface, skip clearly unavailable positions with an explicit report. Do not continue sending other claims after an uncertain submission. After each confirmed plan, refresh discovery so later requests use current balances.
