# Getting Started

This guide goes from credentials to a reconciled order over REST.
Latency-sensitive strategies should move the same order model to the
[write WebSocket](/api/exchange-websocket) afterwards.

## 1. Set your credentials

Mosaiq access is tied to an approved EVM wallet. That wallet address is your
public Mosaiq `user`.

Create an API key from an authenticated Para wallet session:

```bash
curl https://production.mosaiq.0d.finance/v1/apiKey \
  -H "Authorization: Bearer $PARA_JWT" \
  -H "Content-Type: application/json" \
  -d '{}'
```

If the Para session contains multiple EVM wallets, also send
`X-Tessera-Wallet: <approved-wallet>`. The response returns the raw key once.
Creating a key revokes the previous key; keys expire after 30 days.
See [API keys](/api/api-key) for the full contract.

```bash
export MOSAIQ_API_BASE_URL=https://production.mosaiq.0d.finance
export MOSAIQ_USER=0x0000000000000000000000000000000000000001
export MOSAIQ_API_KEY=<your-api-key>
```

Trading requests authenticate with `Authorization: Bearer <your-api-key>`.

## 2. Inspect the account and market catalog

```bash
curl "$MOSAIQ_API_BASE_URL/v1/clearinghouseState?user=$MOSAIQ_USER"
```

Use the response to check:

* `data.userData.marginSummary.availableFunds` for opening capacity;
* `data.userData.userCaps` for account-level limits;
* `data.universeData.meta.venues` for venue reachability;
* `data.universeData.universe[*].venues[*]` for venue codes, trading status,
  tick size, size increment, and minimum notional.

Use `universe[*].name` as the order field `a` and `venues[*].venue` exactly as
returned. Do not derive venue symbols or precision rules in the client.

## 3. Start lifecycle subscriptions

Open the user-data WebSocket before the first write and subscribe to
`orderUpdates` and `userFills`:

```ts
const apiBaseUrl = 'https://production.mosaiq.0d.finance'
const user = '0x0000000000000000000000000000000000000001'

const url = new URL('/v1/ws', apiBaseUrl)
url.protocol = 'wss:'
url.searchParams.set('user', user)

const ws = new WebSocket(url)

ws.addEventListener('open', () => {
  for (const type of ['orderUpdates', 'userFills']) {
    ws.send(JSON.stringify({ method: 'subscribe', subscription: { type } }))
  }
})

ws.addEventListener('message', (event) => {
  const message = JSON.parse(event.data)
  if (message.status !== 'ok') return

  if (message.topic === 'orderUpdates') {
    for (const order of message.data.orderUpdates) {
      console.log('order', order.cloid, order.status)
    }
  }

  if (message.topic === 'userFills') {
    for (const fill of message.data.userFills) {
      console.log('fill', fill.cloid, fill.fillId)
    }
  }
})
```

The first message for each topic is a snapshot. Store order transitions by
`cloid` and fills by `(venue, fillId)`; processing must be idempotent.

## 4. Fund the account

```bash
curl "$MOSAIQ_API_BASE_URL/v1/exchange" \
  -H "Authorization: Bearer $MOSAIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"deposit","amount":"100"}'
```

Send exactly `amount` USDC on Arbitrum, from the registered wallet, to the
returned `to` address before `expiresAtMs`. The minimum is 1 USDC. Mosaiq
credits the account only after observing a transfer whose sender and amount
match a pending request; any other transfer to the treasury, and a matching
transfer above the operator's auto-credit cap, is held for operator review.
Check the balance through
[`GET /v1/clearinghouseState`](/api/clearinghouse-state). Para-authenticated
clients can inspect request status through [`GET /v1/funding`](/api/funding).

## 5. Submit an order

Choose an active market and values that satisfy the selected venue's live
constraints. Give every placement a fresh, non-zero, lowercase 128-bit
hexadecimal `cloid`.

```bash
export MOSAIQ_ASSET=BTC
export MOSAIQ_VENUE=hyperliquid
export MOSAIQ_LIMIT_PRICE=<current-post-only-price>
export MOSAIQ_SIZE=<valid-base-size>
export MOSAIQ_CLOID=0x00000000000000000000000000000001

curl "$MOSAIQ_API_BASE_URL/v1/exchange" \
  -H "Authorization: Bearer $MOSAIQ_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<JSON
{
  "type": "place",
  "orders": [
    {
      "a": "$MOSAIQ_ASSET",
      "b": "buy",
      "p": "$MOSAIQ_LIMIT_PRICE",
      "s": "$MOSAIQ_SIZE",
      "venue": "$MOSAIQ_VENUE",
      "t": "Alo",
      "c": "$MOSAIQ_CLOID"
    }
  ]
}
JSON
```

```jsonc
{
  "status": "ok",
  "data": [
    {
      "status": "accepted",
      "orderId": "...",
      "cloid": "0x00000000000000000000000000000001",
      "venue": "hyperliquid",
      "size": "<accepted-size>"
    }
  ],
  "server_time_ms": 1780000000100,
  "server_receive_time_ms": 1780000000088
}
```

`accepted` is not fill finality. Track the `cloid` on `orderUpdates`, treat
`userFills` as execution truth, and a later `clearinghouseState` read as account
truth.

## 6. Cancel or reconcile

```bash
curl "$MOSAIQ_API_BASE_URL/v1/exchange" \
  -H "Authorization: Bearer $MOSAIQ_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<JSON
{
  "type": "cancel",
  "orders": [
    { "venue": "$MOSAIQ_VENUE", "c": "$MOSAIQ_CLOID" }
  ]
}
JSON
```

If a request or connection ends without a definitive response, do not resend
it blindly. Reconnect, consume fresh lifecycle snapshots, query
[`GET /v1/openOrders?cloid=<cloid>`](/api/open-orders), and backfill fills
through [`GET /v1/userFills`](/api/user-fills) before deciding whether to
retry.

Next: [Market data WebSocket](/api/market-data-websocket),
[Write WebSocket](/api/exchange-websocket),
[Optimizing latency](/api/optimizing-latency), and the
[Exchange API](/api/exchange) reference.
