Skip to content

Market maker onboarding

5-minute quickstart for staging

Make a Parti account, deposit testnet USDG, click "Provide Liquidity", you're live. The rest of this page covers Direct-API integration for automated MMs.

Audience: market makers integrating with the Parti Oracle order book. Environment: all URLs below target staging. Same shapes apply on prod — only the hostnames change.

What Where
Web app (sign-in + LP modal) https://parti.com
Parti API https://oracle-api.parti.com
Deposit address derivation https://oracle-deposit.parti.com

The protocol is a CLOB — discrete YES/NO shares trade between $0.00 and $1.00 (in basis points, 0 to 10 000). You earn a maker rebate on every fill that hits your resting order — that's the source of your edge.

You can quote three ways. Pick one.

Funding your account

You get a personal deposit address — the only thing you need to remember. Any USDG you send to it lands in your Parti balance, spendable for orders. Pass your EVM 0x address:

curl https://oracle-deposit.parti.com/v1/deposit/robinhood-address/<YOUR_0X_ADDRESS>
# → { "address": "0x…", "chain": "robinhood", "chain_id": 4663, "token": "USDG", ... }

(Or sign in at the web app — the deposit dialog shows it visually with a QR code.)

Send USDG on Robinhood Chain to it:

Deposits are Robinhood Chain-only — send USDG on Robinhood Chain (an EVM chain, chain id 4663). Other tokens or networks will not credit. Your Parti balance ticks up automatically the moment the deposit lands — no claim step. We also re-check the chain periodically and auto-catch any missed credits.

Withdraw any time with POST /v1/withdraw-signed (see LP → Withdrawals) — funds land back in your own wallet on Robinhood Chain; withdrawals confirm automatically.

Path A — In-browser bot (no code)

Best for: discretionary makers, smaller capital, one-off campaigns.

  1. Sign in at parti.com with email or a social login — an embedded wallet is created for you in the background.
  2. Deposit USDG on Robinhood Chain via the deposit dialog. Your Parti balance appears once the deposit is confirmed.
  3. Open the Earn tab and click any market in the "Quotable markets" list (ranked by 24h volume).
  4. "Provide Liquidity" modal opens with two modes:
    • Simple — pick capital + risk preset (Conservative / Balanced / Aggressive). One click and you're live on both sides of the book.
    • Advanced — full knobs: spread, levels per side, contracts per level, rebalance interval, skew tolerance, stop-loss, take-profit.
  5. Bot quotes both sides of the mid, widens on volatility, leans on inventory skew, re-quotes every ~15 s. Auto-pauses if inventory gets too one-sided.
  6. Live stats while running: PnL (USD + %), inventory skew bar, effective spread, current volatility, rebalance count.
  7. Stop & Withdraw — one click; cancels all resting orders and returns capital to your wallet balance.

You never sign individual orders — the embedded wallet signs silently in the background.

Path B — Direct API

Best for: automated market makers, larger capital, custom strategies.

1. One-time self-registration

You sign a registration message once — the API sets a 7-day session cookie, upserts your builder row (Solana address as payout wallet, registered name, fee_bps = 0, enabled = true), and returns a stable api_key.

TS=$(date +%s)
MSG="Parti Session\nUser: <YOUR_SOLANA_PUBKEY>\nTimestamp: $TS"
SIG=$(your-signer "$MSG")   # Ed25519, hex-encoded

curl -X POST https://oracle-api.parti.com/v1/builders/register \
  -c /tmp/parti-cookies.txt \
  -H 'Content-Type: application/json' \
  -d "{ \"user\":\"<YOUR_SOLANA_PUBKEY>\", \"name\":\"my-mm-bot\", \"signature\":\"$SIG\", \"timestamp\":$TS }"
# → { "api_key": "..." }   ← stable per user, save this

Pass that api_key as builder_api_key on every order. Until ops sets your fee_bps > 0, builder attribution is a no-op and you earn the protocol's standard maker_rebate_bps on every fill (5 bps today on staging). Once ops activates your row, you start earning fee_bps × notional extra on every fill your api_key touched.

2. Place an order

Sign the canonical 90-byte order message and POST:

[ 0..32) market_id     32 bytes — sha256(market_id_string) if not already hex
[32..64) user pubkey   32 bytes — your Solana pubkey (base58 → bytes)
[64]     outcome       u8 — 0 = yes, 1 = no
[65]     side          u8 — 0 = buy, 1 = sell
[66..74) price_bps     u64 LE — 0..10000
[74..82) size          u64 LE — contracts
[82..90) nonce         u64 LE — monotonic per user
curl -X POST https://oracle-api.parti.com/v1/orders \
  -b /tmp/parti-cookies.txt \
  -H 'Content-Type: application/json' \
  -d '{
    "market_id": "<hex_or_slug>", "user": "<YOUR_SOLANA_PUBKEY>",
    "side": "buy", "outcome": "yes", "price": 4850, "size": 100,
    "order_type": "post_only", "signature": "<hex_signature>", "nonce": 1700000000
  }'
# → { order_id, fills: [...], remaining, market_id }

order_type: gtc (rest until filled/cancelled), post_only (reject if would cross — preferred for makers), ioc (fill what you can, cancel rest), fok (all-or-nothing).

3. Cancel

# Single order
curl -X POST .../v1/orders/cancel -b /tmp/parti-cookies.txt \
  -d '{"order_id": 12345, "signature": "", "nonce": 0}'

# Cancel everything you own
curl -X POST .../v1/orders/cancel-all -b /tmp/parti-cookies.txt \
  -d '{"signature": "", "nonce": 0}'

4. Read state

Endpoint Returns
GET /v1/markets?status=active list markets
GET /v1/markets/{id}/book full book snapshot
GET /v1/balance/{user} available / locked / total micro-USDC
GET /v1/position/{market_id}/{user} yes / no contract count
GET /v1/orders/all/{user} your live resting orders
GET /v1/fees default + per-category + per-market fees

Path C — Hands-off (server-managed bot)

Best for: anyone who doesn't want to run their own process. You authorize a server-side session key to place orders on your behalf for a bounded window; our Parti does the rebalancing across a basket of markets you pick. Capital stays in your Parti balance the whole time; you can stop or revoke any time.

This is the same path the web app's "Basket" LP mode uses — same endpoints, same auth, same trust model. The full reference, byte layouts, and a copy-paste Node lifecycle example live in LP → LP bot. In short:

# 1) Server-generated session keypair + canonical message to sign
curl -X POST .../v1/lp-bot/session/new -d '{"user":"<PUBKEY>","expires_in_secs":86400,"scope":"orders"}'
# 2) Sign message_bytes_hex with your Solana key, then record the delegation
curl -X POST .../v1/lp-bot/delegate -d '{ ...session_pub, expires_at_unix, nonce, signature... }'
# 3) Start the bot
curl -X POST .../v1/lp-bot/start -d '{ ...basket, strategy... }'
# 4) Monitor + stop
curl ".../v1/lp-bot/status?user=<PUBKEY>"
curl -X POST .../v1/lp-bot/stop -d '{"user":"<PUBKEY>","revoke_session":true}'

Security model

  • Session keys are scoped to orders only. withdraw is hard-rejected.
  • Every order and delegation is signature-verified server-side before it executes, so a forged delegation can never be accepted.
  • Nonce monotonicity per user prevents replay of older delegations.
  • Delegations expire (5 min minimum, 30 days maximum). Stop + revoke_session: true revokes instantly.
  • All managed-bot orders show in your normal /v1/orders/all/<user> and /v1/balance/<user> results — one account, no separate accounting.

Maker rewards

Two stacking income streams on every fill against your resting order:

  1. Maker rebate — paid out of protocol fees. Currently 5 bps per fill on staging (live value at GET /v1/fees). Lands in your Parti balance the moment the fill confirms.
  2. LP rewards pool — daily proportional share of the rewards budget. Score depends on how much depth you keep near mid and how symmetric you quote. Capped at 40% per wallet. Paid daily at 00:00 UTC straight to your Parti balance — no claim step.

Withdraw any time. Daily auto-sweep can be enabled on request.

Limits & hygiene

  • Min order size: 1 contract. Sub-1¢ dust is rejected.
  • Nonce: must be strictly greater than your previous order's nonce. Use Math.max(prev_nonce, Date.now()) to be safe.
  • Self-trade prevention: a resting order of yours that would cross your own incoming order gets cancelled. Configurable per request via stp (cancel_resting default).
  • Rate limit: 50 req / 60s per user on /v1/orders. WS book subscriptions don't count.
  • Trading pauses: matching can be paused — resting orders stay live, new orders queue.

Sandbox check

Hit GET /v1/markets/{id}/book and you should see live levels. If your POST /v1/orders returns 200 with a non-zero order_id, you're in. The fills array lists any cross-matches that landed.

Questions / bug reports: ping your Parti contact directly — we respond same-day.