Routes
Send your API key:
POST requests so that their filters can travel in a JSON
body, and the single-transaction read is a GET. All three only read, so they
are safe to retry.
Every request with a valid API key counts as one API query against your
organization’s monthly allowance, including a retried request and one answered
with 400 or 404.
Ownership
The Swig must be an active Swig owned by your API key’s organization on the requested network. An unknown Swig, an inactive one, and another organization’s Swig all answer404, so a response never reveals whether a Swig
exists outside your organization. Positions cover the Swig’s vault and all of
its sub-accounts, enabled or not.
Coverage
The index records actions on these protocols:
Only transactions the index interpreted are listed. A transaction it could not
interpret, or has not processed yet, is omitted from the list, and the
single-transaction read answers
404 for it. Indexer status is never returned.
Latest position state is recorded for Raydium CLMM positions only. Swap-only
protocols have no positions.
List DEX transactions
POST /wallet/api/swig/{swig_config_address}/dex/transactions
Request body:
Filters:
Filters combine with AND, and their order does not matter. Each kind may appear
once.
protocol, actionType, and swigVaultAddress must all match the same
action. A matching transaction still carries every DEX action the Swig executed
in it, so a list item and a single-transaction read have the same shape. Slot
filters do not change the order: transactions come newest first by slot, then
by signature.
Transaction fields:
Action fields:
Action payloads
action has exactly one key. Its value carries protocolInstruction (the
venue instruction name) and protocolActorAddress, plus:
withdrawals include any fees the venue pays out in the same transfer, as
Raydium CLMM does.
Each amount is an object:
Reading amounts
amountRawis signed for the action’sprotocolActorAddress: a negative amount left its accounts, a positive one arrived. It is a decimal string so that large values survive JSON exactly.protocolActorAddressis the Swig vault on a direct call. When an aggregator such as Jupiter routed the trade, it is the router’s account, and a routed swap appears as one action per venue hop. These are venue-level actions, not the wallet’s net token change. For wallet-relative inflows and outflows, use token transactions.
Get one DEX transaction
GET /wallet/api/swig/{swig_config_address}/dex/transactions/{transaction_signature}
Query parameters:
The response is
{ "transaction": { ... } }, where the transaction has exactly
the shape of a list item. It answers 404 when the Swig is not yours, or when
the Swig executed no indexed DEX action in that transaction.
List latest DEX positions
POST /wallet/api/swig/{swig_config_address}/dex/positions
The request body takes the same network, pageSize, cursor, and filters
fields as the transaction list. A position cursor is
{ "protocol", "dexPositionAddress" }. Filters:
Filters combine with AND in any order, each kind may appear once, and each
applies to the position. Positions are ordered by protocol, then position
address. The order never depends on state, so a position that closes does not
move.
A second page, read by sending the first page’s
nextCursor back:
Position fields:
Exactly one of
open and closed is present. Test for the key, not its
contents: closed is an empty object. open.state.raydiumClmm carries the
Raydium CLMM position account: liquidityRaw, tickLowerIndex,
tickUpperIndex, tokenFeesOwed0, tokenFeesOwed1, and one
rewardAmountsOwed entry per reward slot. A closed position is state, not a
separate action; the close itself appears in the transaction history.
Pagination
nextCursoris the sort key of the page’s last row:{ slot, transactionSignature }for transactions,{ protocol, dexPositionAddress }for positions. Send it back unchanged ascursor, and the next page starts after that row.nextCursoris absent on the last page.- Keep the same
network, Swig, and filters for every page. A cursor is a position in the sort order, not a token tied to the request it came from, so a cursor sent with different filters is not refused: it reads the new filters’ rows after that position. - Pages stay stable while new transactions are indexed: a newer transaction appears at the start of a fresh walk, not inside one already in progress.
- A cursor is not a credential. Every page checks the API key and ownership again.
- Each page is one API query. A larger
pageSize, up to 100, reads a long history in fewer requests.
Errors
See Errors for the general error format.

