> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/api-reference/ko/guides/get-started.md).

# 시작하기

아무것도 없는 상태에서 Nexus Exchange에서 포지션에 진입하기까지의 8단계 안내입니다. 지갑으로 로그인하고, HMAC API 키를 발급하고, 요청에 서명하고, 계정에 자금을 넣고, 시장을 둘러보고, 주문을 넣고, 주문을 취소하거나 수정하고, 포지션을 모니터링합니다.

모든 단계는 cURL, Rust, Python, TypeScript, Exchange CLI의 다섯 가지 클라이언트로 제시됩니다. 단계마다 탭을 하나 선택하십시오.

이 페이지는 Exchange 앱이 한때 `/api-docs`에서 제공하던 대화형 API 문서의 **Getting Started** 탭에서 시작되었습니다. 그 경로는 더 이상 연결되지 않으므로, 이제 이 페이지가 안내서입니다.

## 시작하기 전에

* 로그인 메시지에 서명하려면 **Ethereum 지갑이 필요합니다**. 시작하는 데 그 밖의 것은 필요하지 않습니다.
* **기본 URL.** 아래 예시는 퍼블릭 테스트넷 호스트를 사용합니다. 접두사가 없는 경로는 `/v1` 전송 기본 경로인 `https://api.testnet.nexus.xyz/v1` 아래에 붙고, `/api/v1` 경로는 호스트 루트에 붙으므로 전체 URL은 `https://api.testnet.nexus.xyz/api/v1/…` 형태가 됩니다. 로컬에서 실행할 때 기본 URL은 `http://localhost:9090`입니다. 호출하는 배포에 맞는 기본 URL로 바꾸십시오. 버전이 있는 경로가 존재하는 곳에서는 `/api/v1` 접두사를 붙여 경로를 표시합니다. `/v1` 기본 URL 위의 접두사 없는 형태도 같은 작업에 도달하며, 공식 클라이언트는 이 형태로 옮겨 가고 있습니다. 계약이 선언하는 다른 기본 URL과 `/api/v1` 경로의 `servers` 재정의가 해석되는 방식은 [기본 URL](/api-reference/ko/readme.md#base-urls)을 참조하십시오.
* **인증.** 두 가지 방식이 있습니다. API 키 생성과 관리에만 쓰이는 **세션 토큰**(Bearer)과, 모든 거래를 포함한 그 밖의 모든 작업에 쓰이는 **HMAC-SHA256** API 키 서명입니다.
* **두 개의 배포.** Exchange 앱은 하나의 코드베이스에서 두 번 배포됩니다. **테스트넷** 배포는 운영 중이며 합성 크레딧 포셋으로 계정에 자금을 넣습니다. 실제 자금을 쓰는 **메인넷** 배포는 Ethereum Mainnet에서 USDX를 브리징하여 자금을 넣게 됩니다. 메인넷은 아직 운영되지 않으며, 호스트인 `api.nexus.xyz`도 연결되지 않습니다. 아래 4단계는 두 배포에서 다르며, 두 가지 방식을 모두 설명합니다.
* **플레이스홀더.** `0xSIGNATURE_HEX`, `nx_7f3a1b...`, `sess_abc123...`, `0x<wallet-private-key>` 같은 값은 플레이스홀더입니다. 자신의 값으로 바꾸십시오. 비밀 값은 절대 커밋하지 마십시오.

### 언어별 지원 범위

cURL이 기준이며, 모든 단계에 cURL 예시가 있습니다. 네 가지 SDK/CLI 클라이언트는 아직 모든 단계를 지원하지 않습니다. 어떤 클라이언트에 해당 단계의 예시가 없으면 탭에 그렇게 표시되며, 그때는 cURL 예시를 따르십시오. 대화형 문서도 안내 문구와 함께 cURL로 대체하는 같은 방식을 썼습니다.

### 기계 판독용 진입점

에이전트는 이 페이지를 읽지 않고도 다음에서 시작할 수 있습니다.

* `llms.txt`: <https://exchange.nexus.xyz/llms.txt>
* `openapi.json`: OpenAPI 계약, `https://api.testnet.nexus.xyz/openapi.json`
* `/metadata`: Exchange 앱의 기계 판독용 메타데이터 경로
* **MCP 서버**: npm에 게시되어 있어 한 줄로 추가할 수 있습니다. stdio를 통해 로컬에서 실행되므로 API 키가 사용자의 컴퓨터를 벗어나지 않습니다.

```bash
claude mcp add nexus-exchange -- npx -y @nexus-xyz/exchange-mcp
```

공개 시장 데이터 및 데모 도구는 자격 증명이 필요 없으므로, 키가 없어도 이 명령이 유용합니다. 호스팅형 MCP 엔드포인트가 계획되어 있지만 DNS가 아직 활성화되지 않았으므로, 현재 추가할 원격 URL은 없습니다.

OpenAPI 사양과 변경 이력은 [nexus-xyz/nexus-exchange-api](https://github.com/nexus-xyz/nexus-exchange-api)에서 버전 관리되며, 릴리스는 [GitHub Releases](https://github.com/nexus-xyz/nexus-exchange-api/releases)에서 추적됩니다.

***

## 인증

1\~3단계에서는 지갑에서 출발해 서명된 요청까지 진행합니다.

## 1. 로그인

`POST /auth/login`. 인증이 필요하지 않습니다.

EIP-191 개인 서명으로 인증합니다. 서명할 메시지는 항상 고정 문자열 "Sign in to Nexus Exchange"입니다. 서버는 서명에서 사용자의 지갑 주소를 복원합니다.

**참고**

* 세션 토큰은 24시간 후 만료됩니다.
* 세션은 API 키를 생성하고 관리할 때만 필요하며, 거래에는 필요하지 않습니다.

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST 'https://api.testnet.nexus.xyz/v1/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "message": "Sign in to Nexus Exchange",
    "signature": "0xSIGNATURE_HEX"
  }'
```

{% endtab %}

{% tab title="Rust" %}

```rust
use nexus_exchange::{Client, Config, EthSigner, Network};

// EIP-191 personal_sign of the fixed login message. The signer
// holds your key only to sign — nothing is written to disk.
let signer = EthSigner::from_hex("0x<wallet-private-key>")?;
let client = Client::new(Config::new(Network::Testnet));

let session = client.sign_in(&signer).await?;
println!("signed in as {}", session.address);
// session.token is a SecretString — hand it to
// Config::session_token to authenticate the /keys endpoints.
```

{% endtab %}

{% tab title="Python" %}

```python
from nexus_exchange import Client, EthSigner

signer = EthSigner.from_hex("0x<wallet-private-key>")

with Client() as client:
    session = client.sign_in(signer)  # EIP-191 personal_sign
    print(session.address, session.token)
```

{% endtab %}

{% tab title="TypeScript" %}
TypeScript에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}

{% tab title="CLI" %}

```bash
export NEXUS_PRIVATE_KEY=0x<your-evm-key>
nexus auth login   # signs EIP-191, stores the session token (mode 0600)
```

{% endtab %}
{% endtabs %}

**요청 본문**

```json
{
  "message": "Sign in to Nexus Exchange",
  "signature": "0xSIGNATURE_HEX"
}
```

**응답**

```json
{
  "token": "sess_abc123...",
  "address": "0xYOUR_WALLET_ADDRESS"
}
```

## 2. API 키 생성

`POST /keys`. **세션 토큰이 필요합니다.**

세션 토큰으로 HMAC 키 쌍을 생성합니다. 시크릿은 한 번만 표시되므로 즉시 저장하십시오.

**참고**

* 이 응답 이후에는 시크릿을 다시 조회할 수 없습니다.
* 키는 계정의 등급을 상속합니다. `X-RateLimit-*` 응답 헤더가 등급별 요청 한도를 알려 줍니다.

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST 'https://api.testnet.nexus.xyz/v1/keys' \
  -H 'Authorization: Bearer sess_abc123...' \
  -H 'Content-Type: application/json' \
  -d '{"label": "my-bot"}'
```

{% endtab %}

{% tab title="Rust" %}

```rust
use nexus_exchange::{Client, Config, Network};

// /keys endpoints authenticate with the session token from step 1.
let client =
    Client::new(Config::new(Network::Testnet).session_token("sess_..."));

let key = client.create_api_key().await?;
// key.secret is returned once — persist it immediately.
println!("key_id: {}", key.key_id);
```

{% endtab %}

{% tab title="Python" %}
Python에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}

