> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/exchange/apis-and-rates/market-maker-guide.md).

# Market Maker Guide

Everything a market maker needs to integrate with the Nexus Exchange. The exchange is API-first — there is no MM-specific UI; you quote, cancel, and stream over the same REST + WebSocket surface every client uses, with a higher rate tier and a maker-only order type.

For the primitives, this guide points at the reference pages rather than restating them: [REST](/exchange/apis-and-rates/exchange-rest.md), [WebSocket](/exchange/apis-and-rates/exchange-websocket.md), [Rate Limits](/interfaces/rate-limits.md), [Rate & Connection Limits](/exchange/apis-and-rates/rate-limits.md), and the [Quickstart](/exchange/trading/quickstart.md).

## 1. Get MM-tier access

The **Market Maker** rate tier (**a budget of 2,000 weight per second**, of which a plain order submit costs 1) is admin-assigned, not self-serve — see [Rate Limits](/interfaces/rate-limits.md) for how requests are costed. Request the tier via your Nexus contact with your `key_id`. Until promoted, a key runs at the base tier. MM keys also get higher WebSocket ceilings (100 simultaneous connections vs. 5 at base, and 1,000 subscriptions vs. 50).

> Testnet-preview note: tier assignment and rate-limit state are currently in-memory at the gateway and reset on restart — after a gateway redeploy an MM key may briefly fall back to base until re-promoted. Note also that a key carries its own ceiling from the moment it was created (20/s by default) and a promotion does not rewrite it: check `GET /account/rate-limit` after being promoted, since the effective limit is whichever of the two binds first, and mint a fresh key if it still reports the base number.

## 2. Authenticate

Standard flow (details in the [section overview](/exchange/apis-and-rates.md)): wallet-signed session token (EIP-191) to create an **HMAC API key**, then sign every request with the key. The session token is for key management only — never for trading. Keep the HMAC secret safe; it's shown once.

## 3. The maker order surface

The order type that matters most for market making:

* **Post-only** — set `time_in_force: "PostOnly"` on a limit order. The engine **rejects** the order (rather than filling) if it would cross the book and take liquidity on entry, guaranteeing you rest as a maker. A crossing post-only order comes back as an `InvalidOrder` with code **`WouldTakeLiquidity`** — detect that and re-quote. This is the primary tool for never paying taker fees.
* Standard `GTC` / `IOC` / `FOK` are also available for the non-resting cases.
* **Batch + cancel-all.** Use batch order placement to refresh a quote ladder in one request, and market-scoped cancel-all to pull quotes on a market quickly. Amend is available for in-place price/size changes. (See [REST reference](/exchange/apis-and-rates/exchange-rest.md).)

## 4. Stream the market

Subscribe over [WebSocket](/exchange/apis-and-rates/exchange-websocket.md) rather than polling:

* **Order book** and **trades** for the market data you quote against.
* **Your fills / orders / positions** (private channels) to track quote state — mint a single-use ws-token via `POST /ws/token`, then connect.

Connection and subscription caps are per-tier (MM: 100 connections, 1,000 subscriptions) and form their own budget, separate from the REST one — see [Rate Limits](/interfaces/rate-limits.md). Subscriptions are capped per connection *and* across all of an account's connections at the same number, so spreading a quote ladder over more sockets does not raise the total. Design for reconnect: the client should re-subscribe and re-sync book state on reconnect, and a resubscribe storm is covered by the 2× inbound-frame burst allowance.

## 5. What to expect on latency & throughput

**We do not publish a latency figure for this venue yet.** Earlier revisions of this page carried an order-to-ack p95 and a WebSocket delivery p95 that were internal engineering targets, not measurements of the deployed testnet preview. Both have been removed rather than restated: a latency number a desk cannot reproduce is worse than no number at all.

What we can tell you today:

* **Rate ceiling, not a measured capacity.** The MM tier admits **2,000 weight per second** per key (see [Rate & Connection Limits](/exchange/apis-and-rates/rate-limits.md)). That is the configured admission ceiling — it is not a measured saturation point and it is not a throughput commitment. Pace against the `x-ratelimit-*` headers on every response and back off on `429` + `retry-after`, remembering two things about what those headers mean: `x-ratelimit-remaining` counts **unit-cost** requests, so it overstates how many heavy reads are left; and order writes draw on a **separate** budget from reads, so a healthy `remaining` on your last read says nothing about placement headroom.
* **Latency: measure it from your own client, and hold us to what you measure.** The numbers that matter to a quoting strategy — REST order-to-ack round trip, and matching-event-to-WebSocket-frame delivery — depend on your network path as much as on us, so your own measurement is the one worth acting on. Tell your Nexus contact what you get; a reproducible client-side number from a real desk is more useful to us than an internal one.
* **Latency goals tighten across release gates**, as noted in the [WebSocket reference](/exchange/apis-and-rates/exchange-websocket.md). When we publish a figure it will carry its conditions: environment, client location, network path, offered load, what the timer starts and stops on, and percentiles from a single run rather than averaged across runs.

## 6. Tooling

* **SDKs:** Rust (`nexus-exchange` on crates.io), Python (`nexus-exchange` on PyPI — the repository is `nexus-exchange-py`), and TypeScript (`@nexus-xyz/exchange-ts` on npm) all wrap this API, including request signing.
* **CLI:** `nexus-exchange-cli` (`nexus`) is a thin command layer over the Rust SDK.
* **CCXT:** the API exposes CCXT-compatible endpoints (tagged in the OpenAPI spec), so existing CCXT-based MM tooling connects with minimal changes.

## 7. Testnet status

This is a testnet preview: balances are testnet USDX (no real funds), state can reset on redeploy, and tier/rate-limit ceilings are configurable and may change as the tier system is finalized across release gates. Treat API keys as re-creatable.

***

*Doc note (ENG-2755): the per-tier ceilings now live in exactly one published place —* [*Rate Limits*](/interfaces/rate-limits.md) *— so this guide names only the MM figures it needs and links for the rest. The earlier Pro-tier inconsistency (ENG-4062: 200 req/s published vs. `DEFAULT_PRO_RPS` = 20 in code) is resolved; the published number is 20, matching the code.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nexus.xyz/exchange/apis-and-rates/market-maker-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
