Documentation

Market Maker API

Programmatic access to all LP functions. Use the API to automate inventory management, configure spreads, monitor fills, and withdraw earnings without the web dashboard.

API key auth is coming soon. All endpoints are currently available via the web dashboard.

Last updated: 8 April 2026

Base URL

https://simplefx.io/api/v1/mm

Authentication

All requests must include your LP API key in the Authorization header. API keys are issued from the SimpleFX dashboard under Settings.

Request headerjson
Authorization: Bearer mm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are prefixed mm_live_ for production and mm_test_ for sandbox.

HTTP statusMeaning
401Missing or invalid API key
403Key is valid but does not have permission for this resource
429Rate limit exceeded (60 req/min per key)

Account

Returns the authenticated LP account profile and status.

GET/api/v1/mm/account
Responsejson
{
  "id": "lp_01jqe...",
  "email": "mm@example.com",
  "walletAddress": "0x723A3D...155aBe",
  "isActive": true,
  "createdAt": "2026-01-15T10:00:00Z"
}

Balances

Returns current inventory balances for the LP wallet.

GET/api/v1/mm/balances
Responsejson
{
  "ntzs": "9452.000000000000000000",
  "usdc": "3.912500",
  "usdt": "500.000000",
  "wallet": {
    "address": "0x723A3D...155aBe",
    "chain": "base"
  }
}

When the position is active, ntzs reflects the DB-tracked pool position. When inactive it reflects the raw on-chain wallet balance.

Rate & Quote

Returns the nTZS/USD mid-rate the swap engine is pricing from — the active nTZS/USDC pair, synced from the Bank of Tanzania's published mean rate.

GET/api/v1/mm/rate
Responsejson
{
  "midRateTZS": 2639.8663,
  "rateUpdatedAt": "2026-09-03T06:00:51.932Z",
  "quotable": true
}

What a taker would receive if your position filled this swap, at your spread, with the platform fee applied on top — priced by the same function the engine executes with.

GET/api/v1/mm/quote

Query parameters:

fromTokenrequiredstringNTZS, USDC, or USDT
toTokenrequiredstringNTZS, USDC, or USDT
amountrequirednumberInput amount (human-readable, not wei)
slippageBpsnumberSlippage tolerance in bps, used only to compute minOutput. Default 100, max 500.
Example — GET /api/v1/mm/quote?fromToken=USDC&toToken=NTZS&amount=10json
{
  "fromToken": "USDC",
  "toToken": "NTZS",
  "amountIn": "10",
  "expectedOutput": 26245.751,
  "minOutput": 25983.293,
  "minAmountOut": "25983.293000",
  "rate": 2624.5751,
  "midRate": 2639.8663,
  "rateUpdatedAt": "2026-09-03T06:00:51.932Z",
  "spreadBps": 38,
  "slippageBps": 100,
  "protocolFeeBps": 20,
  "expiresAt": "2026-09-03T10:00:30.000Z"
}

Configure Spread

Updates the bid and ask spread for the LP position, and optionally which sides and which pairs you quote. One spread applies to every pair you quote; each pair is priced off its own mid-rate. Min 10, max 500 bps per side.

PATCH/api/v1/mm/spread
bidBpsrequiredintegerBid spread in bps (nTZS → stablecoin direction — you BUY nTZS). Min 10, max 500.
askBpsrequiredintegerAsk spread in bps (stablecoin → nTZS direction — you SELL nTZS). Min 10, max 500.
quoteBidbooleanQuote the bid side. false = never routed nTZS → stablecoin fills, whatever you hold. Default true.
quoteAskbooleanQuote the ask side. false = never routed stablecoin → nTZS fills. Default true. Both false is refused.
quotePairsstring[] | nullCounter-token symbols you quote: any of USDC, USDT, TGBP, ZARP. null = all pairs (default). Empty list is refused.
Request bodyjson
{
  "bidBps": 120,
  "askBps": 150,
  "quoteBid": false,
  "quoteAsk": true,
  "quotePairs": ["USDC", "USDT"]
}
Responsejson
{
  "bidBps": 120,
  "askBps": 150,
  "quoteBid": false,
  "quoteAsk": true,
  "quotePairs": ["USDC", "USDT"],
  "updatedAt": "2026-09-03T09:30:00Z"
}

Activate / Deactivate

Activates or deactivates the LP position. Activating sweeps inventory from the LP wallet to the solver pool and makes the position available to the matching engine. Deactivating returns tokens to the LP wallet.

PATCH/api/v1/mm/activate
isActiverequiredbooleantrue to activate, false to deactivate
Request bodyjson
{
  "isActive": true
}
Responsejson
{
  "isActive": true,
  "walletAddress": "0x723A3D...155aBe",
  "updatedAt": "2026-04-08T09:31:00Z"
}

Fill History

Returns the most recent 100 fills for the LP position, ordered newest first.

GET/api/v1/mm/fills
Responsejson
{
  "fills": [
    {
      "id": "fill_01jqe...",
      "fromToken": "USDC",
      "toToken": "NTZS",
      "amountIn": "10.000000",
      "amountOut": "37312.500000000000000000",
      "feesEarned": "37.312500000000000000",
      "txHash": "0xabc123...",
      "createdAt": "2026-04-08T09:28:00Z"
    }
  ]
}

Withdraw

Withdraws tokens from the LP wallet to an external address. The LP position must be deactivated before withdrawing the full balance.

POST/api/v1/mm/withdraw
tokenrequiredstring"ntzs", "usdc", or "usdt"
toAddressrequiredstringDestination EVM address (0x...)
amountrequiredstringHuman-readable amount e.g. "500.00"
chainstring"base" or "bnb" — chain to withdraw from (default: "base"). Required for USDT on BNB.
Request bodyjson
{
  "token": "ntzs",
  "toAddress": "0xRecipient...",
  "amount": "500.00"
}
Responsejson
{
  "txHash": "0xdef456...",
  "status": "confirmed"
}

Error Codes

CodeHTTPDescription
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403Insufficient permissions for this operation
NOT_FOUND404LP account or resource not found
INSUFFICIENT_BALANCE400Wallet balance too low for the requested operation
INSUFFICIENT_LIQUIDITY400Solver pool lacks enough output tokens
INVALID_AMOUNT400Amount is zero, negative, or non-numeric
INVALID_ADDRESS400Destination address failed checksum validation
SPREAD_OUT_OF_RANGE400Bid or ask bps outside the 10–500 range
POSITION_INACTIVE400Operation requires an active LP position
RATE_LIMIT429Exceeded 60 requests/minute for this API key
INTERNAL_ERROR500Unexpected server error — contact support

Integration Examples

Node.js / TypeScript

const BASE = 'https://simplefx.io/api/v1/mm'
const KEY = process.env.SIMPLEFX_API_KEY

async function getBalances() {
  const res = await fetch(`${BASE}/balances`, {
    headers: { Authorization: `Bearer ${KEY}` },
  })
  return res.json()
}

async function setSpread(bidBps: number, askBps: number) {
  const res = await fetch(`${BASE}/spread`, {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ bidBps, askBps }),
  })
  return res.json()
}

cURL

# Get current balances
curl https://simplefx.io/api/v1/mm/balances \
  -H "Authorization: Bearer mm_live_xxxx"

# Update spread
curl -X PATCH https://simplefx.io/api/v1/mm/spread \
  -H "Authorization: Bearer mm_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{"bidBps": 120, "askBps": 150}'
NEDA Labs Ltd. — Dar es Salaam, Tanzania