{% tab title="TypeScript" %}
TypeScript에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}

{% tab title="CLI" %}

```bash
nexus keys create   # secret is shown ONCE — store it now
```

{% endtab %}
{% endtabs %}

**요청 본문**

```json
{
  "label": "my-bot"
}
```

**응답**

```json
{
  "key_id": "nx_7f3a1b...",
  "secret": "e4d2c8f1...long_hex..."
}
```

## 3. 요청 서명

`GET /markets`. **HMAC API 키가 필요합니다.**

인증이 필요한 모든 요청에는 헤더 세 개가 필요합니다. 정규 문자열을 만들고, 시크릿으로 HMAC-SHA256을 계산한 뒤, 그 결과를 첨부하십시오.

**필수 헤더**

| 헤더            | 필수 | 설명                         |
| ------------- | -- | -------------------------- |
| `X-API-Key`   | 예  | 키 ID(`nx_...`)             |
| `X-Timestamp` | 예  | 에포크 이후 현재 시각(ms)           |
| `X-Signature` | 예  | 정규 문자열의 HMAC-SHA256 16진수 값 |

**참고**

* 정규 형식: `timestamp\nMETHOD\npath\nquery\nsha256(body)`
* `path`는 **계약에 적힌 그대로의** 경로입니다. 경로에 `/api/v1` 접두사가 있으면 포함하되, `/v1` 전송 접두사는 서명 검증 전에 제거되므로 **포함하지 않습니다**. `…/v1/markets`를 호출하면 `/markets`에 서명하고, `…/api/v1/tickers`를 호출하면 `/api/v1/tickers`에 서명합니다.
* 타임스탬프는 서버 시각과 ±30초 이내여야 합니다(에포크 이후 밀리초).
* 본문이 없는 GET 요청은 빈 문자열을 해시하십시오.

