> ## Documentation Index
> Fetch the complete documentation index at: https://docs.d1.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# Market Makers

> APIs and integration guides for teams providing liquidity on D1.

D1's Market Maker API is a machine-to-machine interface for authorized liquidity providers. Through it you read markets and account state, submit and manage orders, receive fills and reconcile executions.

External MM V1 is the current programmatic market-maker interface for D1. It works on the same markets, order books, fills and balances as everyone else on D1. There is no separate market-maker trading system. Your orders rest in the same order book and match by the same price-time priority as every other order.

You bring your own pricing, volatility, inventory and hedging. D1 is the source of truth for instruments, order books, balances, positions, fills and settlement.

## What you can do

| Area | Endpoints |
| - | - |
| Identity and permissions | `GET /mm/v1/status` |
| Market data | `GET /mm/v1/markets`, `GET /mm/v1/markets/{instrumentId}`, `GET /mm/v1/markets/{instrumentId}/orderbook` |
| Account state | `GET /mm/v1/balances`, `GET /mm/v1/positions` |
| Trading | `POST /mm/v1/orders`, `POST /mm/v1/orders/{orderId}/cancel`, `POST /mm/v1/orders/cancel-all` |
| Orders | `GET /mm/v1/orders`, `GET /mm/v1/orders/{orderId}` |
| Fills | `GET /mm/v1/executions` (sequenced sync), `GET /mm/v1/fills` (history) |

