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

# Authentication

> API keys, the Authorization header, what keys can do, and rate limits.

Every request is authenticated with an API key sent as a Bearer token.

```text theme={null}
Authorization: Bearer murmo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Keys are created in the Murmo app and are prefixed `murmo_`. The key identifies your user and
can place trades and move funds into positions on your behalf. Guard it accordingly.

<Warning>
  The key is sent in the **`Authorization` header only**. It is never read from the query string,
  because query strings get captured in load-balancer and CDN logs. Don't put your key in a URL.
</Warning>

## What a key can and cannot do

<CardGroup cols={2}>
  <Card title="Allowed" icon="circle-check">
    Reads (identity, account, positions, trades), group spot trades, prediction and perp
    positions, group membership and settings, and chat.
  </Card>

  <Card title="Not allowed" icon="circle-xmark">
    Withdrawing funds out of your wallet and managing API keys. These require an interactive
    (in-app) session and have no API route. Your key cannot drain your wallet to an external address.
  </Card>
</CardGroup>

Funds you deposit can be **deployed** (swapped, staked into positions) by the key, but they cannot be
**withdrawn** by it. To move money out, use the app.

<Note>
  API keys are scoped to the **REST API** (`/api/v1`) and the real-time [WebSocket gateways](/websockets/overview).
  They are **not** accepted on the GraphQL endpoint (`/graphql`) — that's the interactive app surface
  and requires a session. A key used against GraphQL returns `403 FORBIDDEN`.
</Note>

## Inspect the current credential

`GET /api/v1/me` echoes who you are, which key you're using (metadata only — never the secret), and
your rate budget:

```bash theme={null}
curl https://api.alpha-labs.trade/api/v1/me \
  -H "Authorization: Bearer $MURMO_API_KEY"
```

```json theme={null}
{
  "data": {
    "userId": "d66bafb2-...",
    "authMethod": "apiKey",
    "apiKey": {
      "id": "ak_...",
      "label": "my-bot",
      "prefix": "murmo_froc",
      "lastUsedAt": "2026-06-02T19:00:00.000Z",
      "expiresAt": null,
      "createdAt": "2026-05-20T12:00:00.000Z"
    },
    "rateLimit": { "limit": 1200, "windowSeconds": 60 }
  }
}
```

## Rate limits

API-key traffic is limited to **1,200 requests per 60-second window**. Over the limit you'll receive
`429 Too Many Requests` — back off and retry. The budget is reported on `GET /api/v1/me`.

<Tip>
  Polling? Prefer [WebSockets](/websockets/overview) for live prices and chat instead of tight REST
  loops — it's lower latency and won't burn your rate budget.
</Tip>

## WebSocket authentication

The same `murmo_` key authenticates the real-time gateways. Pass it in the Socket.IO handshake
`auth.token` (or an `Authorization: Bearer` header) — never in the query string:

```javascript theme={null}
import { io } from "socket.io-client";

const socket = io("wss://api.alpha-labs.trade/perps", {
  transports: ["websocket"],
  auth: { token: process.env.MURMO_API_KEY }, // "murmo_..."
});
```

See [Real-time overview](/websockets/overview).

## Errors

| Status                  | Meaning                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------- |
| `401 Unauthorized`      | Missing/invalid `Authorization` header or key.                                               |
| `403 Forbidden`         | Authenticated, but not permitted (e.g. not a member of the group, or an in-app-only action). |
| `429 Too Many Requests` | Rate limit exceeded.                                                                         |

See [Errors](/concepts/errors) for the response shapes and codes.

## Security checklist

<Steps>
  <Step title="Store the key in a secret">
    Environment variable or secret manager — never in source control or a URL.
  </Step>

  <Step title="Send it only over HTTPS / WSS">
    Always TLS. Never log the full key; the `prefix` is enough to identify it.
  </Step>

  <Step title="Rotate if exposed">
    Revoke and recreate the key in the app if it leaks. Keys can be scoped/expired there.
  </Step>
</Steps>