{% tabs %}
{% tab title="cURL" %}

```bash
# Build the HMAC signature
TIMESTAMP=$(python3 -c 'import time; print(int(time.time()*1000))')
BODY_HASH=$(echo -n "" | shasum -a 256 | cut -d' ' -f1)
CANONICAL="$TIMESTAMP\nGET\n/markets\n\n$BODY_HASH"
SIGNATURE=$(echo -ne "$CANONICAL" | \
  openssl dgst -sha256 -mac HMAC -macopt "hexkey:$NEXUS_API_SECRET" -hex | awk '{print $NF}')

curl 'https://api.testnet.nexus.xyz/v1/markets' \
  -H "X-API-Key: nx_7f3a1b..." \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE"
```

{% endtab %}

{% tab title="Rust" %}

```rust
use nexus_exchange::{Client, Config, Network};

// The SDK builds the canonical string and HMAC-signs every request.
let client = Client::new(Config::new(Network::Testnet).api_key(
    std::env::var("NEXUS_API_KEY")?,
    std::env::var("NEXUS_API_SECRET")?,
));

let markets = client.fetch_markets().await?;
println!("{} markets", markets.len());
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from nexus_exchange import Client

# The SDK builds the canonical string and HMAC-signs every request.
client = Client(
    api_key=os.environ["NEXUS_API_KEY"],
    api_secret=os.environ["NEXUS_API_SECRET"],
)

print(len(client.fetch_markets()), "markets")
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
import { Client, Network } from "@nexus-xyz/exchange-ts";

// The SDK builds the canonical string and HMAC-signs every request.
const client = new Client({
  network: Network.Testnet,
  apiKey: process.env.NEXUS_API_KEY,
  apiSecret: process.env.NEXUS_API_SECRET,
});

console.log((await client.fetchMarketSummaries()).length, "markets");
```

{% endtab %}

{% tab title="CLI" %}

```bash
nexus setup            # interactive; stores credentials (mode 0600)
# ...or per shell:
export NEXUS_API_KEY=nx_...
export NEXUS_API_SECRET=...
nexus balance          # every request is HMAC-signed for you
```

{% endtab %}
{% endtabs %}

**응답**

```json
[
  { "id": "BTC-USDX-PERP", "base": "BTC", "quote": "USDX", "status": "active" },
  { "id": "ETH-USDX-PERP", "base": "ETH", "quote": "USDX", "status": "active" }
]
```

{% hint style="info" %}
대화형 문서에서는 이 단계에 `GET /markets`를 실제로 호출하는 "Try it" 버튼이 있습니다.
{% endhint %}

***

## 거래

4\~8단계에서는 계정에 자금을 넣고, 포지션에 진입하고, 이를 모니터링합니다.

## 4. 계정 자금 충전

`POST /account/credit`. **HMAC API 키가 필요합니다.** 테스트넷 전용입니다.

거래를 시작하려면 합성 USDX 크레딧을 받으십시오. API 키마다 하루 최대 500 USDX를 받을 수 있습니다. `"amount"`를 생략하면 남은 일일 한도 전액을 받습니다.

{% hint style="warning" %}
크레딧 포셋은 **테스트넷**에만 있습니다. 실제 자금을 쓰는 메인넷 배포에서는 이 엔드포인트가 `403`을 반환하며, 자금은 브리지로만 넣을 수 있습니다. 아래의 메인넷 방식을 참조하십시오.
{% endhint %}

**참고**

* 금액은 API의 모든 금전 값과 마찬가지로 10진수 문자열입니다.
* 일일 한도를 모두 쓰면 429를 반환합니다. 한도는 다음 UTC 날짜에 초기화됩니다.

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST 'https://api.testnet.nexus.xyz/api/v1/account/credit' \
  -H 'X-API-Key: nx_7f3a1b...' \
  -H 'X-Timestamp: UNIX_MS' \
  -H 'X-Signature: HMAC_HEX' \
  -H 'Content-Type: application/json' \
  -d '{"amount": "500"}'
```

{% endtab %}

{% tab title="Rust" %}

```rust
use nexus_exchange::types::Decimal;

// `client` is the HMAC-credentialed client from step 3.
// Pass None to claim the full remaining daily allowance.
let credit = client
    .claim_credit(Some("500".parse::<Decimal>()?))
    .await?;
