> For the complete documentation index, see [llms.txt](https://docs.hello.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello.trade/developer-tools/authentication-and-account-model.md).

# Authentication & Account Model

## Account Model

Each Ethereum wallet address corresponds to a unique trading account. Accounts are created automatically on first authentication, provided the wallet has been granted app access.

### Account Creation

* Accounts are created automatically on first authenticated request (WebSocket authentication or HTTP request with valid signature)
* Subsequent requests from the same wallet use the existing account
* No separate registration or account creation step required
* The wallet must have **app access** before authentication will succeed (see [App Access Gate](#app-access-gate) below)

### Margin Modes

Positions are margined in one of two modes:

* **Cross** (default) — all cross positions share one collateral pool; any position's loss can draw on the entire pool. `withdrawable` (free collateral) is cross margin.
* **Isolated** — the position carries its own dedicated margin for that market. Losses are capped at the margin committed there, and a liquidation cannot touch cross collateral or any other position's margin.

Isolated margin is funded by isolated deposits or cross → isolated transfers ([`POST /api/margin/transfer`](/developer-tools/rest-api/authenticated-endpoints.md#post-apimargintransfer)), and leaves via isolated withdrawal or a transfer back to cross. Leverage is tracked per mode, so the same instrument can run different leverage cross vs isolated.

Writes that touch margin carry a `marginMode` field (`Cross` | `Isolated`) that must match bit 0 of the signed payload's `flags`. Reads are combined: [`GET /api/account_summary`](/developer-tools/rest-api/public-endpoints.md#get-apiaccount_summary) covers cross and isolated in one response, with positions tagged by `marginMode`.

***

## App Access Gate

The trading platform is invite-gated. A wallet that has not applied a valid referral code cannot authenticate.

### How the gate surfaces

| Surface                                             | Response when gated                                      |
| --------------------------------------------------- | -------------------------------------------------------- |
| REST authed write (e.g. `POST /api/margin/deposit`) | `HTTP 403` with body `{"error":"USER_NOT_INVITED: ..."}` |
| WebSocket trading authentication                    | Error code **4015 `USER_NOT_INVITED`**                   |

Always parse the `USER_NOT_INVITED:` prefix rather than the freeform tail — the tail is human-readable and may change.

### Endpoints

| Method | Path                                     | Auth   | Purpose                                                                                                                                                                                                                  |
| ------ | ---------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GET`  | `/api/user/access-status/:walletAddress` | public | `{ hasAppAccess: boolean }`. Single source of truth for the gate predicate.                                                                                                                                              |
| `POST` | `/api/referral/apply`                    | signed | Submit an invite code. See [REST API — POST /api/referral/apply](/developer-tools/rest-api/authenticated-endpoints.md#post-apireferralapply) for the full request/response spec, signed payload format, and error codes. |

***

## Authentication

WebSocket connections must authenticate before performing trading operations.

### Authentication Flow

1. Connect to WebSocket endpoint
2. Send `authenticate` message with EIP-191 signature
3. Receive `authenticateSuccess` response
4. Connection is authenticated for trading operations

### Signature Requirements

Authentication uses EIP-191 (`personal_sign`). See [Signatures - EIP-191 Operations](/developer-tools/signatures.md#eip-191-operations) for signature construction.

Message format: `{wallet_address}:{nonce}`

All authentication signatures are validated for:

* Signature validity (recovered address must match claimed address)
* Nonce validity (5-minute time window)
* Nonce uniqueness (replay protection)
* Rate limiting (20 requests/second per authenticated wallet)

See [Nonce & Rate Limits](/developer-tools/nonce-and-rate-limits.md) for validation details.

***

## Connection State

### Authenticated

After successful authentication, connections can:

* Place, replace, and cancel orders
* Subscribe to private execution reports
* Manage margin and leverage

### Unauthenticated

Before authentication, connections can only:

* Authenticate
* Access public market data (if available)

### Logout

Send `logout` message to clear authentication state. Connection returns to unauthenticated state.

***

## Connection Limits

| Limit                       | Value      |
| --------------------------- | ---------- |
| Max connections per account | 8          |
| Idle timeout                | 30 seconds |
| Ping interval               | 15 seconds |

Connections exceeding idle timeout are automatically disconnected. Maintain connection by responding to ping frames or sending requests.

***

## Request Processing

Requests from the same wallet are processed sequentially. The system waits for each operation to complete before processing the next request from that wallet.

***

## Common Errors

| Error Code | Cause                                                                                |
| ---------- | ------------------------------------------------------------------------------------ |
| 4001       | Signature verification failed                                                        |
| 4002       | Nonce validation failed (replay, expired, or out of window)                          |
| 4003       | Connection not authenticated                                                         |
| 4004       | Signature wallet doesn't match authenticated wallet                                  |
| 4015       | Wallet not invited — apply a referral code (see [App Access Gate](#app-access-gate)) |
| 4029       | Rate limit exceeded                                                                  |
| 5000       | Connection limit exceeded (>8 connections per account)                               |
| 5003       | Failed to create or retrieve account                                                 |

For complete error code reference and troubleshooting guidance, see [Error Codes](/developer-tools/error-codes.md).

***

## API Reference

For detailed request and response formats, see:

* [WebSocket API](/developer-tools/websocket-api.md) - WebSocket message specifications
* [REST API](/developer-tools/rest-api.md) - HTTP endpoint specifications
