Docs

Developers

HTTP API

The Socket API reads finalized chain state, quotes exactly, and prepares unsigned transactions. It holds no keys and submits nothing.

The API is what the app runs on. It reads pools, positions and hook state from finalized RPC, keeps an index of pools and swaps in PostgreSQL, and builds transactions for wallets to sign. It has no custody key and no route that sends a transaction.

On this site it is reachable at /api/socket, so GET /pools below is /api/socket/pools.

Conventions#

  • JSON in and out. POST bodies must be application/json and at most 64 KiB.
  • Token amounts, liquidity, square-root prices, nonces and slots are decimal strings. Ticks, fees in ppm and phases are numbers. Keys are base58.
  • Errors are { "error": { "code": "…", "message": "…" } } with a 4xx status, or 503 when the RPC or database fails.
  • Every read says where it came from: source is finalized-rpc, finalized-postgresql-index or finalized-rpc-simulation.

Reads#

MethodRouteReturns
GET/health{ status: "ok" } while the process runs.
GET/ready{ status, programId, finalizedSlot, indexedSlot } when the index is current; 503 when it is missing, stale or stopped.
GET/configThe Socket program, the built-in hooks program, the genesis hash, the hook allowlist (configured hooks plus governance-listed ones), token labels, and the listing program, registry and governance program.
GET/tokensMints in indexed pools with decimals and an optional label.
GET/pools?limit=100&after=ADDRESSIndexed pools, sorted by address, 1 to 500 per page.
GET/pools/:addressThe live pool, its mints and vault balances, and its resolved hook accounts.
GET/pools/:address/hookBuilt-in hook state, plus derived.dynamicFeePpm for a dynamic-fee pool at the server's current second.
GET/pools/:address/activity?limit=50Recent swaps, newest first, 1 to 200, with hook compute per call.
GET/pools/:address/twap?seconds=NA TWAP read: { windowSeconds, startTimestamp, endTimestamp, meanTick }.
GET/positions?owner=KEYEvery position of one owner, with current amounts, fees and whether it is in range.
GET/transactions?limit=100&beforeSlot=NIndexed program transactions and their logs.
GET/listingsEvery hook listing in the registry: hook, author, stake, proposed, listed or removed, and when.
GET/governance?limit=50The realm, the governance, SOCKET's supply, the listing stake and its lock, the voting rules (votingSeconds, holdUpSeconds, yesThresholdPercent, yesThresholdWeight, proposeWeight) and recent proposals with their votes, deadlines and the listing each one changes.
GET/governance/voters/:ownerOne holder's deposit, wallet balance, open votes, and whether they can propose or withdraw.

Quotes#

HTTP
POST /quote/swap
RequestJSON
{ "pool": "<address>", "amount": "1000000000", "aToB": true, "exactIn": true }

Returns the fee and where it came from (feeSource: "base" | "hook"), amountIn, amountOut, lpFee, amountRemaining (unspent input for a partial exact-in fill), ticksCrossed, maxSurcharge, the pool's price and liquidity before and after, the hook's kind and which swap phases it runs, and blocked when a filled range order would revert the swap.

Quotes run the same math as the program against finalized state. They are estimates of what execution will do, not guarantees: send swaps with a slippage limit.

Prepare#

POST /prepare/:operation returns { transaction, blockhash, lastValidBlockHeight, requiredSigners }: a base64 unsigned legacy transaction with a compute-limit instruction first. Every request includes owner, the fee payer and signer, and may include computeUnits (10,000 to 1,400,000; default 1,000,000).

OperationFields besides owner
initializenonce, mintA, mintB, sqrtPrice, tickSpacing, baseFeePpm, maxFeePpm, maxDeltaBps, permissions, hookBudget, hookProgram, extras, optional hookInit (built-in hooks only).
open-positionpool, nonce, lowerTick, upperTick.
add-liquiditypool, position, userA, userB, liquidity, maxA, maxB. Or open: true with nonce, lowerTick, upperTick to open and deposit in one transaction.
remove-liquiditypool, position, userA, userB, liquidity, minA, minB, optional collect: true.
collectpool, position, userA, userB.
collect-hook-feespool, userA, userB, amountA, amountB. The owner must be the pool's creator.
swappool, userA, userB, amount, limit, aToB, exactIn, threshold, maxTotalInput.
cancel-orderpool. The owner must be the range order's owner.
observe-twappool, secondsAgo.

Listing and governance operations return { transactions: [...] } instead: the same unsigned transactions, in the order to send them. Most fit in one; a proposal or a withdrawal that releases many votes can take two.

OperationFields besides owner
listing-proposehook, optional source (defaults to the owner's SOCKET account). Locks the listing stake.
listing-withdrawhook. The owner must be the author; the listing must be proposed or removed, and its lock passed.
governance-depositamount, optional source.
governance-withdrawNone. Releases finished votes, then returns the whole deposit.
governance-proposeaction (approve or remove), hook, optional burn for a removal, optional descriptionLink. Creates the proposal, adds its one transaction and opens the vote; the response includes proposal.
governance-voteproposal, approve.
governance-finalizeproposal. Anyone, once the voting time has ended.
governance-executeproposal. Anyone, once the hold-up has passed.

Liquidity, collection and swap operations accept createTokenAccounts: true: a missing associated token account of the owner is created in the same transaction. Any other missing account is an error.

Running your own#

The API is a Node service with a PostgreSQL index. It runs anywhere Node 22 does; set the RPC URL, the genesis hash, the program ID, the hook allowlist, the listing registry (SOCKET_LISTING_REGISTRY) and the database URL. Database migrations run when it starts. It is public by design: put rate limits and authentication at your ingress if you need them.