println!("credited {} (today: {})", credit.amount, credit.credited_today);
```

{% endtab %}

{% tab title="Python" %}

```python
# `client` is the HMAC-credentialed client from step 3.
credit = client.claim_credit("500")  # omit the amount for the daily max
print(credit.amount, credit.credited_today)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
// `client` is the HMAC-credentialed client from step 3.
const credit = await client.claimCredit({ amount: "500" }); // {} = daily max
console.log(credit.amount, credit.credited_today);
```

{% endtab %}

{% tab title="CLI" %}

```bash
nexus account credit --amount 500   # omit --amount for the daily max
```

{% endtab %}
{% endtabs %}

**요청 본문**

```json
{
  "amount": "500"
}
```

**응답**

```json
{
  "amount": "500",
  "credited_today": "500",
  "daily_limit": "500"
}
```

### 메인넷의 4단계: 실제 담보로 자금 충전

실제 자금을 쓰는 메인넷 배포(계획 단계, 아직 운영되지 않음)에서는 실제 입금이 4단계를 대신합니다. 테스트용 자금을 쓰는 테스트넷 배포에는 합성 크레딧 포셋이 있고, 실제 자금을 쓰는 메인넷 배포에는 없습니다. 이를 직접 분기 처리할 필요는 없습니다. 하나의 엔드포인트가 "이 배포는 담보를 어떻게 받는가"에 답하며, 그 답에 방식(mode)이 담겨 있습니다.

[`GET /account/deposit-target`](https://docs.nexus.xyz/api-reference/account/fetch-deposit-address)(영어). **HMAC API 키가 필요합니다.**

메인넷에는 합성 크레딧이 없습니다. 거래소에 담보를 어디로 보낼지 묻고, 보낸 다음, 잔액에 반영될 때까지 폴링하십시오.

**자금 충전 방식을 하드코딩하지 마십시오.** 응답은 `mode`로 구분되는 판별 유니온입니다. 받게 되는 방식은 요청이 아니라 배포의 속성이며, 이를 선택하는 파라미터는 없습니다. 실제 입금 컨트랙트가 설정된 배포는 `onchain`으로 응답합니다. 그 밖의 모든 배포는 `testnet-faucet`으로 응답하며 자신의 합성 크레딧 엔드포인트를 가리킵니다. `mode`에 따라 분기하면 같은 클라이언트 코드로 어느 배포에서든 자금을 충전할 수 있습니다.

**참고**

* 조회 전용입니다. `GET /account/deposit-target`은 자금을 이동하지 않으며 입금도 생성하지 않습니다. 반환된 안내에 따라 행동하는 것은 별도의 명시적인 단계입니다.
* `onchain` 방식에서 `onchain.address`는 입금 컨트랙트 주소이고 `onchain.chain`은 그 컨트랙트가 있는 체인입니다. 둘 다 배포 설정이므로, 하드코딩하지 말고 읽어서 사용하십시오.
* **`403 EARLY_ACCESS_REQUIRED`는 해당 계정에 아직 이곳에서 자금을 넣을 수 없다는 뜻입니다.** 배포가 자금 충전을 얼리 액세스 참여자로 제한하는 경우, 등록되지 않은 계정은 거부되며, 이 거부는 **계정이 등록될 때까지 영구적입니다. 다시 시도하지 마십시오.** 이 게이트는 의도적으로 `POST /account/credit` 및 `POST /faucet`과 같게 동작하므로, 자금을 넣을 수 없는 계정에는 자금 충전 방법을 알려 주지 않습니다.
* 이 엔드포인트는 `onchain` 형태를 채우기 위해 주소를 지어내지 않습니다. 온체인 입금으로 설정되었지만 주소가 잘못된 배포는 주소를 공개하는 대신 `503 DEPOSIT_TARGET_MISCONFIGURED`를 반환합니다. 잘못된 주소로 입금하면 자금이 소실되기 때문입니다. 이는 일시적인 장애가 아니라 운영자의 설정 오류이며, 다시 시도해도 해결되지 않습니다.
* `min_amount`는 **권고 값이며 강제되지 않습니다**. 첫 거래가 가능해지는 하한일 뿐이며, 이보다 작은 온체인 입금을 거부하는 장치는 없습니다.
* `confirm`은 두 방식에서 동일하므로 어느 배포에서든 작동합니다. 거래하기 전에 `balance`에 자금이 반영될 때까지 `GET /account`를 폴링하십시오.
* `POST /account/credit`은 **테스트넷 전용** 포셋이며, 지급되는 USDX는 합성 자산입니다. 계약 자체의 지침은 모든 네트워크에 이 작업이 있다고 가정하는 자금 충전 흐름을 만들지 말라는 것입니다. 메인넷에는 합성 크레딧이 전혀 없습니다.
* [`GET /api/v1/bridge/assets`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-assets)(영어)는 지원 체인과, 체인별로 입금 가능한 자산의 소수점 자릿수, 최소 금액, 필요한 컨펌 수를 나열합니다.
* 크로스체인 입금은 [`GET /api/v1/bridge/deposits`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-deposits)(영어)로 추적하거나, 개별 입금은 `{tx_hash}:{log_index}` ID로 [`GET /api/v1/bridge/deposits/{id}`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-deposit)(영어)에서 추적하십시오. 이 읽기 모델은 감시자(watcher)가 기록하며, 엔드포인트는 이를 읽기만 합니다.
* 온체인 이체는 되돌릴 수 없습니다. 안내에 명시된 자산만, 본인이 관리하는 지갑에서 보내십시오.
* 전체 흐름은 이곳에서 자금을 넣고, 거래하고(다음 단계), 출금하는 것입니다. `GET /withdrawals`는 출금 기록을 나열하고 [`POST /withdrawals`](https://docs.nexus.xyz/api-reference/account/withdraw)(영어)는 출금을 시작합니다. 출금은 API 키가 **아니라** 지갑 자체의 키로 서명한 EIP-712 `WithdrawIntent`로 인증되므로, 위의 HMAC 자격 증명을 재사용하지 않습니다. 브리지 출금은 별도의 작업인 [`POST /api/v1/bridge/withdrawals`](https://docs.nexus.xyz/api-reference/bridge/create-bridge-withdrawal)(영어)입니다.

{% tabs %}
{% tab title="cURL" %}

```bash
# 1) Ask the venue how this deployment accepts collateral.
#    Branch on .mode — "onchain" or "testnet-faucet". Do not assume either shape.
curl 'https://api.testnet.nexus.xyz/v1/account/deposit-target' \
  -H 'X-API-Key: nx_7f3a1b...' \
  -H 'X-Timestamp: UNIX_MS' \
  -H 'X-Signature: HMAC_HEX'

