> For the complete documentation index, see [llms.txt](https://docs.sodex.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sodex.com/for-developers/api-reference/trading-api/rest-v1/sodex-rest-public-api.md).

# Public

Public REST endpoints use `${PUBLIC_ENDPOINT}` as the base URL:

* Mainnet: `https://mainnet-gw.sodex.dev/api/v1`
* Testnet: `https://testnet-gw.sodex.dev/api/v1`

## User

### Query Subaccounts

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/subaccounts`

*Get the user's primary account ID and subaccounts.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/subaccounts" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Response

| Name        | Type              | Required | Description                                                                                                                             |
| ----------- | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`           | `true`   | Response status code. `0` means success.                                                                                                |
| `data`      | `UserSubaccounts` | `true`   | Response data when `code` is `0`. See [`UserSubaccounts`](/for-developers/api-reference/trading-api/rest-v1/schema.md#usersubaccounts). |
| `timestamp` | `uint64`          | `true`   | Response timestamp in milliseconds.                                                                                                     |

Use `data.primaryAccountID` as the trading `accountID` for builder-fee approval and as the builder ID when that account is the builder.

### Query API Keys

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/api-keys`

*Get API keys for the user's primary account by default, or an owned subaccount selected by `accountID`.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/api-keys?accountID=12345" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Query Params

| Name        | Type     | Required | Restrictions                         | Description                                                                      |
| ----------- | -------- | -------- | ------------------------------------ | -------------------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | none                                 | Optional primary or owned subaccount ID. The primary account is used by default. |
| `name`      | `string` | `false`  | should match `^[0-9a-zA-Z_-]{1,36}$` | Optional API key name filter                                                     |

#### Response

| Name        | Type             | Required | Description                                                                                                                           |
| ----------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`          | `true`   | Response status code. `0` means success.                                                                                              |
| `data`      | `AccountAPIKeys` | `true`   | Response data when `code` is `0`. See [`AccountAPIKeys`](/for-developers/api-reference/trading-api/rest-v1/schema.md#accountapikeys). |
| `timestamp` | `uint64`         | `true`   | Response timestamp in milliseconds.                                                                                                   |

### Add API Key

`POST ${PUBLIC_ENDPOINT}/user/{userAddress}/api-keys`

*Add an API key to both spot and perps. Use `permissions` to disable selected API key permissions, or `builder` to approve a builder fee in the same signed action.*

* Auth: signed write with the universal domain; `X-API-Chain` is required

```bash
curl -X POST "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/api-keys" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Chain: <API-Chain>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <AddAPIKeyRequest | AddPermissionedAPIKeyRequest>
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Headers

| Name          | Type        | Required | Description                                                                                  |
| ------------- | ----------- | -------- | -------------------------------------------------------------------------------------------- |
| `X-API-Chain` | `uint64`    | `true`   | Any `uint64`. Use this exact value as EIP-712 `domain.chainId` when generating `X-API-Sign`. |
| `X-API-Sign`  | `HexString` | `true`   | EIP-712 universal signature from the user's wallet                                           |
| `X-API-Nonce` | `uint64`    | `true`   | Unique nonce in milliseconds                                                                 |

#### Request Body

See [`AddAPIKeyRequest`](/for-developers/api-reference/trading-api/rest-v1/schema.md#addapikeyrequest) or [`AddPermissionedAPIKeyRequest`](/for-developers/api-reference/trading-api/rest-v1/schema.md#addpermissionedapikeyrequest) in [Schema](/for-developers/api-reference/trading-api/rest-v1/schema.md).

Additional Information:

* `accountID` must be the primary account ID or one of the subaccount IDs belonging to `userAddress`.
* The request succeeds only when both spot and perps accept it.
* `builder`, if provided, uses [`BuilderParams`](/for-developers/api-reference/trading-api/rest-v1/schema.md#builderparams).
* `permissions`, if provided, is a bit mask where a set bit disables the corresponding [`APIKeyPermissionEnum`](/for-developers/api-reference/trading-api/rest-v1/schema.md#apikeypermissionenum).
* A permissioned API key must disable `TRADE`, `CANCEL`, or both; enabling both `TRADE` and `CANCEL` is not supported.
* `builder` and `permissions` cannot be used together in the same request.

#### Response

| Name        | Type     | Required | Description                              |
| ----------- | -------- | -------- | ---------------------------------------- |
| `code`      | `int32`  | `true`   | Response status code. `0` means success. |
| `data`      | `null`   | `true`   | No endpoint-specific response payload.   |
| `timestamp` | `uint64` | `true`   | Response timestamp in milliseconds.      |

### Revoke API Key

*API key revocation does not support the universal domain. To revoke an API key from both markets, submit two engine-specific requests.*

1. Call `DELETE ${SPOT_ENDPOINT}/accounts/api-keys` with a `spot` domain signature. See [Remove API Key in the Spot REST API](/for-developers/api-reference/trading-api/rest-v1/sodex-rest-spot-api.md#remove-api-key).
2. Call `DELETE ${PERPS_ENDPOINT}/accounts/api-keys` with a `futures` domain signature. See [Remove API Key in the Perps REST API](/for-developers/api-reference/trading-api/rest-v1/sodex-rest-perps-api.md#remove-api-key).

Use the same [`RevokeAPIKeyRequest`](/for-developers/api-reference/trading-api/rest-v1/schema.md#revokeapikeyrequest) body for both calls, but sign each request separately with the account's master wallet. Engine-specific EIP-712 signatures use signature type `0x01`; a universal `0x02` signature cannot be used for revocation. See [Trading actions](/for-developers/developers/trading/authentication-and-signing.md#trading-actions) for signing details and [REST API endpoints](/for-developers/api-reference/trading-api/rest-v1.md#endpoints) for the endpoint base URLs.

```bash
# Revoke from spot.
curl -X DELETE ${SPOT_ENDPOINT}/accounts/api-keys \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Sign: <SPOT-API-Sign>' \
  -H 'X-API-Nonce: <SPOT-API-Nonce>' \
  -d <RevokeAPIKeyRequest>

# Revoke from perps.
curl -X DELETE ${PERPS_ENDPOINT}/accounts/api-keys \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Sign: <PERPS-API-Sign>' \
  -H 'X-API-Nonce: <PERPS-API-Nonce>' \
  -d <RevokeAPIKeyRequest>
```

Both calls are required. A successful spot revoke does not revoke the key from perps, and a successful perps revoke does not revoke it from spot. Each call returns its own response and can succeed or fail independently.

### Query Builders

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/builders`

*Get approved builders for the user.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/builders" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Response

| Name        | Type       | Required | Description                                                                                                               |
| ----------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`    | `true`   | Response status code. `0` means success.                                                                                  |
| `data`      | `Builders` | `true`   | Response data when `code` is `0`. See [`Builders`](/for-developers/api-reference/trading-api/rest-v1/schema.md#builders). |
| `timestamp` | `uint64`   | `true`   | Response timestamp in milliseconds.                                                                                       |

### Query Builder Fee Summary

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/builder/summary`

*Get the selected builder account's combined Spot and Perps statistics. No signature is required.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/builder/summary" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description                     |
| ------------- | ----------- | -------- | ----------------- | ------------------------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | Builder account owner's address |

#### Query Parameters

| Name        | Type     | Required | Description                                                                            |
| ----------- | -------- | -------- | -------------------------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | Builder account ID belonging to `userAddress`. Defaults to the user's primary account. |

#### Response

| Name        | Type                        | Required | Description                                                                                                                                                |
| ----------- | --------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`                     | `true`   | Response status code. `0` means success.                                                                                                                   |
| `data`      | `BuilderFeeStats` or `null` | `true`   | Builder statistics, or `null` when none are available. See [BuilderFeeStats](/for-developers/api-reference/trading-api/rest-v1/schema.md#builderfeestats). |
| `timestamp` | `uint64`                    | `true`   | Response timestamp in milliseconds.                                                                                                                        |

### Query Builder Fee Daily Chart

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/builder/daily-chart`

*Get the latest daily builder statistics, returned in ascending UTC date order. No signature is required.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/builder/daily-chart?limit=90" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description                     |
| ------------- | ----------- | -------- | ----------------- | ------------------------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | Builder account owner's address |

#### Query Parameters

| Name        | Type     | Required | Description                                                                            |
| ----------- | -------- | -------- | -------------------------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | Builder account ID belonging to `userAddress`. Defaults to the user's primary account. |
| `limit`     | `uint32` | `false`  | Number of latest daily records to return. Default: `90`, Min: `1`, Max: `300`.         |

#### Response

| Name        | Type                          | Required | Description                                                                                                                                                             |
| ----------- | ----------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`                       | `true`   | Response status code. `0` means success.                                                                                                                                |
| `data`      | `Array<BuilderFeeDailyStats>` | `true`   | Daily records, or an empty array when none are available. See [BuilderFeeDailyStats](/for-developers/api-reference/trading-api/rest-v1/schema.md#builderfeedailystats). |
| `timestamp` | `uint64`                      | `true`   | Response timestamp in milliseconds.                                                                                                                                     |

### Approve Builder Fee

`POST ${PUBLIC_ENDPOINT}/user/{userAddress}/builders`

*Approve or clear a builder fee on both spot and perps.*

* Auth: signed write with the universal domain; `X-API-Chain` is required

```bash
curl -X POST "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/builders" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Chain: <API-Chain>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <ApproveBuilderFeeRequest>
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Headers

| Name          | Type        | Required | Description                                                                                  |
| ------------- | ----------- | -------- | -------------------------------------------------------------------------------------------- |
| `X-API-Chain` | `uint64`    | `true`   | Any `uint64`. Use this exact value as EIP-712 `domain.chainId` when generating `X-API-Sign`. |
| `X-API-Sign`  | `HexString` | `true`   | EIP-712 universal signature from the user's wallet                                           |
| `X-API-Nonce` | `uint64`    | `true`   | Unique nonce in milliseconds                                                                 |

#### Request Body

See [`ApproveBuilderFeeRequest`](/for-developers/api-reference/trading-api/rest-v1/schema.md#approvebuilderfeerequest) in [Schema](/for-developers/api-reference/trading-api/rest-v1/schema.md).

Additional Information:

* `accountID` must be the primary account ID of `userAddress`.
* `builderID` is the builder's trading account ID. When `maxFeeRate` is non-zero, that account must exist in both spot and perps and have at least `100` vUSDC in each engine.
* A user may have at most 10 builder approvals at a time.
* The request succeeds only when both spot and perps accept it.
* `maxFeeRate` must be between `0` and `2000`, inclusive. Spot orders are capped at `2000` (2%); Perps orders are capped at `200` (0.2%).
* `maxFeeRate=0` clears the builder approval without checking the builder account eligibility or minimum balance; the user's account and signature checks still apply.

#### Response

| Name        | Type     | Required | Description                              |
| ----------- | -------- | -------- | ---------------------------------------- |
| `code`      | `int32`  | `true`   | Response status code. `0` means success. |
| `data`      | `null`   | `true`   | No endpoint-specific response payload.   |
| `timestamp` | `uint64` | `true`   | Response timestamp in milliseconds.      |

### Query user rate limits

`GET ${PUBLIC_ENDPOINT}/user/{userAddress}/ratelimit`

*Get transaction and cancel quota information for a user address.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/user/0x0123456789070ce8f0d6bab722103d12674bc257/ratelimit" \
  -H 'Accept: application/json'
```

#### Path Params

| Name          | Type        | Required | Restrictions      | Description      |
| ------------- | ----------- | -------- | ----------------- | ---------------- |
| `userAddress` | `HexString` | `true`   | valid EVM address | User EVM address |

#### Response

| Name        | Type            | Required | Description                                                                                                                         |
| ----------- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`         | `true`   | Response status code. `0` means success.                                                                                            |
| `data`      | `UserRateLimit` | `true`   | Response data when `code` is `0`. See [`UserRateLimit`](/for-developers/api-reference/trading-api/rest-v1/schema.md#userratelimit). |
| `timestamp` | `uint64`        | `true`   | Response timestamp in milliseconds.                                                                                                 |

## Announcement

> Mainnet only. These endpoints are not available on testnet.

### Query announcements

`GET ${PUBLIC_ENDPOINT}/announcements`

*Get a paginated list of public announcements.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/announcements?page=1&size=20&lang=en" \
  -H 'Accept: application/json'
```

#### Query Params

| Name   | Type     | Required | Restrictions               | Description                              |
| ------ | -------- | -------- | -------------------------- | ---------------------------------------- |
| `page` | `int`    | `false`  | `>= 1`; default `1`        | Page number                              |
| `size` | `int`    | `false`  | `1` to `100`; default `20` | Page size                                |
| `lang` | `string` | `false`  | `en`, `zh`, `ja`, `ko`     | Announcement language. Defaults to `en`. |

#### Response

| Name        | Type               | Required | Description                                                                                                                               |
| ----------- | ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`            | `true`   | Response status code. `0` means success.                                                                                                  |
| `data`      | `AnnouncementList` | `true`   | Response data when `code` is `0`. See [`AnnouncementList`](/for-developers/api-reference/trading-api/rest-v1/schema.md#announcementlist). |
| `timestamp` | `uint64`           | `true`   | Response timestamp in milliseconds.                                                                                                       |

### Query announcement detail

`GET ${PUBLIC_ENDPOINT}/announcements/detail/{id}`

*Get a public announcement detail by ID.*

```bash
curl -X GET "${PUBLIC_ENDPOINT}/announcements/detail/123?lang=en&plainText=false" \
  -H 'Accept: application/json'
```

#### Path Params

| Name | Type    | Required | Restrictions | Description     |
| ---- | ------- | -------- | ------------ | --------------- |
| `id` | `int64` | `true`   | numeric      | Announcement ID |

#### Query Params

| Name        | Type     | Required | Restrictions           | Description                                             |
| ----------- | -------- | -------- | ---------------------- | ------------------------------------------------------- |
| `lang`      | `string` | `false`  | `en`, `zh`, `ja`, `ko` | Announcement language. Defaults to `en`.                |
| `plainText` | `bool`   | `false`  | `true` or `false`      | Whether to return plain text body. Defaults to `false`. |

#### Response

| Name        | Type                 | Required | Description                                                                                                                                   |
| ----------- | -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `code`      | `int32`              | `true`   | Response status code. `0` means success.                                                                                                      |
| `data`      | `AnnouncementDetail` | `true`   | Response data when `code` is `0`. See [`AnnouncementDetail`](/for-developers/api-reference/trading-api/rest-v1/schema.md#announcementdetail). |
| `timestamp` | `uint64`             | `true`   | Response timestamp in milliseconds.                                                                                                           |
