# Exchange Endpoint

The Superstack wallet API provides an endpoint to interact with and trade on the Hyperliquid chain. This is useful for programmatically executing perps & spot trading on Hyperliquid.

**Endpoint:** `POST <https://wallet-service.superstack.xyz/api/exchange`>

**Headers:**

* `Content-Type: application/json`
* `Authorization: Bearer <YOUR_API_KEY>`

**Request Body:**

```json
{
  "action": {
    "type": "<action_type>",
	   // action-specific parameters
  },
  "vaultAddress": String, // optional, set it if trading on behalf of a vault or subaccount
  "expiresAfter": Number, // optional, expires timestamp in milliseconds
}
```

**Subaccounts and vaults**

If you want to trade on behalf of a subaccount or vault, you can set the `vaultAddress` field to the address of the subaccount or vault. The format is 42-character hexadecimal address string.

**Expires After**

Some actions support an optional field `expiresAfter` which is a timestamp in milliseconds after which the action will be rejected. Users can set it to limit the action to a certain time period.

**Action Types**

Currently, the following actions are supported:

* `order`: Place an order
* `cancel`: Cancel an order
* `cancelByCloid`: Cancel an order by client order ID
* `scheduleCancel`: Schedule automatic order cancellation
* `batchModify`: Modify multiple orders
* `updateLeverage`: Update leverage
* `updateIsolatedMargin`: Update isolated margin
* `usdSend`: Transfer USDC within the Hyperliquid ecosystem
* `spotSend`: Transfer spot assets
* `usdClassTransfer`: Transfer from Spot account to Perp account (and vice versa)

Following are the details of each action.

#### **Action:** Place an order

Place one or more orders on the Hyperliquid.

**Action Type:** `order`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "order",
    "orders": [{
      "a": Number,        // asset ID
      "b": Boolean,       // isBuy
      "p": String,        // price
      "s": String,        // size
      "r": Boolean,       // reduceOnly
      "t": {
        "limit": {
          "tif": "Alo" | "Ioc" | "Gtc"
        } or
        "trigger": {
          "isMarket": Boolean,
          "triggerPx": String,
          "tpsl": "tp" | "sl"
        }
      },
      "c": String        // optional, cloid (client order id), 128-bit hex string, e.g. "0x1234567890abcdef1234567890abcdef"
    }],
    "grouping": "na" | "normalTpsl" | "positionTpsl",
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Cancel order(s)

Cancel one or more orders by order ID on the Hyperliquid.

**Action Type:** `cancel`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "cancel",
    "cancels": [{
      "a": Number,  // asset ID
      "o": Number   // oid (order id)
    }]
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Cancel order(s) by cloid

Cancel one or more orders by client order ID on the Hyperliquid.

**Action Type:** `cancelByCloid`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "cancelByCloid",
    "cancels": [{
      "asset": Number,
      "cloid": String
    }]
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Schedule cancel

Schedule automatic order cancellation on the Hyperliquid.

**Action Type:** `scheduleCancel`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "scheduleCancel",
    "time": Number // optional, timestamp
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Modify multiple orders

Modify multiple existing orders on the Hyperliquid.

**Action Type:** `batchModify`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "batchModify",
    "modifies": [{
      "oid": Number | Cloid,
      "order": {
        "a": Number,
        "b": Boolean,
        "p": String,
        "s": String,
        "r": Boolean,
        "t": {
          "limit": {
            "tif": "Alo" | "Ioc" | "Gtc"
          } or
          "trigger": {
            "isMarket": Boolean,
            "triggerPx": String,
            "tpsl": "tp" | "sl"
          }
        },
        "c": Cloid // optional, client order id
      }
    }]
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Update leverage

Update cross or isolated leverage on a coin on the Hyperliquid.

**Action Type:** `updateLeverage`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "updateLeverage",
    "asset": Number,    // asset ID
    "isCross": Boolean, // true or false if updating cross-leverage,
    "leverage": Number  // integer representing new leverage, subject to leverage constraints on that coin
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Update isolated margin

Add or remove margin from isolated position on the Hyperliquid.

**Action Type:** `updateIsolatedMargin`

**Required API Key Permissions:** `TRADING`

**Request Body:**