# onchain mode answers with the deposit contract to send to:
#   { "mode": "onchain", "account": "0x742d...", "asset": "USDX", "min_amount": "10",
#     "onchain": { "chain": "nexus-mainnet", "asset": "USDX",
#                  "address": "0x1f98...", "min_amount": "10" },
#     "confirm": { "method": "GET", "path": "/account", "poll_field": "balance" } }

# 2) Send the named asset to onchain.address on onchain.chain from your own wallet.

# 3) Confirm with the instruction's own confirm block — poll until balance moves.
curl 'https://api.testnet.nexus.xyz/v1/account' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'

# Optional: the cross-chain deposit record, once the watcher has seen it.
curl 'https://api.testnet.nexus.xyz/api/v1/bridge/deposits' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'
```

{% endtab %}

{% tab title="Rust" %}
Rust에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오. 브리지 단계용 고수준 클라이언트 래퍼는 아직 개발 중입니다.
{% endtab %}

{% tab title="Python" %}
Python에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}

{% tab title="TypeScript" %}
TypeScript에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}

{% tab title="CLI" %}
CLI에서는 아직 지원되지 않습니다. cURL 예시를 사용하십시오.
{% endtab %}
{% endtabs %}

**요청 본문**

없음. `GET /account/deposit-target`은 파라미터와 본문을 받지 않습니다.

**응답** (`onchain` 방식, 계약에 있는 `DepositTarget` 예시)

```json
{
  "mode": "onchain",
  "account": "0x742d35cc6634c0532925a3b844bc9e7595f0beb0",
  "asset": "USDX",
  "min_amount": "10",
  "onchain": {
    "chain": "nexus-mainnet",
    "asset": "USDX",
    "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
    "token_address": "0xf92b58d2225a73b45ded3bc2290ac1a2077c1cf2",
    "min_amount": "10",
    "instructions": "Approve USDX spend for the deposit contract, then call depositTo(token, amount, beneficiary) with token set to `onchain.token_address`, amount in USDX base units, and beneficiary set to `account`. Only USDX is accepted; other tokens are rejected on-chain. Funds credit to the exchange account within 30s of on-chain confirmation."
  },
  "confirm": {
    "method": "GET",
    "path": "/account",
    "poll_field": "balance",
    "note": "Poll until balance reflects the deposit (SPEC target: within 30s of on-chain confirmation)."
  }
}
```

## 5. 시장 둘러보기

`GET /markets/{market_id}/ticker`. **HMAC API 키가 필요합니다.**

이용 가능한 무기한 선물 시장을 나열하고 현재 가격을 확인합니다.

{% tabs %}
{% tab title="cURL" %}

```bash
# List markets (4 trading on testnet today; 32 configured)
curl 'https://api.testnet.nexus.xyz/v1/markets' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'

# Get a single ticker
curl 'https://api.testnet.nexus.xyz/api/v1/markets/BTC-USDX-PERP/ticker' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'
```

{% endtab %}

{% tab title="Rust" %}

```rust
let markets = client.fetch_markets().await?;
println!("{} markets", markets.len());

let ticker = client.fetch_ticker("BTC-USDX-PERP").await?;
println!(
    "{}: last={:?} mark={:?}",
    ticker.symbol, ticker.last, ticker.mark_price
);
```

{% endtab %}

{% tab title="Python" %}

```python
for market in client.fetch_markets():
    print(market.market_id)

