# API Reference

This document provides a detailed reference for integrating with the FermiHybrid Sequencer API, which enables interaction with a decentralized order book for Solana token markets.

#### Base URL <a href="#base-url" id="base-url"></a>

You can ping the following URLs (at the `/health`endpoint), for figuring out which is your closest local sequencer for order placement/cancellation. Note that market related read ops can only be performed against the global sequencer.

#### Authentication <a href="#authentication" id="authentication"></a>

All endpoints that modify state (place/cancel orders) require cryptographic signatures to ensure the request originates from the owner of the key. See [Signing Requirements](https://github.com/Fermi-DEX/fermihybrid-sequencer/commits/exp_virtual/#signing-requirements) section for details.

#### Market Operations <a href="#market-operations" id="market-operations"></a>

**Create Market**

Creates a new trading market for a pair of tokens.

**Endpoint:** `POST /markets`

**Request Body:**

```
{
  "base_mint": "Base58EncodedPublicKey",
  "quote_mint": "Base58EncodedPublicKey",
  "name": "MARKET_NAME"
}
```

**Response:**

```
{
  "code": 201,
  "message": "Market created successfully",
  "data": {
    "uuid": "market-uuid",
    "base_mint": "Base58EncodedPublicKey",
    "quote_mint": "Base58EncodedPublicKey",
    "name": "MARKET_NAME",
    "created_at": 1679489282
  }
}
```

**List Markets**

Retrieves all available markets.

**Endpoint:** `GET /markets`

**Response:**

```
{
  "code": 200,
  "message": "Markets retrieved successfully",
  "data": [
    {
      "uuid": "market-uuid-1",
      "base_mint": "Base58EncodedPublicKey",
      "quote_mint": "Base58EncodedPublicKey",
      "name": "SOL/USDC",
      "created_at": 1679489282
    },
    {
      "uuid": "market-uuid-2",
      "base_mint": "Base58EncodedPublicKey",
      "quote_mint": "Base58EncodedPublicKey",
      "name": "BONK/USDC",
      "created_at": 1679489282
    }
  ]
}
```

**Get Orderbook**

Retrieves the current orderbook for a specific market.

**Endpoint:** `GET /markets/:market_id/orderbook`

**Parameters:**

* `market_id` (UUID) - The unique identifier of the market

**Response:**

```
{
  "code": 200,
  "message": "Orderbook retrieved successfully",
  "data": {
    "buys": [
      {
        "order_id": 123,
        "owner": "Base58EncodedPublicKey",
        "price": 50000000,
        "quantity": 2000000000,
        "side": "Buy",
        "expiry": 1679489282,
        "base_mint": "Base58EncodedPublicKey",
        "quote_mint": "Base58EncodedPublicKey",
        "market_id": "market-uuid"
      }
    ],
    "sells": [
      {
        "order_id": 124,
        "owner": "Base58EncodedPublicKey",
        "price": 51000000,
        "quantity": 1000000000,
        "side": "Sell",
        "expiry": 1679489282,
        "base_mint": "Base58EncodedPublicKey",
        "quote_mint": "Base58EncodedPublicKey",
        "market_id": "market-uuid"
      }
    ]
  }
}
```

**Get Trades**

Retrieves recent trade history for a specific market.

**Endpoint:** `GET /markets/:market_id/trades`

**Parameters:**

* `market_id` (UUID) - The unique identifier of the market

**Response:**

```
{
  "code": 200,
  "message": "Trade history retrieved successfully",
  "data": [
    {
      "buyer_order_id": 123,
      "seller_order_id": 456,
      "buyer": "Base58EncodedPublicKey",
      "seller": "Base58EncodedPublicKey",
      "price": 50500000,
      "quantity": 1000000000,
      "timestamp": 1679489282
    }
  ]
}
```

#### Order Operations <a href="#order-operations" id="order-operations"></a>

**Place Order**

Places a new order in a market.

**Endpoint:** `POST /orders`

**Request Body:**

```
{
  "intent": {
    "order_id": 123,
    "owner": "Base58EncodedPublicKey",
    "side": "Buy",
    "price": 50000000,
    "quantity": 1000000000,
    "expiry": 1679489282,
    "market_id": "market-uuid"
  },
  "signature": [signature_bytes]
}
```

The `signature` field must contain a valid ed25519 signature over the message derived from the order intent. See [Order Placement Signing](https://github.com/Fermi-DEX/fermihybrid-sequencer/commits/exp_virtual/#order-placement-signing)for details.

**Response:**

```
{
  "code": 200,
  "message": "Order placed successfully",
  "data": {
    "order_id": 123,
    "market_id": "market-uuid",
    "status": "placed"
  }
}
```

**Cancel Order**

Cancels an existing order.

**Endpoint:** `POST /orders/cancel`

**Request Body:**

```
{
  "order_id": 123,
  "owner": "Base58EncodedPublicKey",
  "market_id": "market-uuid",
  "signature": "HexEncodedSignature"
}
```

The `signature` field must contain a hex-encoded ed25519 signature over the message derived from the cancellation data. See [Order Cancellation Signing](https://github.com/Fermi-DEX/fermihybrid-sequencer/commits/exp_virtual/#order-cancellation-signing) for details.

**Response:**

```
{
  "code": 200,
  "message": "Order cancelled successfully",
  "data": {
    "order_id": 123,
    "market_id": "market-uuid",
    "status": "cancelled"
  }
}
```

#### Signing Requirements <a href="#signing-requirements" id="signing-requirements"></a>

**Order Placement Signing**

To place an order, you must create and sign a message using the following steps:

1. Create an `OrderIntent` with all order details
2. Serialize the `OrderIntent` using Borsh serialization (not JSON)
3. Create the signing message by:
   * Prepending the domain prefix `FRM_DEX_ORDER:`
   * Appending the Borsh-serialized order intent
   * Computing the SHA-256 hash of this combined data
   * Converting the hash to a hex string
   * Converting the hex string to UTF-8 bytes
4. Sign these UTF-8 bytes with an ed25519 private key
5. Include the signature in the request

**Order Cancellation Signing**

To cancel an order, you must create and sign a message using the following steps:

1. Create a `CancelOrderData` with order ID, owner public key, and market ID
2. Serialize using Borsh serialization
3. Create the signing message by:
   * Prepending the domain prefix `FRM_DEX_CANCEL:`
   * Appending the Borsh-serialized cancel data
   * Computing the SHA-256 hash of this combined data
   * Converting the hash to a hex string
   * Converting the hex string to UTF-8 bytes
4. Sign these UTF-8 bytes with an ed25519 private key
5. Convert the signature to a hex string
6. Include the hex-encoded signature in the request

#### Error Handling <a href="#error-handling" id="error-handling"></a>

All API responses follow a standard format:

```
{
  "code": 400,
  "message": "Error message",
  "error": "Detailed error description"
}
```

Common error codes:

* 400: Bad Request (invalid parameters, parsing errors)
* 401: Unauthorized (invalid signature)
* 404: Not Found (market or resource not found)
* 500: Internal Server Error

#### Receipt System <a href="#receipt-system" id="receipt-system"></a>

The sequencer provides cryptographic receipts for each processed order. These receipts can be used to verify that an order was received and processed by the sequencer.

**OrderReceipt Structure**

Copy

```
struct OrderReceipt {
    order_id: u64,
    owner: Pubkey,
    timestamp_ms: u128,
    sequencer_id: String,
    merkle_root: [u8; 32],
    sequencer_signature: [u8; 64],
}
```

The receipt contains:

* `order_id`: The unique identifier of the order
* `owner`: The public key of the order owner
* `timestamp_ms`: The precise millisecond timestamp when the order was processed
* `sequencer_id`: The identifier of the processing sequencer
* `merkle_root`: A cryptographic commitment to the state of the orderbook at the time of processing
* `sequencer_signature`: The sequencer's signature over the receipt data

**Receipt Signing Format**

The sequencer signs the receipt with the following message format:

Copy

```
ORDER_RECEIPT:{order_id}:{owner}:{timestamp_ms}:{sequencer_id}:{merkle_root_hex}
```

**Verifying a Receipt**

To verify a receipt, reconstruct the signing message and verify the signature against the sequencer's public key:

Copy

```
use ed25519_dalek::{PublicKey, Signature, Verifier};
use hex;

// Reconstruct the message that was signed
let message = format!(
    "ORDER_RECEIPT:{}:{}:{}:{}:{}",
    receipt.order_id,
    receipt.owner,
    receipt.timestamp_ms,
    receipt.sequencer_id,
    hex::encode(receipt.merkle_root)
);

// Convert to bytes
let message_bytes = message.as_bytes();

// Parse the signature and sequencer's public key
let signature = Signature::from_bytes(&receipt.sequencer_signature).unwrap();
let sequencer_pubkey = PublicKey::from_bytes(&sequencer_public_bytes).unwrap();

// Verify the signature
let is_valid = sequencer_pubkey.verify(message_bytes, &signature).is_ok();
```


---

# Agent Instructions: 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:

```
GET https://docs.fermilabs.xyz/fermi-dex/api-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