> [!NOTE]
>
> **V1 is sell-to-close.** You can buy options and sell options you hold. You cannot write options or create a net short position. See [Trading Rules](https://docs.d1.exchange/market-makers/trading-rules.md#sell-to-close).

## Getting API access

External Market Maker access is currently **permissioned**. There is no self-service sign-up. Contact D1 to request access to the Market Maker API:

> [card] [Request Market Maker API access](mailto:jerry@cohuman.xyz)
>
> Email `jerry@cohuman.xyz`

### Onboarding flow

```text theme={null}
Request MM access
    ↓
D1 approves and registers your market maker account
    ↓
D1 issues a read key (mm:read)
    ↓
You verify connectivity and account state with GET /mm/v1/status
    ↓
D1 checks trading eligibility and enables trading for your account
    ↓
D1 issues a trading key (mm:read + mm:trade)
    ↓
You begin quoting
```

**1. Request access**

Email D1 with the details listed under [What to include](#what-to-include).

**2. D1 registers your market maker account**

Your market maker account is linked to an existing D1 account. That D1 account must already exist before D1 can register it.

**3. Receive a read key**

D1 issues an API key with the `mm:read` scope, and gives you the API base URL. With it you can authenticate and use every read endpoint: markets, order books, balances, positions, orders, fills and executions.

**4. Verify your integration**

Call `GET /mm/v1/status`. See [First verification](#first-verification).

**5. Trading is enabled**

When you are ready to trade, ask D1 to enable trading. D1 enables it only after your account passes its trading checks, described below.

**6. Receive a trading key**

D1 issues a separate trading key with `mm:read` and `mm:trade`. Your read key does not gain trading permission; trading always uses a key issued for it.

**7. Begin quoting**

Check that `trading.available` is `true` in `GET /mm/v1/status`, then follow the [Quickstart](https://docs.d1.exchange/market-makers/quickstart.md).

### What to include

Include in your request:

* your organization or team name;
* a contact name and email address for operational issues;
* the address of your existing D1 account;
* the display name you want for your market maker account;
* your intended integration or use case;
* whether you need read access only, or trading access as well.

> [!WARNING]
>
> Never send D1 a private key, seed phrase, password or API key. D1 will never ask for them.

### Read access and trading access

| | Read access | Trading access |
| - | - | - |
| Key scopes | `mm:read` | `mm:read` and `mm:trade` |
| What it allows | Status, markets, order books, balances, positions, orders, fills and executions | Everything read access allows, plus placing, cancelling and cancel-all |
| When you get it | After D1 registers your account | After D1 enables trading for your account |

D1 may issue read access first, so you can integrate and validate market data, account state and connectivity. Trading access is enabled separately, after your account passes D1's trading checks. These include:

* your market maker account is active;
* your available USDC balance meets D1's minimum for trading;
* your account holds no short positions and has no resting orders placed outside this API;
* your resting orders are within the [order limits](https://docs.d1.exchange/market-makers/trading-rules.md#order-limits).

A trading key alone does not guarantee that you can place orders. Placement also needs trading to be enabled for your account and switched on at D1, so check `trading.available` in `GET /mm/v1/status`. See [Trading availability](https://docs.d1.exchange/market-makers/trading-rules.md#trading-availability). The limits that currently apply to you are in the `limits` object of the same response.

### Key delivery

D1 generates each key and gives you the full key once, when it is created. Store it the moment you receive it.

> [!WARNING]
>
> Store the API key immediately in a secure secret manager. D1 does not expose the raw key again after issuance. If you lose it, ask D1 to revoke it and issue a new one.

To refer to a key later, for example when asking D1 to revoke it, use its `keyId` from `GET /mm/v1/status`. Never send the full key.

### First verification

Once you have a key, set up your environment and call `GET /mm/v1/status`:

```bash theme={null}
export D1_API_URL="<provided-by-d1>"
export D1_MM_API_KEY="<your-api-key>"

curl "$D1_API_URL/mm/v1/status" \
  -H "Authorization: Bearer $D1_MM_API_KEY"
```

Check the response:

| Look at | Expect |
| - | - |
| HTTP status | `200`. A `401` means the key is wrong or revoked; a `403` means your account is suspended. See [Errors](https://docs.d1.exchange/market-makers/errors.md). |
| `dealer.status` | `ACTIVE`. |
| `dealer.id`, `credential.keyId` | Your account and key identifiers. Record them; they are safe to log. |
| `credential.scopes` | `["mm:read"]` for a read key, `["mm:read", "mm:trade"]` for a trading key. |
| `trading.available` | `true` once you can place orders. `false` with `reason: "TRADING_DISABLED"` until trading is enabled. |
| `limits` | `maxOpenExposure`, `maxRestingOrders` and `maxRestingOrdersPerInstrument` for your account. |

Then continue with the [Quickstart](https://docs.d1.exchange/market-makers/quickstart.md).

### Replacing and revoking keys

* Keys can be revoked by D1. Revocation is permanent.
* If a key may be compromised, ask D1 to revoke it **immediately**, then switch to your other key.
* Request replacement keys through the same contact as above. There is no self-service key creation or rotation.
* Your account can have up to two active keys. Where it makes sense, give each integration its own key so you can revoke one without stopping the other.

See [Rotation](https://docs.d1.exchange/market-makers/authentication.md#rotation) and [Keeping your key safe](https://docs.d1.exchange/market-makers/authentication.md#keeping-your-key-safe).

## API contract

The Market Maker API is a dedicated machine-to-machine trading interface for authorized market makers. Only the endpoints documented under `/mm/v1` are part of the Market Maker API contract.

Build your integration only on the documented endpoints, response schemas and error codes. Anything else you may observe is not part of the contract and can change without notice.

## Start here

> [card] [Quickstart](https://docs.d1.exchange/market-makers/quickstart.md)
>
> From API key to a placed, reconciled and cancelled order.

> [card] [Authentication](https://docs.d1.exchange/market-makers/authentication.md)
>
> Bearer API keys, the `mm:read` and `mm:trade` scopes, and key security.

> [card] [Orders](https://docs.d1.exchange/market-makers/orders.md)
>
> Place, cancel and cancel-all, and safe retries with `clientOrderId`.

> [card] [Trading Rules](https://docs.d1.exchange/market-makers/trading-rules.md)
>
> Trading availability, sell-to-close and order limits.

> [card] [Fills & Executions](https://docs.d1.exchange/market-makers/executions.md)
>
> The sequenced `/executions` feed for fill reconciliation.

> [card] [Reliability](https://docs.d1.exchange/market-makers/reliability.md)
>
> How to build a market-making client that handles timeouts and restarts.

## Integration flow

**1. Authenticate**

Call `GET /mm/v1/status` with the API key D1 gave you during onboarding. Check `trading.available` before you place orders.

**2. Load the market catalog**

Page through `GET /mm/v1/markets`. Cache each market's terms and refresh `status` and `tradingPaused` regularly.

**3. Read order books**

Poll `GET /mm/v1/markets/{instrumentId}/orderbook` for the markets you quote.

**4. Load account state**

Read `GET /mm/v1/balances`, `GET /mm/v1/positions` and `GET /mm/v1/orders?state=resting`.

**5. Quote**

Place limit orders with `POST /mm/v1/orders`, each with its own `clientOrderId`. Cancel with `POST /mm/v1/orders/{orderId}/cancel` or `POST /mm/v1/orders/cancel-all`.

**6. Reconcile executions**

Consume `GET /mm/v1/executions` from a durable checkpoint. Use this feed, not `/fills`, to process fills.

## API conventions

* **Your account only.** The account is always the one your API key belongs to. Nothing in a request selects a different account, and a request body that names an account is refused.
* **Strict requests.** An unknown, repeated or malformed query parameter or body field returns `400 MALFORMED_REQUEST`. It is never ignored. Out-of-range values are refused, not clamped.
* **Exact numbers.** Prices, quantities and amounts are `{ units, decimals }` objects. See [Exact numbers](https://docs.d1.exchange/market-makers/market-data.md#exact-numbers).
* **Timestamps.** Fields ending in `Ms` are Unix milliseconds as decimal strings. `expirySeconds` is Unix seconds, also as a string. Every successful response except `GET /mm/v1/status` includes `serverTimeMs`.
* **No caching.** Responses are sent with `Cache-Control: no-store`.
* **Opaque identifiers.** Treat `instrumentId`, `orderId` and `fillId` as opaque strings.

For exact request and response schemas for every endpoint, see the [API Reference](https://docs.d1.exchange/api-reference/introduction.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.