ticker = client.fetch_ticker("BTC-USDX-PERP")
print(ticker.last, ticker.mark_price)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
for (const market of await client.fetchMarketSummaries()) {
  console.log(market.market_id);
}

const ticker = await client.fetchTicker("BTC-USDX-PERP");
console.log(ticker.last, ticker.markPrice);
```

{% endtab %}

{% tab title="CLI" %}

```bash
nexus markets                 # tradable markets and their rules
nexus ticker BTC-USDX-PERP    # ticker for one market
```

{% endtab %}
{% endtabs %}

**응답**

```json
{
  "symbol": "BTC-USDX-PERP",
  "last": 84250.5,
  "bid": 84249.0,
  "ask": 84252.0,
  "volume": 1523.4,
  "change": 2.1
}
```

{% hint style="info" %}
이 단계의 원본 주석은 `# List markets (all 32)`였습니다. 이는 운영 중인 시장 수가 아니라 설정된 시장 수입니다. 현재 테스트넷에서는 **4개** 시장이 거래되고 있으므로 위 주석을 수정했습니다. 현재 시장 목록은 [Exchange Testnet](https://docs.nexus.xyz/exchange/exchange-testnet)을 참조하십시오.

메인넷 배포에서는 시장 구성이 다릅니다. 메인넷은 3개 시장 (`BTC-USDX-PERP`, `ETH-USDX-PERP`, `SOL-USDX-PERP`)으로 시작해 32개 이상으로 확장됩니다. 그곳의 cURL 주석은 `# List markets (3 at internal launch: BTC, ETH, SOL — expanding to 32+)`입니다.

대화형 문서에서는 이 단계에 `GET /markets/BTC-USDX-PERP/ticker`를 실제로 호출하는 "Try it" 버튼이 있습니다.
{% endhint %}

### 가격 및 수량 정밀도

제출하기 전에 반올림하십시오. 모든 시장은 세 가지 단위 규칙을 선언하며, 거래소는 규칙에 맞지 않는 주문을 대신 반올림하지 않고 거부합니다.

| `GET /markets`의 필드 | 규칙                        |
| ------------------ | ------------------------- |
| `tick_size`        | 지정가는 이 값의 정확한 배수여야 합니다.   |
| `lot_size`         | 주문 수량은 이 값의 정확한 배수여야 합니다. |
| `min_order_size`   | 주문 수량은 최소 이 값 이상이어야 합니다.  |

`BTC-USDX-PERP`의 값은 각각 `0.5`, `0.001`, `0.001`입니다. 따라서 `83000.25`라는 가격은 `0.5`의 배수가 아니므로 유효하지 않으며, `0.0005`라는 수량도 로트 단위와 최솟값 모두보다 작으므로 유효하지 않습니다. `83000.00`과 `0.001`은 유효합니다.

값을 하드코딩하지 말고 시장별로 읽으십시오. 값은 시장마다 다르며(`ETH-USDX-PERP`는 `0.10`과 `0.01`, `SOL-USDX-PERP`는 `0.01`과 `0.1`), 상장 시점의 설정입니다. [Market Specifications](https://docs.nexus.xyz/exchange/trading/perpetuals/market-specifications)(영어)에서 상장된 모든 시장의 현재 표를 제공합니다.

**안전한 쪽으로 올림 또는 내림하십시오.** 매수 가격은 호가 단위에 맞춰 *내림*하고 매도 가격은 *올림*하며, 수량은 로트 단위에 맞춰 내림하십시오. 수량을 올림하면 주문이 총자산으로 감당할 수 있는 증거금을 넘어설 수 있고, 그러면 주문이 다른 이유로 거부됩니다.

## 6. 주문하기

`POST /orders`. **HMAC API 키가 필요합니다.**

지정가 또는 시장가 주문을 제출합니다. 응답으로 접수가 확인됩니다.

**참고**

* 최우선 가격으로 즉시 체결하려면 `"type": "market"`을 사용하십시오.
* 여러 주문을 한 번의 `POST /orders/batch` 호출로 묶을 수 있습니다. 거래소는 주문을 순서대로 처리하며, 결과는 요청 순서를 유지합니다.

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST 'https://api.testnet.nexus.xyz/api/v1/orders' \
  -H 'X-API-Key: nx_7f3a1b...' \
  -H 'X-Timestamp: UNIX_MS' \
  -H 'X-Signature: HMAC_HEX' \
  -H 'Content-Type: application/json' \
  -d '{
    "market_id": "BTC-USDX-PERP",
    "side": "buy",
    "type": "limit",
    "size": 0.01,
    "price": 83000.00
  }'
```

{% endtab %}

{% tab title="Rust" %}

```rust
use nexus_exchange::types::{OrderRequest, Side, TimeInForce};

let order = OrderRequest::limit(
    "BTC-USDX-PERP",
    Side::Buy,
    "83000".parse()?,
    "0.01".parse()?,
    TimeInForce::Gtc,
);
let placed = client.create_order(&order).await?;
println!("placed {} — {}", placed.order.id, placed.order.status);
```

{% endtab %}

{% tab title="Python" %}

```python
from decimal import Decimal
from nexus_exchange import OrderRequest

