> For the complete documentation index, see [llms.txt](https://docs.kryptox.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kryptox.finance/api.md).

# API

## Introduction

* The request URL must be assembled from the BASE URL and the specific endpoint path.
* This document lists the REST endpoint base URL: `https://api.kryptox.finance`.
* For `GET` and `DELETE` requests, all query parameters must be included in the URL (e.g. `/api/v1/market/instruments-info?symbol=BTCUSDC`). If there is no request body (typical for `GET`), the body must be an empty string `""`.
* For `POST` requests, all parameters must be included in the request body as JSON (e.g. `{"currency": "BTC"}`). Do not include extra whitespace in the JSON string.
* All requests and responses use the `application/json` content type.

### Authentication

Each endpoint declares its own authentication type, which determines what credentials must be supplied when calling it. When authentication is required, the request must include the authentication signature headers below.

| Type       | Description                       |
| ---------- | --------------------------------- |
| NONE       | Public endpoint; no auth required |
| USER\_DATA | Requires a valid signed request   |

#### Authentication Signature Headers

| Header         | Description                                                                                |
| -------------- | ------------------------------------------------------------------------------------------ |
| `kx-user`      | Account wallet address                                                                     |
| `kx-signer`    | API wallet address. If you have not created an API wallet, use the account wallet address. |
| `kx-nft`       | Sub-account NFT ID                                                                         |
| `kx-nonce`     | Current timestamp in microseconds                                                          |
| `kx-signature` | Request signature                                                                          |

* The message to be signed is the pre-concatenated string `{kx-user + kx-nft + kx-signer + kx-nonce + body}`.
* The signed body must be byte-identical to the request body that is actually sent.

#### Place Order Example (Python)

```python
# order test
import json
import time

import requests
from eth_account import Account
from eth_account.messages import encode_typed_data

host = "https://api.kryptox.finance"
domain_name = "kryptox"

# kx-user
kx_user = "0x6943e080745DB3E1E2bE9B703C845B976b15f2FD"
# api wallet
kx_signer = "0xDF5EaB18e88c7715E2EFa7814fA54Ee60d3BB55A"
kx_signer_private_key = "2ae9c6f1c3c57bf256c92e186059df18150d17af2ebaed020269cbb9b2e99f43"
kx_nft = "14"

typed_data = {
    "types": {
        "EIP712Domain": [
            {"name": "name", "type": "string"},
            {"name": "version", "type": "string"},
            {"name": "chainId", "type": "uint256"},
            {"name": "verifyingContract", "type": "address"}
        ],
        "Message": [
            {"name": "msg", "type": "string"}
        ]
    },
    "primaryType": "Message",
    "domain": {
        "name": domain_name,
        "version": "1",
        "chainId": 1666,
        "verifyingContract": "0x0000000000000000000000000000000000000000"
    },
    "message": {
        "msg": "$msg"
    }
}

base_headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
}

place_order = {
    "url": "/api/v1/order",
    "method": "POST",
    "params": {
        "symbol": "BTCUSDC",
        "type": "limit",
        "side": "BUY",
        "size": "1",
        "price": 60000,
        "clientOid": "123"
    }
}
batch_place_order = {
    "url": "/api/v1/batch-orders",
    "method": "POST",
    "params": [
        {
            "symbol": "BTCUSDC",
            "type": "limit",
            "side": "BUY",
            "size": "1",
            "price": 60000,
            "clientOid": "123"
        }
    ]
}

_last_sec = 0
_i = 0

def get_nonce():
    global _last_sec, _i
    now_sec = int(time.time())

    if now_sec == _last_sec:
        _i += 1
    else:
        _last_sec = now_sec
        _i = 0

    return now_sec * 1_000_000 + _i

def build_signature(message):
    typed_data["message"]["msg"] = message
    sign_message = encode_typed_data(full_message=typed_data)
    return Account.sign_message(sign_message, private_key=kx_signer_private_key).signature.hex()

def build_request_body(params):
    return json.dumps(params, separators=(",", ":"), ensure_ascii=False)

def build_auth_headers(body, nonce):
    nft_value = kx_nft or ""
    message = kx_user + nft_value + kx_signer + nonce + body
    headers = dict(base_headers)
    headers["kx-user"] = kx_user
    headers["kx-signer"] = kx_signer
    headers["kx-nonce"] = nonce
    headers["kx-signature"] = build_signature(message)
    headers["kx-nft"] = nft_value
    return headers

def send(api):
    body = build_request_body(api["params"])
    nonce = str(get_nonce())
    headers = build_auth_headers(body, nonce)
    request_url = host + api["url"]

    print("url:", request_url)
    print("headers:", headers)
    print("body:", body)

    response = requests.request(
        method=api.get("method", "POST"),
        url=request_url,
        headers=headers,
        data=body.encode("utf-8"),
    )
    print(response, response.text, response.headers)

if __name__ == "__main__":
    send(place_order)
    # send(batch_place_order)
```

### Rate Limits

#### REST Rate Limits

Each user has a fixed API resource pool that refreshes periodically. Each API call consumes a quota from the pool; once the pool hits 0, further requests are rate-limited and the server returns HTTP `429` with error code `429000`.Pool size: `2000 / 30s`.Example: a `Place Order` call has weight `2`, so the remaining pool drops to `1998` after one call. When the pool reaches `0`, requests get throttled. If the pool is not exhausted within 30s, it resets to `2000`.Each response includes the following headers:

```bash
"gw-ratelimit-limit": 500
"gw-ratelimit-remaining": 300
"gw-ratelimit-reset": 1489
```

#### Public Endpoint Rate Limits

Public endpoints are IP-rate-limited. For heavy use of public endpoints, prefer the WebSocket interface (where available) over REST. To avoid IP-level rate limits, you can:

* Bind multiple IP addresses (IPv4 or IPv6) to a single server.
* Send requests from different IP addresses.

#### Server Overload Throttling

Beyond the regular rate limits, server overload may trigger temporary throttling. In this case the system returns error code `429000`, but the response headers do not include per-account rate-limit info. This throttling does not count against the regular quota. Retry later.

#### WebSocket Rate Limits

1. Connections: each user is allowed 100 connections, and each IP is allowed 100 connections.
2. Client-to-server messages: 10 messages per second.
3. Subscriptions: up to 100 streams per request; up to 1024 streams subscribed on a single connection.


---

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

```
GET https://docs.kryptox.finance/api.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.
