> For the complete documentation index, see [llms.txt](https://bitbook.rwatokens.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bitbook.rwatokens.net/cedex-and-trading/cedex-and-trading/cedex-api-reference.md).

# CEDEX API Reference

## CEDEX API Reference

**Compliant Exchange for Digital Securities · REST + WebSocket · v1.0 · Module-Aware**

API reference for cedex.market — the trading venue that preserves all 42 Transfer Hook security controls on every ST22 Digital Securities trade. Dual-layer architecture: centralized order matching (Web2 performance) with decentralized Solana settlement (Web3 finality). The API serves all three production modules: Equities (Module 1), Real Estate (Module 2), and CORECM — Carbon Ore, Rare Earth, and Critical Minerals (Module 3). Module-aware endpoints, error codes, and WebSocket channels are documented inline.

***

### Table of Contents

1. Overview​
2. ​Authentication​
3. ​Rate Limits​
4. ​Public Endpoints​
5. ​Authenticated Endpoints​
6. ​WebSocket API​
7. ​Compliance Pre-Flight​
8. ​Error Reference​
9. ​Pagination​
10. ​Idempotency​
11. ​Code Examples​
12. ​Module-Aware API Surface​
13. ​Changelog​

***

### 1. Overview

#### Base URLs

| Environment | REST API                             | WebSocket                             |
| ----------- | ------------------------------------ | ------------------------------------- |
| Production  | `https://api.cedex.market/v1`        | `wss://api.cedex.market/ws/v1`        |
| Devnet      | `https://api.devnet.cedex.market/v1` | `wss://api.devnet.cedex.market/ws/v1` |

#### Request Format

All requests use JSON. All responses return JSON.

```
Content-Type: application/json
Accept: application/json
```

#### Timestamps

All timestamps are Unix seconds (UTC) unless otherwise noted. ISO 8601 format is available via the `?format=iso` query parameter.

#### Amounts

All token amounts are in raw units (with decimals applied). For an ST22 token with 9 decimals, `1_000_000_000` = 1.0 token. SOL amounts are in lamports (`1_000_000_000` = 1.0 SOL). Stablecoin amounts (USDC, PYUSD) are in 6-decimal raw units (`1_000_000` = 1.0 stablecoin unit).

#### Performance

| Metric                    | Value                           |
| ------------------------- | ------------------------------- |
| Pre-flight compliance     | 2,000–3,000ms                   |
| On-chain execution        | 400–600ms                       |
| Total order-to-settlement | 3–4 seconds                     |
| Block finality            | \~13 seconds (32 confirmations) |
| Order book sync           | 400ms (1 Solana block)          |
| Compute units per swap    | \~800,000 CU                    |

***

### 2. Authentication

#### Wallet Signature Authentication

CEDEX uses Solana wallet signature authentication. All authenticated endpoints require a signed message proving wallet ownership.

**Step 1: Request Challenge**

```
POST /auth/challenge
```

**Request:**

```json
{
  "wallet": "9aB2xY..."
}
```

**Response:**

```json
{
  "challenge": "CEDEX-AUTH-1711929600-a1b2c3d4",
  "expires_at": 1711929900
}
```

**Step 2: Sign and Submit**

```
POST /auth/verify
```

**Request:**

```json
{
  "wallet": "9aB2xY...",
  "challenge": "CEDEX-AUTH-1711929600-a1b2c3d4",
  "signature": "base58-encoded-ed25519-signature"
}
```

**Response:**

```json
{
  "token": "eyJhbGciOiJFZDI1NTE5...",
  "expires_at": 1712016000,
  "wallet": "9aB2xY...",
  "empire_verified": true,
  "eligibility": "RegD",
  "jurisdiction": "US",
  "kyc_status": "verified",
  "kyc_expires": 1743465600
}
```

The `eligibility` field reports the offering exemption(s) the wallet is verified for: `"RegD"` (US accredited), `"RegS"` (non-US), `"RegCF"` (US retail crowdfunding), or a comma-separated combination such as `"RegD,RegS"` for wallets that satisfy multiple paths.

**Using the Token**

Include the bearer token in all authenticated requests:

```
Authorization: Bearer eyJhbGciOiJFZDI1NTE5...
```

**Token lifetime:** 24 hours. Refresh by repeating the challenge/verify flow.

#### Empire Verification Requirement

All authenticated endpoints require Empire Stock Transfer verification. Wallets that have not completed Empire's KYC, KYB, AML, OFAC, and KYW verification receive:

```json
{
  "error": {
    "code": "EMPIRE_VERIFICATION_REQUIRED",
    "message": "Wallet not verified by Empire Stock Transfer. Complete onboarding through your issuer."
  }
}
```

Empire is the platform's sole investor onboarding authority. The platform does not perform investor verification or operate a KYC portal independent of Empire.

***

### 3. Rate Limits

| Tier                           | Requests/min | Orders/min | WebSocket Subscriptions |
| ------------------------------ | ------------ | ---------- | ----------------------- |
| Standard                       | 120          | 30         | 10 channels             |
| Verified (Empire KYC complete) | 600          | 120        | 50 channels             |
| Institutional (on request)     | 3,000        | 600        | Unlimited               |

Rate-limit headers on every response:

```
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1711929660
```

Exceeding limits returns `429 Too Many Requests`:

```json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Retry after 2026-04-01T00:01:00Z",
    "retry_after": 1711929660
  }
}
```

***

### 4. Public Endpoints

No authentication required. Read-only market data.

#### `GET /markets`

List all active ST22 trading pairs across all modules.

**Query Parameters:**

| Parameter | Type     | Description                                                 |
| --------- | -------- | ----------------------------------------------------------- |
| `module`  | `string` | Filter by module: `"equities"`, `"real_estate"`, `"corecm"` |

**Response:**

```json
{
  "markets": [
    {
      "mint": "7xK9p2...",
      "symbol": "ACME-ST22",
      "module": "equities",
      "issuer_name": "ACME Corporation",
      "issuer_cik": "0001234567",
      "decimals": 9,
      "price_sol": 0.0001153,
      "price_usd": 0.0184,
      "volume_24h_sol": 1250.5,
      "volume_24h_usd": 200080.0,
      "pool_depth_sol": 50000.0,
      "pool_depth_tokens": 433043000000000,
      "change_24h_pct": -2.14,
      "high_24h": 0.0001205,
      "low_24h": 0.0001098,
      "total_supply": 1000000000000000000,
      "circulating_supply": 200000000000000000,
      "custody_ratio": 1.0,
      "custody_verified": true,
      "hook_active": true,
      "controls_active": 42,
      "is_trading": true,
      "circuit_breaker_active": false,
      "listed_at": 1711929600
    }
  ],
  "count": 1,
  "timestamp": 1711930000
}
```

The `module` field on each market object is one of `"equities"`, `"real_estate"`, or `"corecm"`. Module 2 markets include additional NAV-related fields (see §12.2). Module 3 markets include additional Classification-related fields (see §12.3).

#### `GET /markets/{mint}`

Get detailed market data for a single ST22 token.

**Path Parameters:**

| Parameter | Type     | Description                |
| --------- | -------- | -------------------------- |
| `mint`    | `string` | ST22 mint address (base58) |

**Response:** Same structure as the single-market object above, plus:

```json
{
  "...market fields...",
  "security_config": {
    "max_wallet_percent_bps": 499,
    "price_impact_max_bps": 200,
    "circuit_breaker_threshold_bps": 3000,
    "circuit_breaker_cooldown_secs": 86400,
    "holding_period_reg_d_secs": 15778800,
    "holding_period_reg_s_secs": 31536000,
    "holding_period_reg_cf_secs": 31536000
  },
  "custody": {
    "custodied_balance": 1000000000,
    "token_supply": 1000000000,
    "ratio": 1.0,
    "attestation_slot": 285000000,
    "ed25519_verified": true,
    "last_update_ms": 1711930000400
  },
  "fee_config": {
    "total_bps": 500,
    "pool_bps": 44,
    "issuer_bps": 200,
    "staking_bps": 150,
    "protocol_bps": 106
  }
}
```

For Module 2 markets, the response also includes a `nav` object (see §12.2). For Module 3 markets, the response also includes a `classification` object (see §12.3).

#### `GET /markets/{mint}/orderbook`

Current order book.

**Query Parameters:**

| Parameter | Type      | Default | Description                         |
| --------- | --------- | ------- | ----------------------------------- |
| `depth`   | `integer` | 20      | Number of levels per side (max 100) |

**Response:**

```json
{
  "mint": "7xK9p2...",
  "bids": [
    { "price": 0.0001150, "amount": 50000000000, "total": 50000000000 },
    { "price": 0.0001145, "amount": 30000000000, "total": 80000000000 },
    { "price": 0.0001140, "amount": 75000000000, "total": 155000000000 }
  ],
  "asks": [
    { "price": 0.0001155, "amount": 40000000000, "total": 40000000000 },
    { "price": 0.0001160, "amount": 25000000000, "total": 65000000000 },
    { "price": 0.0001165, "amount": 60000000000, "total": 125000000000 }
  ],
  "spread_bps": 4.3,
  "mid_price": 0.00011525,
  "timestamp": 1711930000
}
```

#### `GET /markets/{mint}/trades`

Recent trades. Newest first.

**Query Parameters:**

| Parameter | Type      | Default | Description                     |
| --------- | --------- | ------- | ------------------------------- |
| `limit`   | `integer` | 50      | Results per page (max 200)      |
| `before`  | `string`  | —       | Cursor: trade ID for pagination |
| `after`   | `string`  | —       | Cursor: trade ID for pagination |

**Response:**

```json
{
  "trades": [
    {
      "id": "trade_a1b2c3d4",
      "mint": "7xK9p2...",
      "side": "buy",
      "amount": 10000000000,
      "price": 0.0001153,
      "value_sol": 1.153,
      "fee_sol": 0.05765,
      "fee_breakdown": {
        "pool": 0.005074,
        "issuer": 0.02306,
        "staking": 0.017295,
        "protocol": 0.012221
      },
      "price_impact_bps": 12,
      "tx_signature": "5vGh7kJ...",
      "block_slot": 285000150,
      "timestamp": 1711929990
    }
  ],
  "has_more": true,
  "next_cursor": "trade_x9y8z7w6"
}
```

#### `GET /markets/{mint}/ohlcv`

Candlestick / OHLCV data.

**Query Parameters:**

| Parameter  | Type      | Default | Description                               |
| ---------- | --------- | ------- | ----------------------------------------- |
| `interval` | `string`  | `1h`    | `1m`, `5m`, `15m`, `1h`, `4h`, `1d`, `1w` |
| `from`     | `integer` | —       | Start time (Unix seconds)                 |
| `to`       | `integer` | —       | End time (Unix seconds)                   |
| `limit`    | `integer` | 100     | Max candles (max 1000)                    |

**Response:**

```json
{
  "mint": "7xK9p2...",
  "interval": "1h",
  "candles": [
    {
      "timestamp": 1711929600,
      "open": 0.0001140,
      "high": 0.0001165,
      "low": 0.0001098,
      "close": 0.0001153,
      "volume_tokens": 500000000000,
      "volume_sol": 57.65,
      "trade_count": 142
    }
  ],
  "count": 1
}
```

#### `GET /oracle/{mint}/custody`

Current Empire Stock Transfer custody attestation.

**Response:**

```json
{
  "mint": "7xK9p2...",
  "custodied_balance": 1000000000,
  "token_supply": 1000000000,
  "ratio": 1.0,
  "attestation_slot": 285000200,
  "attestation_timestamp": 1711930080,
  "ed25519_verified": true,
  "empire_pubkey": "EmpK3y...",
  "discrepancy_detected": false,
  "slot_age": 0,
  "latency_ms": 145
}
```

#### `GET /oracle/{mint}/nav` *(Module 2 only)*

Most recent appraised NAV for a Module 2 ST22 mint. See §12.2.

#### `GET /oracle/{mint}/classification` *(Module 3 only)*

Most recent USGS / DOE classification status and federal-action status for a Module 3 ST22 mint. See §12.3.

#### `GET /oracle/ofac/status`

OFAC oracle health.

**Response:**

```json
{
  "last_refresh": 1711929600,
  "next_refresh": 1711933200,
  "entry_count": 12847,
  "list_hash": "a1b2c3d4e5f6...",
  "is_fresh": true,
  "staleness_threshold_secs": 86400,
  "halt_threshold_secs": 172800,
  "status": "healthy"
}
```

#### `GET /oracle/aml/{wallet}`

AML risk score for a wallet (cached, public subset).

**Response:**

```json
{
  "wallet": "9aB2xY...",
  "risk_score": 12,
  "disposition": "approve",
  "provider": "chainalysis+trm",
  "scored_at": 1711926000,
  "cache_expires": 1711947600,
  "is_fresh": true
}
```

Scores 31–70 return `"disposition": "review"` with limited detail. Scores 71–100 return `"disposition": "reject"`.

#### `GET /health`

System health check.

**Response:**

```json
{
  "status": "operational",
  "version": "1.0.0",
  "solana_slot": 285000250,
  "solana_tps": 2847,
  "rpc_latency_ms": 45,
  "oracle_status": {
    "custody": "healthy",
    "ofac": "healthy",
    "aml": "healthy",
    "twap": "healthy",
    "edgar": "healthy",
    "nav": "healthy",
    "classification": "healthy"
  },
  "circuit_breaker_global": false,
  "mev_protection": "active",
  "timestamp": 1711930100
}
```

The `nav` and `classification` fields under `oracle_status` reflect the aggregate health of those oracle networks across all Module 2 and Module 3 mints respectively. Per-mint oracle health is reported by the per-mint endpoints.

***

### 5. Authenticated Endpoints

All endpoints below require `Authorization: Bearer <token>` from a wallet that has completed Empire Stock Transfer verification.

#### `POST /orders`

Place a market or limit order. Every order goes through pre-flight compliance verification (2–3 seconds) before on-chain submission.

**Request (market):**

```json
{
  "mint": "7xK9p2...",
  "side": "buy",
  "type": "market",
  "amount": 50000000000,
  "slippage_bps": 100,
  "idempotency_key": "order_20260401_001"
}
```

**Request (limit):**

```json
{
  "mint": "7xK9p2...",
  "side": "sell",
  "type": "limit",
  "amount": 100000000000,
  "limit_price": 0.0001200,
  "expiry": 1712016000,
  "idempotency_key": "order_20260401_002"
}
```

**Request Fields:**

| Field             | Type      | Required    | Description                                   |
| ----------------- | --------- | ----------- | --------------------------------------------- |
| `mint`            | `string`  | Yes         | ST22 mint address                             |
| `side`            | `string`  | Yes         | `"buy"` or `"sell"`                           |
| `type`            | `string`  | Yes         | `"market"` or `"limit"`                       |
| `amount`          | `integer` | Yes         | Token amount (raw, with decimals)             |
| `limit_price`     | `number`  | Limit only  | SOL per token                                 |
| `slippage_bps`    | `integer` | Market only | Max slippage (default 100 = 1%, max 500 = 5%) |
| `expiry`          | `integer` | Limit only  | Unix timestamp (default: 24h from now)        |
| `idempotency_key` | `string`  | Recommended | Prevents duplicate orders (see §10)           |

**Response (market — filled):**

```json
{
  "order_id": "ord_x1y2z3",
  "status": "filled",
  "side": "buy",
  "type": "market",
  "amount_requested": 50000000000,
  "amount_filled": 50000000000,
  "effective_price": 0.0001155,
  "value_sol": 5.775,
  "fee": {
    "total_sol": 0.28875,
    "total_bps": 500,
    "pool_sol": 0.025410,
    "issuer_sol": 0.11550,
    "staking_sol": 0.086625,
    "protocol_sol": 0.061215
  },
  "price_impact_bps": 18,
  "compliance_check": "passed",
  "controls_executed": 42,
  "tx_signature": "5vGh7kJ...",
  "block_slot": 285000300,
  "settled_at": 1711930200,
  "created_at": 1711930197
}
```

**Response (limit — open):**

```json
{
  "order_id": "ord_a4b5c6",
  "status": "open",
  "side": "sell",
  "type": "limit",
  "amount_requested": 100000000000,
  "amount_filled": 0,
  "limit_price": 0.0001200,
  "expiry": 1712016000,
  "compliance_check": "passed",
  "created_at": 1711930210
}
```

**Compliance flow:**

```
1. CEDEX receives order
2. Pre-flight compliance (2-3s):
   ├─ Custody verification (Empire Ed25519, CV-01 through CV-06)
   ├─ OFAC screening (SC-30 through SC-34)
   ├─ AML risk scoring (IV-09)
   ├─ KYC / eligibility check (IV-07, IV-08)
   ├─ Holding period verification (HP-24)
   ├─ Price impact pre-check (CB-21)
   ├─ Module 2: NAV-deviation pre-check (CB-21 extension)
   └─ Module 3: Classification freshness + federal-action freeze pre-check (CV-04, REG-42)
3. If ANY pre-flight fails → return error immediately (no on-chain tx)
4. If pre-flight passes → submit to Solana
5. Token-2022 Transfer Hook executes all 42 controls on chain
6. If on-chain hook passes → settlement + fee distribution
7. If on-chain hook fails → atomic revert (no fee charged)
```

#### `GET /orders`

List orders for the authenticated wallet.

**Query Parameters:**

| Parameter | Type      | Default | Description                                          |
| --------- | --------- | ------- | ---------------------------------------------------- |
| `status`  | `string`  | —       | `open`, `filled`, `cancelled`, `expired`, `rejected` |
| `mint`    | `string`  | —       | Filter by ST22 mint                                  |
| `side`    | `string`  | —       | `buy` or `sell`                                      |
| `limit`   | `integer` | 50      | Max results (max 200)                                |
| `before`  | `string`  | —       | Cursor: order ID                                     |

**Response:**

```json
{
  "orders": [
    {
      "order_id": "ord_a4b5c6",
      "mint": "7xK9p2...",
      "symbol": "ACME-ST22",
      "side": "sell",
      "type": "limit",
      "status": "open",
      "amount_requested": 100000000000,
      "amount_filled": 0,
      "limit_price": 0.0001200,
      "expiry": 1712016000,
      "created_at": 1711930210
    }
  ],
  "has_more": false
}
```

#### `DELETE /orders/{order_id}`

Cancel an open order.

**Response:**

```json
{
  "order_id": "ord_a4b5c6",
  "status": "cancelled",
  "cancelled_at": 1711930500
}
```

Returns `404` if the order is not found or not owned by the authenticated wallet. Returns `409` if the order is already filled or expired.

#### `GET /portfolio`

Current ST22 holdings with holding-period status.

**Response:**

```json
{
  "wallet": "9aB2xY...",
  "positions": [
    {
      "mint": "7xK9p2...",
      "symbol": "ACME-ST22",
      "module": "equities",
      "balance": 50000000000,
      "value_sol": 5.765,
      "value_usd": 922.40,
      "percent_of_supply": 0.50,
      "within_wallet_limit": true,
      "holding_period": {
        "purchase_timestamp": 1711929600,
        "jurisdiction": "US",
        "regime": "RegD",
        "holding_period_secs": 15778800,
        "unlock_timestamp": 1727708400,
        "is_locked": true,
        "seconds_remaining": 15778200,
        "unlock_date": "2026-09-30T00:00:00Z"
      },
      "custody": {
        "ratio": 1.0,
        "ed25519_verified": true,
        "last_attestation_ms": 1711930400
      }
    }
  ],
  "total_positions": 1,
  "total_value_sol": 5.765,
  "locked_positions": 1,
  "tradeable_positions": 0
}
```

The `holding_period.regime` field reports the offering exemption applied to the position: `"RegD"` (6 months), `"RegS"` (12 months), or `"RegCF"` (12 months). The `holding_period_secs` value reflects the regime.

#### `POST /estimate`

Estimate swap output without executing. No on-chain transaction; no fee charged.

**Request:**

```json
{
  "mint": "7xK9p2...",
  "side": "buy",
  "input_amount": 10000000000
}
```

**Response:**

```json
{
  "mint": "7xK9p2...",
  "side": "buy",
  "input_amount": 10000000000,
  "output_amount": 86758000000,
  "effective_price": 0.00011527,
  "price_impact_bps": 95,
  "would_trigger_circuit_breaker": false,
  "would_succeed": true,
  "fee": {
    "total_lamports": 500000000,
    "total_bps": 500,
    "pool_lamports": 44000000,
    "issuer_lamports": 200000000,
    "staking_lamports": 150000000,
    "protocol_lamports": 106000000
  },
  "pool_state": {
    "sol_reserve": 100000000000000,
    "token_reserve": 1000000000000000000,
    "k": "100000000000000000000000000000000"
  },
  "timestamp": 1711930300
}
```

If the pre-flight check would fail, `would_succeed` is `false` and a `failure_reason` field is returned with one of: `"HOLDING_PERIOD_LOCKED"`, `"WALLET_LIMIT_EXCEEDED"`, `"PRICE_IMPACT_EXCEEDED"`, `"OFAC_MATCH"`, `"AML_HIGH_RISK"`, `"CUSTODY_DISCREPANCY"`, `"NAV_DEVIATION_EXCEEDED"` (Module 2), `"CLASSIFICATION_STALE"` (Module 3), `"FEDERAL_ACTION_FROZEN"` (Module 3).

***

### 6. WebSocket API

Real-time data streams via persistent WebSocket connection.

#### Connection

```
wss://api.cedex.market/ws/v1
```

Authenticated connection (required for private channels):

```
wss://api.cedex.market/ws/v1?token=eyJhbGciOiJFZDI1NTE5...
```

#### Subscribe

```json
{
  "action": "subscribe",
  "channel": "orderbook",
  "mint": "7xK9p2..."
}
```

#### Unsubscribe

```json
{
  "action": "unsubscribe",
  "channel": "orderbook",
  "mint": "7xK9p2..."
}
```

#### Heartbeat

Server sends ping every 30 seconds. Client must respond with pong within 10 seconds or the connection is terminated.

```json
{ "type": "ping", "timestamp": 1711930400 }
```

```json
{ "type": "pong" }
```

#### Channel: `orderbook`

Real-time order book updates. Snapshot on subscribe, then incremental deltas.

**Subscription:**

```json
{ "action": "subscribe", "channel": "orderbook", "mint": "7xK9p2..." }
```

**Snapshot (sent on subscribe):**

```json
{
  "type": "snapshot",
  "channel": "orderbook",
  "mint": "7xK9p2...",
  "bids": [
    { "price": 0.0001150, "amount": 50000000000 },
    { "price": 0.0001145, "amount": 30000000000 }
  ],
  "asks": [
    { "price": 0.0001155, "amount": 40000000000 },
    { "price": 0.0001160, "amount": 25000000000 }
  ],
  "sequence": 100001,
  "timestamp": 1711930400
}
```

**Delta (incremental updates):**

```json
{
  "type": "delta",
  "channel": "orderbook",
  "mint": "7xK9p2...",
  "changes": [
    { "side": "bid", "price": 0.0001150, "amount": 45000000000 },
    { "side": "ask", "price": 0.0001155, "amount": 0 }
  ],
  "sequence": 100002,
  "timestamp": 1711930400
}
```

`amount: 0` = level removed. Apply deltas sequentially by `sequence`. If a sequence gap is detected, re-subscribe for a fresh snapshot.

#### Channel: `trades`

Real-time trade feed.

**Subscription:**

```json
{ "action": "subscribe", "channel": "trades", "mint": "7xK9p2..." }
```

**Message:**

```json
{
  "type": "trade",
  "channel": "trades",
  "mint": "7xK9p2...",
  "id": "trade_a1b2c3d4",
  "side": "buy",
  "amount": 10000000000,
  "price": 0.0001153,
  "value_sol": 1.153,
  "price_impact_bps": 12,
  "tx_signature": "5vGh7kJ...",
  "timestamp": 1711930410
}
```

#### Channel: `custody`

Real-time Empire custody attestation updates (\~400ms per Solana block).

**Subscription:**

```json
{ "action": "subscribe", "channel": "custody", "mint": "7xK9p2..." }
```

**Message:**

```json
{
  "type": "custody_update",
  "channel": "custody",
  "mint": "7xK9p2...",
  "custodied_balance": 1000000000,
  "token_supply": 1000000000,
  "ratio": 1.0,
  "attestation_slot": 285000400,
  "ed25519_verified": true,
  "discrepancy_detected": false,
  "timestamp": 1711930410
}
```

If `discrepancy_detected: true`, all transfers are halted on this mint by Transfer Hook controls CV-01 through CV-06 until 2-of-3 oracle consensus resolves the discrepancy.

#### Channel: `circuit_breaker`

Circuit-breaker activation and deactivation events.

**Subscription:**

```json
{ "action": "subscribe", "channel": "circuit_breaker", "mint": "7xK9p2..." }
```

**Message:**

```json
{
  "type": "circuit_breaker",
  "channel": "circuit_breaker",
  "mint": "7xK9p2...",
  "event": "triggered",
  "breaker_type": "price_halt",
  "trigger_value": 1250,
  "threshold": 1000,
  "cooldown_secs": 900,
  "resume_at": 1711931310,
  "timestamp": 1711930410
}
```

**Breaker types:**

| Type                   | Trigger                                                         | Module Scope |
| ---------------------- | --------------------------------------------------------------- | ------------ |
| `price_halt`           | Price move > threshold in 5 min                                 | All modules  |
| `price_impact`         | Single trade price impact > 2% (or per-mint config)             | All modules  |
| `volume_halt`          | Wallet daily-sell limit > 30%                                   | All modules  |
| `oracle_failure`       | Custody or OFAC oracle stale beyond threshold                   | All modules  |
| `nav_deviation`        | On-chain price deviates from NAV beyond `nav_deviation_max_bps` | Module 2     |
| `nav_stale`            | NAV oracle exceeds `nav_reappraisal_max_age_secs`               | Module 2     |
| `classification_stale` | Classification oracle exceeds `classification_max_age_secs`     | Module 3     |
| `federal_action`       | Federal-action freeze active (Control 42)                       | Module 3     |

#### Channel: `nav` *(Module 2 only)*

Real-time NAV oracle updates for Module 2 mints. See §12.2.

#### Channel: `classification` *(Module 3 only)*

Real-time Classification oracle updates and federal-action events for Module 3 mints. See §12.3.

#### Channel: `orders` (Authenticated)

Private channel — requires authenticated WebSocket connection. Real-time updates for the authenticated wallet's orders.

**Subscription:**

```json
{ "action": "subscribe", "channel": "orders" }
```

**Message:**

```json
{
  "type": "order_update",
  "channel": "orders",
  "order_id": "ord_x1y2z3",
  "status": "filled",
  "amount_filled": 50000000000,
  "effective_price": 0.0001155,
  "tx_signature": "5vGh7kJ...",
  "timestamp": 1711930420
}
```

***

### 7. Compliance Pre-Flight

Every order runs through pre-flight compliance verification before on-chain submission. This saves the user gas fees on trades that would fail the Transfer Hook.

#### Pre-Flight Sequence

| Step | Hook                                            | Source                        | Latency   | Module Scope  |
| ---- | ----------------------------------------------- | ----------------------------- | --------- | ------------- |
| 1    | Custody Verification (CV-01 to CV-06)           | Empire Ed25519 oracle         | 100–150ms | All modules   |
| 2    | OFAC Screening (SC-30 to SC-34)                 | OFAC SDN oracle               | 200–500ms | All modules   |
| 3    | AML Risk (IV-09)                                | Chainalysis + TRM Labs        | 300–400ms | All modules   |
| 4    | KYC and eligibility (IV-07, IV-08)              | Empire registry               | 50–100ms  | All modules   |
| 5    | Holding Period (HP-24)                          | On-chain HoldingPeriodAccount | <10ms     | All modules   |
| 6    | Price Impact (CB-21)                            | TWAP oracle (Pyth Network)    | 50–100ms  | All modules   |
| 7    | NAV Deviation (CB-21 extension)                 | NAVOracle PDA                 | 50–100ms  | Module 2 only |
| 8    | Classification + Federal Action (CV-04, REG-42) | ClassificationOracle PDA      | 50–100ms  | Module 3 only |

**Total pre-flight:** 2,000–3,000ms

If pre-flight fails, the API returns the specific error code immediately — no on-chain transaction submitted, no gas fee charged. The user can see exactly which control would reject the trade and why.

#### Pre-Flight Response (Failure)

```json
{
  "order_id": null,
  "status": "rejected",
  "compliance_check": "failed",
  "failed_control": {
    "control_id": "HP-24",
    "code": 6024,
    "name": "TokensLocked",
    "message": "Tokens locked — Reg D / Reg S / Reg CF holding period not elapsed",
    "details": {
      "mint": "7xK9p2...",
      "beneficiary": "9aB2xY...",
      "purchase_timestamp": 1711929600,
      "unlock_timestamp": 1727708400,
      "seconds_remaining": 15778200,
      "jurisdiction": "US",
      "regime": "RegD"
    }
  }
}
```

#### Module 2 Pre-Flight Failure (NAV Deviation)

```json
{
  "order_id": null,
  "status": "rejected",
  "compliance_check": "failed",
  "failed_control": {
    "control_id": "CB-21",
    "code": 6021,
    "name": "NavDeviationExceeded",
    "message": "Price deviates from NAV beyond configured tolerance",
    "details": {
      "mint": "7xK9p2...",
      "current_price_usd": 1250.00,
      "appraised_nav_usd": 1000.00,
      "deviation_bps": 2500,
      "max_allowed_bps": 2200,
      "last_appraisal_timestamp": 1709251200,
      "next_appraisal_target": 1740787200
    }
  }
}
```

#### Module 3 Pre-Flight Failure (Federal Action)

```json
{
  "order_id": null,
  "status": "rejected",
  "compliance_check": "failed",
  "failed_control": {
    "control_id": "REG-42",
    "code": 6042,
    "name": "FederalActionFrozen",
    "message": "Mint frozen by federal-action regulatory override",
    "details": {
      "mint": "7xK9p2...",
      "freeze_timestamp": 1711930000,
      "freeze_authority": "LegalCounsel+3of5",
      "trigger_source": "Federal Register",
      "action_reference": "EO-14118",
      "expected_resolution": "pending"
    }
  }
}
```

***

### 8. Error Reference

#### HTTP Status Codes

| Status | Meaning       | When                                                     |
| ------ | ------------- | -------------------------------------------------------- |
| `200`  | Success       | Request completed                                        |
| `201`  | Created       | Order placed                                             |
| `400`  | Bad Request   | Invalid parameters                                       |
| `401`  | Unauthorized  | Missing or expired token                                 |
| `403`  | Forbidden     | Empire verification required or wallet blacklisted       |
| `404`  | Not Found     | Resource does not exist                                  |
| `409`  | Conflict      | Order already filled or cancelled; idempotency-key reuse |
| `422`  | Unprocessable | Compliance pre-flight failed (Transfer Hook error)       |
| `429`  | Rate Limited  | Exceeded rate limit                                      |
| `500`  | Server Error  | Internal error                                           |
| `503`  | Unavailable   | Maintenance or Solana network issue                      |

#### Error Response Format

```json
{
  "error": {
    "code": 6024,
    "name": "TokensLocked",
    "message": "Tokens locked — Reg D / Reg S / Reg CF holding period not elapsed",
    "category": "HoldingPeriod",
    "control_id": "HP-24",
    "recoverable": true,
    "details": {
      "mint": "7xK9p2...",
      "beneficiary": "9aB2xY...",
      "purchase_timestamp": 1711929600,
      "unlock_timestamp": 1727708400,
      "seconds_remaining": 15778200,
      "jurisdiction": "US",
      "regime": "RegD"
    }
  },
  "request_id": "req_m7n8o9"
}
```

#### Transfer Hook Error Codes (6001–6042)

| Code      | Name                       | HTTP | Recoverable | User Action                                                                        |
| --------- | -------------------------- | ---- | ----------- | ---------------------------------------------------------------------------------- |
| 6001      | `CustodyDiscrepancy`       | 422  | No          | System-level. Wait for oracle consensus.                                           |
| 6002      | `CustodyOracleUnavailable` | 422  | Yes         | Retry after \~400ms (1 block)                                                      |
| 6003      | `SenderSanctioned`         | 403  | No          | OFAC-flagged wallet. Cannot trade.                                                 |
| 6004      | `ReceiverSanctioned`       | 403  | No          | Receiver OFAC-flagged.                                                             |
| 6005      | `OfacOracleStale`          | 422  | Yes         | OFAC refreshing. Retry in minutes.                                                 |
| 6006      | `AMLHighRisk`              | 403  | No          | AML score above 70. Contact Empire.                                                |
| 6007      | `InvalidSigner`            | 403  | No          | KYC, eligibility, or wallet registration missing.                                  |
| 6008–6019 | CEI / Integrity            | 422  | Varies      | See error message.                                                                 |
| 6020      | `WalletLimitExceeded`      | 422  | Yes         | Reduce amount below 4.99% of supply.                                               |
| 6021      | `PriceImpactExceeded`      | 422  | Yes         | Reduce order size or split into smaller orders.                                    |
| 6022      | `VelocityExceeded`         | 422  | Yes         | Slow down. Wait for velocity window.                                               |
| 6023      | `CrossWalletDetected`      | 403  | No          | Behavioral clustering flagged. Contact compliance.                                 |
| 6024      | `TokensLocked`             | 422  | Yes         | Wait for holding period (Reg D 6mo / Reg S 12mo / Reg CF 12mo).                    |
| 6036      | `GlobalCircuitBreaker`     | 503  | Yes         | All trading halted. Wait for cooldown (\~15 min).                                  |
| 6037      | `DailySellLimitExceeded`   | 422  | Yes         | 30% daily sell limit reached. Wait 24h.                                            |
| 6038      | `CustodyDiscrepancyHalt`   | 503  | No          | Custody issue. Await 2-of-3 consensus.                                             |
| 6039      | `OFACEmergencyBlock`       | 503  | No          | Treasury emergency SDN update.                                                     |
| 6040      | `OracleConsensusFail`      | 503  | Yes         | Oracle consensus not reached. Retry.                                               |
| 6041      | `ControlledMigration`      | 503  | Yes         | Upgrade in progress. Wait.                                                         |
| 6042      | `RegulatoryOverride`       | 503  | No          | Legal Counsel + 3-of-5 freeze. Module 3 federal-action freezes also use this code. |

#### Module 2 Specific Error Annotations

| Code | Variant                | Detail Field                                               | User Action                                                |
| ---- | ---------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| 6021 | `NavDeviationExceeded` | `deviation_bps`, `max_allowed_bps`, `appraised_nav_usd`    | Wait for fresh appraisal that restores price within bounds |
| 6021 | `NavStale`             | `last_appraisal_timestamp`, `nav_reappraisal_max_age_secs` | Mint paused pending fresh appraisal                        |

#### Module 3 Specific Error Annotations

| Code | Variant                           | Detail Field                                             | User Action                                      |
| ---- | --------------------------------- | -------------------------------------------------------- | ------------------------------------------------ |
| 6002 | `ClassificationOracleUnavailable` | `last_refresh`, `classification_max_age_secs`            | Retry after relay refresh                        |
| 6042 | `FederalActionFrozen`             | `freeze_timestamp`, `trigger_source`, `action_reference` | No user action — await federal-action resolution |

#### CEDEX Application Error Codes

| Code                           | Name                 | HTTP | Description                                     |
| ------------------------------ | -------------------- | ---- | ----------------------------------------------- |
| `INVALID_MINT`                 | Invalid Mint         | 400  | Mint address not a valid ST22 token             |
| `INVALID_SIDE`                 | Invalid Side         | 400  | Must be `"buy"` or `"sell"`                     |
| `INVALID_AMOUNT`               | Invalid Amount       | 400  | Amount must be > 0                              |
| `SLIPPAGE_EXCEEDED`            | Slippage Exceeded    | 422  | Output below minimum after slippage             |
| `DEADLINE_EXCEEDED`            | Deadline Exceeded    | 422  | Order deadline passed before execution          |
| `INSUFFICIENT_BALANCE`         | Insufficient Balance | 422  | Wallet balance < order amount                   |
| `ORDER_NOT_FOUND`              | Order Not Found      | 404  | Order ID does not exist for this wallet         |
| `ORDER_NOT_CANCELLABLE`        | Not Cancellable      | 409  | Order already filled or expired                 |
| `EMPIRE_VERIFICATION_REQUIRED` | Not Verified         | 403  | Empire KYC, KYB, AML, OFAC, or KYW not complete |
| `RATE_LIMITED`                 | Rate Limited         | 429  | Request rate exceeded                           |
| `MAINTENANCE`                  | Maintenance          | 503  | System maintenance window                       |
| `POOL_NOT_ACTIVE`              | Pool Inactive        | 503  | Trading pair not active                         |
| `IDEMPOTENCY_CONFLICT`         | Duplicate            | 409  | Same idempotency key with different params      |

***

### 9. Pagination

All list endpoints use cursor-based pagination.

```
GET /markets/{mint}/trades?limit=50
GET /markets/{mint}/trades?limit=50&before=trade_x9y8z7w6
```

**Response pagination fields:**

```json
{
  "data": [...],
  "has_more": true,
  "next_cursor": "trade_x9y8z7w6"
}
```

Pass `next_cursor` as the `before` parameter to fetch the next page. When `has_more` is `false`, no more results exist.

***

### 10. Idempotency

Prevent duplicate orders by including an `idempotency_key` in order placement requests.

```json
{
  "...order fields...",
  "idempotency_key": "order_20260401_001"
}
```

**Behavior:**

| Scenario                                           | Response                              |
| -------------------------------------------------- | ------------------------------------- |
| First request with key                             | Order created normally                |
| Duplicate request with same key + same params      | Returns original order (no duplicate) |
| Duplicate request with same key + different params | `409 IDEMPOTENCY_CONFLICT`            |
| Key reuse after 24 hours                           | Key expired — treated as new request  |

**Key format:** Any string up to 128 characters. Recommended: `{purpose}_{date}_{sequence}`.

***

### 11. Code Examples

#### TypeScript (SDK)

```typescript
import { RwaTokensClient } from '@rwatokens/sdk';

const client = new RwaTokensClient({ network: 'mainnet-beta', wallet });

// Market buy
const order = await client.cedex.placeOrder({
  mint:        mintAddress,
  side:        'buy',
  type:        'market',
  amount:      50_000_000_000n,
  slippageBps: 100,
});
console.log(`Filled: ${order.txSignature}`);
```

#### Python

```python
import requests

BASE  = "https://api.cedex.market/v1"
TOKEN = "eyJhbGciOiJFZDI1NTE5..."

# Get markets
markets = requests.get(f"{BASE}/markets").json()

# Place order
order = requests.post(
    f"{BASE}/orders",
    headers={"Authorization": f"Bearer {TOKEN}"},
    json={
        "mint":             "7xK9p2...",
        "side":             "buy",
        "type":             "market",
        "amount":           50000000000,
        "slippage_bps":     100,
        "idempotency_key":  "py_order_001",
    },
).json()

print(f"Status: {order['status']}, TX: {order.get('tx_signature')}")
```

#### cURL

```bash
# Public: Get order book
curl -s https://api.cedex.market/v1/markets/7xK9p2.../orderbook?depth=10 | jq

# Authenticated: Place order
curl -X POST https://api.cedex.market/v1/orders \
  -H "Authorization: Bearer eyJhbGciOiJFZDI1NTE5..." \
  -H "Content-Type: application/json" \
  -d '{
    "mint": "7xK9p2...",
    "side": "buy",
    "type": "market",
    "amount": 50000000000,
    "slippage_bps": 100
  }' | jq

# Cancel order
curl -X DELETE https://api.cedex.market/v1/orders/ord_x1y2z3 \
  -H "Authorization: Bearer eyJhbGciOiJFZDI1NTE5..." | jq
```

#### WebSocket (JavaScript)

```javascript
const ws = new WebSocket('wss://api.cedex.market/ws/v1');

ws.onopen = () => {
  // Subscribe to order book
  ws.send(JSON.stringify({
    action:  'subscribe',
    channel: 'orderbook',
    mint:    '7xK9p2...',
  }));

  // Subscribe to trades
  ws.send(JSON.stringify({
    action:  'subscribe',
    channel: 'trades',
    mint:    '7xK9p2...',
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === 'ping') {
    ws.send(JSON.stringify({ type: 'pong' }));
    return;
  }

  switch (msg.channel) {
    case 'orderbook':
      if (msg.type === 'snapshot') console.log('Book snapshot:', msg.bids.length, 'bids');
      if (msg.type === 'delta')    console.log('Book delta:', msg.changes);
      break;
    case 'trades':
      console.log(`Trade: ${msg.side} ${msg.amount} @ ${msg.price}`);
      break;
    case 'custody':
      if (msg.discrepancy_detected) console.error('CUSTODY DISCREPANCY');
      break;
    case 'nav':
      console.log(`NAV update: ${msg.appraised_nav_usd} (deviation ${msg.current_deviation_bps} bps)`);
      break;
    case 'classification':
      if (msg.federal_action_active) console.error(`FEDERAL ACTION: ${msg.action_reference}`);
      break;
  }
};
```

***

### 12. Module-Aware API Surface

The CEDEX API serves all three modules through the same endpoints, the same authentication, and the same WebSocket protocol. Module-specific behavior surfaces as additional fields on existing endpoints, dedicated oracle endpoints, dedicated WebSocket channels, and module-specific failure-reason codes. This section consolidates the module-specific surface for integrators building module-aware applications.

#### 12.1 Module 1 — Equities

**Module identifier in API responses:** `"equities"`.

**Distinguishing endpoints.** None beyond the standard set. Module 1 mints use the standard custody, OFAC, AML, and TWAP oracles.

**Distinguishing WebSocket channels.** None.

**Distinguishing fields.** `issuer_cik` (for SEC-reporting issuers). The EDGAR pipeline that supplies issuer-disclosure intelligence to Layer 9 IDOS off-chain compliance is not exposed through the public API; Module 1 IDOS-driven status changes appear through the `circuit_breaker` channel as `oracle_failure` events when issuer eligibility lapses.

#### 12.2 Module 2 — Real Estate

**Module identifier in API responses:** `"real_estate"`.

**Additional Public Endpoint: `GET /oracle/{mint}/nav`**

Returns the most recent appraised NAV for a Module 2 mint:

```json
{
  "mint": "5xR3p9...",
  "appraised_nav_usd": 1000.00,
  "appraiser_signature": "Ed25519AppraiserSig...",
  "appraiser_id": "appraiser_xyz_456",
  "last_appraisal_timestamp": 1709251200,
  "next_appraisal_target": 1740787200,
  "nav_deviation_max_bps": 2200,
  "current_price_usd": 1018.50,
  "current_deviation_bps": 185,
  "is_within_bounds": true,
  "is_fresh": true,
  "staleness_threshold_secs": 31536000,
  "status": "healthy"
}
```

**Additional Market Object Field (Module 2 mints):**

```json
{
  "...standard market fields...",
  "nav": {
    "appraised_nav_usd": 1000.00,
    "current_deviation_bps": 185,
    "is_within_bounds": true,
    "next_appraisal_target": 1740787200
  }
}
```

**Additional Health Field:**

The `oracle_status.nav` field on `GET /health` reports aggregate NAV oracle health: `"healthy"`, `"degraded"` (any per-mint NAV staleness above warning threshold), or `"halted"` (any per-mint NAV exceeds halt threshold).

**Additional WebSocket Channel: `nav`**

Real-time NAV oracle updates for a specific Module 2 mint.

```json
{ "action": "subscribe", "channel": "nav", "mint": "5xR3p9..." }
```

```json
{
  "type": "nav_update",
  "channel": "nav",
  "mint": "5xR3p9...",
  "appraised_nav_usd": 1000.00,
  "current_price_usd": 1018.50,
  "current_deviation_bps": 185,
  "is_within_bounds": true,
  "appraisal_timestamp": 1709251200,
  "appraiser_id": "appraiser_xyz_456",
  "timestamp": 1711930410
}
```

**Module 2 Pre-Flight Failure Reasons:**

| Reason                   | Underlying Control | Recoverable                               |
| ------------------------ | ------------------ | ----------------------------------------- |
| `NAV_DEVIATION_EXCEEDED` | CB-21 (extension)  | Yes — wait for fresh appraisal            |
| `NAV_STALE`              | CB-21 (extension)  | Yes — fresh appraisal will resume trading |

**Application Pattern.** Applications displaying real-time price for Module 2 mints should subscribe to the `nav` channel for the same mint and display the NAV reference alongside the live AMM price. The deviation warning surfaces UX context for users when the NAV-deviation breaker triggers.

#### 12.3 Module 3 — CORECM (Carbon Ore, Rare Earth, and Critical Minerals)

**Module identifier in API responses:** `"corecm"`.

**Additional Public Endpoint: `GET /oracle/{mint}/classification`**

Returns the most recent USGS / DOE classification status and federal-action status for a Module 3 mint:

```json
{
  "mint": "8mB4q1...",
  "usgs_critical_minerals_status": "critical_mineral_rare_earth",
  "doe_critical_materials_status": "high_priority",
  "section_232_applicable": false,
  "dpa_title_iii_applicable": true,
  "federal_action_active": false,
  "active_action_references": [],
  "last_refresh_timestamp": 1711930000,
  "classification_max_age_secs": 86400,
  "is_fresh": true,
  "status": "healthy",
  "monitored_sources": [
    "Federal Register",
    "DOE Critical Materials Strategy",
    "USGS Critical Minerals List",
    "DOD Procurement Directives"
  ]
}
```

**Additional Market Object Field (Module 3 mints):**

```json
{
  "...standard market fields...",
  "classification": {
    "usgs_critical_minerals_status": "critical_mineral_rare_earth",
    "doe_critical_materials_status": "high_priority",
    "federal_action_active": false,
    "is_fresh": true
  }
}
```

**Additional Health Field:**

The `oracle_status.classification` field on `GET /health` reports aggregate Classification oracle health.

**Additional WebSocket Channel: `classification`**

Real-time Classification oracle updates and federal-action events for a specific Module 3 mint.

```json
{ "action": "subscribe", "channel": "classification", "mint": "8mB4q1..." }
```

**Routine update message:**

```json
{
  "type": "classification_update",
  "channel": "classification",
  "mint": "8mB4q1...",
  "usgs_critical_minerals_status": "critical_mineral_rare_earth",
  "doe_critical_materials_status": "high_priority",
  "federal_action_active": false,
  "last_refresh_timestamp": 1711930000,
  "is_fresh": true,
  "timestamp": 1711930410
}
```

**Federal-action event message (P0 incident):**

```json
{
  "type": "federal_action_detected",
  "channel": "classification",
  "mint": "8mB4q1...",
  "action_reference": "EO-14118",
  "trigger_source": "Federal Register",
  "detected_timestamp": 1711930000,
  "freeze_pending": true,
  "expected_freeze_timestamp": 1711933600,
  "timestamp": 1711930000
}
```

**Federal-action freeze applied:**

```json
{
  "type": "federal_action_freeze_applied",
  "channel": "classification",
  "mint": "8mB4q1...",
  "action_reference": "EO-14118",
  "freeze_authority": "LegalCounsel+3of5",
  "freeze_timestamp": 1711933600,
  "trading_halted": true,
  "timestamp": 1711933600
}
```

**Module 3 Pre-Flight Failure Reasons:**

| Reason                  | Underlying Control | Recoverable                          |
| ----------------------- | ------------------ | ------------------------------------ |
| `CLASSIFICATION_STALE`  | CV-04 (extension)  | Yes — wait for relay refresh         |
| `FEDERAL_ACTION_FROZEN` | REG-42             | No — await federal-action resolution |

**Application Pattern.** Applications handling Module 3 mints should subscribe to the `classification` channel for every mint they display. The `federal_action_detected` event provides up-to-an-hour advance notice of a likely Control 42 freeze (the platform's incident response runbook §13 specifies a 60-minute SLA from detection to freeze execution); applications can warn users that orders submitted during this window may revert.

#### 12.4 Cross-Module Properties

The following properties are identical across all three modules:

* Authentication, rate limits, idempotency, pagination.
* Order placement and cancellation endpoints.
* The `markets`, `trades`, `orderbook`, `OHLCV`, `custody`, `circuit_breaker`, and `orders` (private) WebSocket channels.
* The 5% fee distribution structure (2% / 1.5% / 1.06% / 0.44%).
* Stablecoin settlement (USDC, PYUSD).
* Pre-flight steps 1–6 (custody, OFAC, AML, KYC, holding period, price impact).
* Holding-period regimes — Reg D (6 months), Reg S (12 months), Reg CF (12 months).
* Transfer Hook error codes 6001–6042.

***

### 13. Changelog

#### v1.0.0 (Q3 2026)

* Initial release — CEDEX mainnet launch.
* Public endpoints: markets, orderbook, trades, OHLCV, oracle status, health.
* Authenticated endpoints: orders (market and limit), portfolio, estimate.
* WebSocket channels: orderbook, trades, custody, circuit\_breaker, orders (private).
* Wallet signature authentication with Empire verification gate.
* Pre-flight compliance verification (42 controls).
* Idempotency support for order placement.
* Three rate-limit tiers (standard, verified, institutional).
* Module-aware endpoint surface: NAV oracle and `nav` WebSocket channel for Module 2; Classification oracle and `classification` WebSocket channel for Module 3.
* Module-specific failure reasons surfaced in pre-flight responses.

***

### Related Documentation

* **SDK Reference** — `RwaTokensClient` wrapping this API.
* **Smart Contract Reference** — On-chain program documentation.
* **Transfer Hook Reference** — Standalone reference for the 42 controls.
* **Stablecoin Settlement Guide** — USDC and PYUSD settlement architecture and developer integration.
* **Oracle Integration Guide** — Custody, OFAC, AML, TWAP, EDGAR, NAV (Module 2), Classification (Module 3) relay architecture.
* **Compliance Integration Guide** — Regulatory mapping for each pre-flight control.
* **Issuer Onboarding Guide** — Module-specific issuer onboarding flow.
* **Incident Response Playbook** — Module 3 federal-action freeze runbook (§13).

***

*RWA Tokens · CEDEX API Reference · v1.0 · cedex.market · Q3 2026*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bitbook.rwatokens.net/cedex-and-trading/cedex-and-trading/cedex-api-reference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