order = OrderRequest.limit(
    "BTC-USDX-PERP", "Buy", Decimal("83000"), Decimal("0.01")
)
placed = client.create_order(order)
print(placed.order.id, placed.order.status)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const { order } = await client.placeOrder({
  market_id: "BTC-USDX-PERP",
  side: "Buy",
  order_type: "Limit",
  price: "83000",
  quantity: "0.01",
  time_in_force: "GTC",
});
console.log(order.id, order.status);
```

{% endtab %}

{% tab title="CLI" %}

```bash
# Prompts for confirmation; pass --yes to skip
nexus order place --market BTC-USDX-PERP --side buy --type limit \
  --price 83000 --quantity 0.01 --tif GTC
```

{% endtab %}
{% endtabs %}

**요청 본문**

```json
{
  "market_id": "BTC-USDX-PERP",
  "side": "buy",
  "type": "limit",
  "size": 0.01,
  "price": 83000.0
}
```

**응답**

```json
{
  "id": "ord_f82a...",
  "status": "open",
  "filled": 0.0,
  "market_id": "BTC-USDX-PERP",
  "side": "buy",
  "type": "limit",
  "size": 0.01,
  "price": 83000.0
}
```

## 7. 취소 또는 수정

`DELETE /orders/{order_id}` · `DELETE /orders` · `PATCH /orders/{order_id}`. **HMAC API 키가 필요합니다.**

이들은 서로 다른 세 가지 작업입니다.

| 작업                          | 효과                                                         |
| --------------------------- | ---------------------------------------------------------- |
| `DELETE /orders/{order_id}` | 대기 중인 주문 하나를 취소합니다.                                        |
| `DELETE /orders`            | 대기 중인 모든 주문을 취소하거나, `?market_id=`를 붙이면 한 시장의 모든 주문을 취소합니다. |
| `PATCH /orders/{order_id}`  | **원자적 취소 후 재주문**: 한 번의 호출로 가격 및/또는 수량을 변경합니다.              |

**참고**

* **수정하면 새 ID를 가진 대체 주문이 반환됩니다.** `200` 본문은 새 주문이며, 수정 대상이었던 ID는 더 이상 존재하지 않습니다. 보낸 ID가 아니라 돌려받은 ID를 추적하십시오.
* 수정할 때는 `price`와 `size` 중 최소 하나를 제공해야 합니다.
* 수정 시의 거래 전 증거금 검사는 **대체되는 주문이 아직 보유하고 있는 예약분을 제외하므로**, 대체 주문이 추가하는 증거금만을 기준으로 산정됩니다. 같은 수량으로 가격만 바꾸면 추가 증거금이 필요 없으며, 수량을 줄이면 증거금이 더 필요해지는 것이 아니라 풀려납니다.
* 청산 주문은 수정할 수 없습니다.
* 수정 시 `409`는 조회한 이후 주문이 변경되었다는 뜻입니다. 조회와 쓰기 사이에 주문이 체결되었거나 취소된 것입니다.
* **취소는 주문 제출과 별도의 요청 한도 예산을 사용합니다.** 주문 예산을 모두 소진해도 취소는 차단되지 않습니다. `bucket: cancel`이 포함된 `429`만이 취소 채널 자체가 포화되었다는 뜻의 거부입니다. [요청 한도](/api-reference/ko/guides/rate-limits.md)를 참조하십시오.

{% tabs %}
{% tab title="cURL" %}

```bash
# Amend a resting order's price — note the response carries a NEW order id
curl -X PATCH 'https://api.testnet.nexus.xyz/api/v1/orders/ORDER_ID?market_id=BTC-USDX-PERP' \
  -H 'X-API-Key: nx_7f3a1b...' \
  -H 'X-Timestamp: UNIX_MS' \
  -H 'X-Signature: HMAC_HEX' \
  -H 'Content-Type: application/json' \
  -d '{"price": 82500.00}'

# Cancel everything on one market
curl -X DELETE 'https://api.testnet.nexus.xyz/api/v1/orders?market_id=BTC-USDX-PERP' \
  -H 'X-API-Key: nx_7f3a1b...' -H 'X-Timestamp: UNIX_MS' -H 'X-Signature: HMAC_HEX'
```

{% endtab %}
{% endtabs %}

## 8. 포지션 모니터링

`GET /positions`. **HMAC API 키가 필요합니다.**

미결제 포지션, 미실현 손익, 계정 건전성을 확인합니다.

{% tabs %}
{% tab title="cURL" %}

```bash
# Open positions
curl 'https://api.testnet.nexus.xyz/api/v1/positions' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'

# Account summary
curl 'https://api.testnet.nexus.xyz/api/v1/account' \
  -H 'X-API-Key: ...' -H 'X-Timestamp: ...' -H 'X-Signature: ...'
```

{% endtab %}

{% tab title="Rust" %}

```rust
let account = client.fetch_balance().await?;
println!("equity {}", account.equity);