```json
{
  "action": {
    "type": "updateIsolatedMargin",
    "asset": Number,  // asset ID
    "isBuy": Boolean, // true, (this parameter won't have any effect until hedge mode is introduced)
    "ntli": Number    // int representing amount to add or remove with 6 decimals, e.g. 1000000 for 1 usd,
  }
  "vaultAddress": String, // optional
  "expiresAfter": Number, // optional
}
```

#### **Action:** Core USDC transfer

Send USD to another address on the Hyperliquid.

**Action Type:** `usdSend`

**Required API Key Permissions:** `TRANSFER`

**Request Body:**

```json
{
  "action": {
    "type": "usdSend",
    "destination": String, //  address in 42-character hexadecimal format; e.g. 0x0000000000000000000000000000000000000000,
    "amount": String       // amount of usd to send as a string, e.g. "1" for 1 usd,
  }
}
```

#### **Action:** Core spot transfer

Send spot assets to another address on the Hyperliquid.

**Action Type:** `spotSend`

**Required API Key Permissions:** `TRANSFER`

**Request Body:**

```json
{
  "action": {
    "type": "spotSend",
    "destination": String, // address in 42-character hexadecimal format; e.g. 0x0000000000000000000000000000000000000000
    "token": String,       // tokenName:tokenId; e.g. "PURR:0xc4bf3f870c0e9465323c0b6ed28096c2"
    "amount": String       // amount of token to send as a string, e.g. "0.01"
  }
}
```

#### **Action:** Transfer from Spot account to Perp account (and vice versa)

Transfer funds between spot and perpetual accounts on the Hyperliquid.

**Action Type:** `usdClassTransfer`

**Required API Key Permissions:** `TRANSFER`

**Request Body:**

```json
{
  "action": {
    "type": "usdClassTransfer",
    "amount": String, // amount of usd to transfer as a string, e.g. "1" for 1 usd.
    "toPerp": Boolean, // true if (spot -> perp) else false,
  }
}
```

#### Example Usage

#### Rust SDK

```rust
use superstack_rust_sdk::{BulkOrder, Limit, Order, OrderRequest, SuperstackApiClient};

#[tokio::main]
async fn main() {
    let api_key = std::env::var("API_KEY").unwrap();
    let client = SuperstackApiClient::new(&api_key);

    let order = BulkOrder {
        orders: vec![OrderRequest {
            asset: 0, // BTC
            is_buy: true,
            reduce_only: false,
            limit_px: "110000.0".to_string(),
            sz: "0.0001".to_string(),
            cloid: None,
            order_type: Order::Limit(Limit {
                tif: "Gtc".to_string(),
            }),
        }],
        grouping: "na".to_string(),
    };
    let response = client.order(order).await.unwrap();
    println!("Order response: {:?}", response);
}
```

#### REST API

First, send the order to the API exchange endpoint to get the response:

```bash
curl -X POST <https://wallet-service.superstack.xyz/api/exchange> \\
  -H "Authorization: Bearer <YOUR_API_KEY>" \\
  -H "Content-Type: application/json" \\
  -d '{
    "action": {
      "type": "order",
      "orders": [{
        "a": 0,
        "b": true,
        "p": "110000",
        "s": "0.0001",
        "r": false,
        "t": {"limit": {"tif": "Gtc"}}
      }],
      "grouping": "na"
    }
  }'
```

Users will get a response like this:

```json
{
    "payload": {
        "action": {
            "grouping": "na",
            "orders": [{
                "a":0,
                "b":true,
                "p":"110000",
                "r":false,
                "s":"0.0001",
                "t":{"limit":{"tif":"Gtc"}},
                "type":"order"
            }],
            "signature": {
                "r":"0x7f4711b90512984fd5a7f5bc821f6d22ede53c59ba7a1a63a9f9b1984dc7c458",
                "s":"0x790f5f3ef1067bb0dc261170c31ec1a2325d3e2bf24353af7ff441f0a6e64111",
                "v":27
            },
            "nonce": 1758104547424
        }
    }
}
```

Then, extract the `payload` field from the response and send it to the Hyperliquid exchange endpoint to execute it:

```bash
curl -X POST <https://api.hyperliquid.xyz/exchange> \\
  -H "Content-Type: application/json" \\
  -d your_payload
```