for p in client.fetch_positions().await? {
    println!(
        "{} {} size {} | uPnL {}",
        p.market_id, p.side, p.size, p.unrealized_pnl
    );
}
```

{% endtab %}

{% tab title="Python" %}

```python
account = client.fetch_balance()
print(account.equity)

for p in client.fetch_positions():
    print(p.market_id, p.side, p.size, p.unrealized_pnl)
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const account = await client.getAccount();
console.log(account.equity);

for (const p of await client.getPositions()) {
  console.log(p.market_id, p.side, p.size, p.unrealized_pnl);
}
```

{% endtab %}

{% tab title="CLI" %}

```bash
nexus positions   # open positions with PnL
nexus balance     # balance, collateral, equity, margin
```

{% endtab %}
{% endtabs %}

**응답**

```json
{
  "balance": 10000.0,
  "equity": 10012.5,
  "margin_used": 83.0,
  "margin_ratio": 0.008,
  "positions": 1
}
```

{% hint style="info" %}
대화형 문서에서는 이 단계에 `GET /account`를 실제로 호출하는 "Try it" 버튼이 있습니다.
{% endhint %}

***

## WebSocket

처음 시작할 때는 폴링으로 충분합니다. 실시간 오더북이나 체결 피드에는 스트림을 사용해야 합니다.

소켓은 두 가지이며, 서로 바꿔 쓸 수 없습니다.

* [`GET /stream`](https://docs.nexus.xyz/api-reference/websocket/connect-stream)(영어)은 공개 시장 데이터이며 **토큰이 필요 없습니다**. `{"subscribe": [...]}` 메시지 하나를 보내십시오. 오더북 프레임은 상위 20개 호가의 전체 스냅숏이므로, 재연결 후 다시 재생할 것이 없습니다.
* [`GET /ws`](https://docs.nexus.xyz/api-reference/websocket/connect-web-socket)(영어)는 [`POST /ws/token`](https://docs.nexus.xyz/api-reference/websocket/create-ws-token)(영어)에서 받은 토큰이 필요하며, 공개 채널과 함께 계정별 채널을 제공하고 `op` 엔벨로프, 시퀀스 번호, 재연결 커서를 사용합니다.

각 페이지에 채널 목록, 메시지 형태, 재연결 규칙이 있습니다.

이를 기반으로 개발하기 전에 다음을 확인하십시오.

* **연결 해제 시 취소는 계정별 선택(opt-in) 기능이며 기본값은 꺼져 있습니다.** `PUT /account/cancel-on-disconnect`로 설정하고 `GET`으로 조회합니다. 이는 데드맨 스위치입니다. 인증된 마지막 연결이 끊긴 뒤 유예 시간 안에 재연결되지 않으면, 거래소가 대기 중인 주문을 취소합니다. 이 기능이 없으면 연결이 끊겨도 주문은 계속 유효합니다.
* **`enabled`만이 아니라 `active`를 확인하십시오.** `enabled`는 사용자 자신의 선택 여부입니다. `active`는 거래소 측 기능 스위치도 함께 요구하므로, 연결 해제 시 취소가 실제로 작동할지는 `active`가 알려 줍니다. 계정이 `enabled: true`로 조회되더라도 보호되지 않을 수 있습니다.
* **스트림은 포지션 상태의 기준이 아닙니다.** 재연결 후에는 중단된 지점부터 다시 재생하지 말고 `GET /positions`와 `GET /account`로 대조하십시오.

## 클라이언트

위의 코드 조각은 다음 패키지를 사용합니다.

| 클라이언트      | 패키지 / 크레이트               |
| ---------- | ------------------------ |
| Rust       | `nexus_exchange`         |
| Python     | `nexus_exchange`         |
| TypeScript | `@nexus-xyz/exchange-ts` |
| CLI        | `nexus` 명령               |

CLI와 언어별 SDK는 Exchange 모노레포 외부에서 배포됩니다. 안내 자료에 저장소가 명시되어 있지 않으므로, 설치 방법은 여기에 옮기지 않습니다.

## 다음 단계

* [개요](/api-reference/ko/readme.md): Exchange API가 다루는 범위와 구성 방식
* [인증](/api-reference/ko/guides/authentication.md): 세션 토큰, HMAC 정규화, API 키 관리의 전체 내용
* [주문 유형](/api-reference/ko/guides/order-types.md): 여덟 가지 주문 유형 전체의 요구 사항 매트릭스와 레퍼런스 사이드바의 거래(Trading) 페이지
* [`GET /stream`](https://docs.nexus.xyz/api-reference/websocket/connect-stream)(영어, 공개, 토큰 불필요) 및 [`GET /ws`](https://docs.nexus.xyz/api-reference/websocket/connect-web-socket)(영어, `POST /ws/token`에서 받은 토큰 필요): 채널, 메시지 형태, 재연결


---

# 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://docs.nexus.xyz/api-reference/ko/guides/get-started.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.
