> 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/pt-br/guides/get-started.md).

# Primeiros passos

Um passo a passo em oito etapas, do zero até uma posição aberta na Nexus Exchange. Você entra com sua carteira, gera uma chave de API HMAC, assina requisições, adiciona fundos à conta, explora os mercados, envia uma ordem, cancela ou edita a ordem e monitora suas posições.

Cada etapa é mostrada em cinco clientes: cURL, Rust, Python, TypeScript e a CLI da Exchange. Escolha uma aba em cada etapa.

Esta página começou como a aba **Getting Started** da documentação interativa da API que o app da Exchange servia em `/api-docs`. Essa rota não responde mais, então esta página passou a ser o guia.

## Antes de começar

* **Você precisa de uma carteira Ethereum** para assinar a mensagem de login. Nada mais é necessário para começar.
* **URL base.** Os exemplos abaixo usam o host público da testnet. Caminhos sem prefixo ficam sob a base de transporte `/v1`, `https://api.testnet.nexus.xyz/v1`, e caminhos `/api/v1` ficam na raiz do host, de modo que uma URL completa fica `https://api.testnet.nexus.xyz/api/v1/…`. Rodando localmente, a base é `http://localhost:9090`. Substitua pela base da implantação que você está chamando. Os caminhos aparecem com o prefixo `/api/v1` onde existe uma rota versionada. A forma sem prefixo na base `/v1` chega à mesma operação e é a que os clientes oficiais estão adotando. Consulte [URLs base](/api-reference/pt-br/readme.md#base-urls) para as outras bases que o contrato declara e para entender como o override de `servers` nos caminhos `/api/v1` é resolvido.
* **Autenticação.** Dois esquemas: um **token de sessão** (Bearer), usado apenas para criar e gerenciar chaves de API, e a assinatura **HMAC-SHA256** com chave de API, usada para todo o resto, inclusive toda a negociação.
* **Duas implantações.** O app da Exchange é implantado duas vezes a partir de um mesmo código. A implantação de **testnet** está no ar e adiciona fundos às contas por meio de um faucet de crédito sintético. A implantação de **mainnet**, com fundos reais, receberá fundos por meio de USDX transferido pela ponte a partir da Ethereum Mainnet. Ela ainda não está no ar: seu host, `api.nexus.xyz`, não responde. O passo 4 abaixo difere entre as duas, e as duas variantes estão documentadas.
* **Placeholders.** Valores como `0xSIGNATURE_HEX`, `nx_7f3a1b...`, `sess_abc123...` e `0x<wallet-private-key>` são placeholders. Substitua pelos seus; nunca faça commit de um segredo.

### Cobertura de linguagens

O cURL é a referência, e toda etapa tem um exemplo em cURL. Os quatro clientes de SDK/CLI ainda não cobrem todas as etapas. Quando um cliente não tem exemplo para uma etapa, a aba avisa, e você segue o exemplo em cURL. A documentação interativa fazia o mesmo, recorrendo ao cURL com um aviso.

### Pontos de entrada legíveis por máquina

Um agente pode começar por estes sem ler esta página:

* `llms.txt`, em <https://exchange.nexus.xyz/llms.txt>
* `openapi.json`, o contrato OpenAPI, em `https://api.testnet.nexus.xyz/openapi.json`
* `/metadata`, a rota de metadados legíveis por máquina do app da Exchange
* O **servidor MCP**, publicado no npm, então adicioná-lo leva uma linha. Ele roda localmente via stdio, então sua chave de API fica na sua máquina:

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

Suas ferramentas públicas de dados de mercado e de demonstração não exigem credenciais, então o comando é útil antes mesmo de você ter uma chave. Um endpoint MCP hospedado está planejado; seu DNS ainda não está no ar, então hoje não há URL remota para adicionar.

A especificação OpenAPI e o changelog são versionados em [nexus-xyz/nexus-exchange-api](https://github.com/nexus-xyz/nexus-exchange-api), e as versões são acompanhadas no [GitHub Releases](https://github.com/nexus-xyz/nexus-exchange-api/releases).

***

## Autenticação

Os passos 1–3 levam você de uma carteira a uma requisição assinada.

## 1. Entrar

`POST /auth/login`. Não exige autenticação.

Autentique-se com uma assinatura pessoal EIP-191. A mensagem a assinar é sempre a string fixa "Sign in to Nexus Exchange". O servidor recupera o endereço da sua carteira a partir da assinatura.

**Observações**

* O token de sessão expira em 24 horas.
* Você só precisa da sessão para criar e gerenciar chaves de API, não para negociar.

{% 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" %}
Ainda não disponível em TypeScript. Use o exemplo em 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 %}

**Corpo da requisição**

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

**Resposta**

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

## 2. Criar chave de API

`POST /keys`. **Exige token de sessão.**

Use o token de sessão para criar um par de chaves HMAC. O segredo é mostrado uma única vez, então salve-o imediatamente.

**Observações**

* Não é possível recuperar o segredo depois desta resposta.
* As chaves herdam o nível da sua conta. Os cabeçalhos de resposta `X-RateLimit-*` informam os limites de requisições de cada nível.

{% 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" %}
Ainda não disponível em Python. Use o exemplo em cURL.
{% endtab %}

{% tab title="TypeScript" %}
Ainda não disponível em TypeScript. Use o exemplo em cURL.
{% endtab %}

{% tab title="CLI" %}

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

{% endtab %}
{% endtabs %}

**Corpo da requisição**

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

**Resposta**

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

## 3. Assinar requisições

`GET /markets`. **Exige chave de API HMAC.**

Toda requisição autenticada precisa de três cabeçalhos. Monte uma string canônica, aplique HMAC-SHA256 a ela com seu segredo e anexe o resultado.

**Cabeçalhos obrigatórios**

| Cabeçalho     | Obrigatório | Descrição                             |
| ------------- | ----------- | ------------------------------------- |
| `X-API-Key`   | sim         | O ID da sua chave (`nx_...`)          |
| `X-Timestamp` | sim         | Hora atual em ms desde a epoch        |
| `X-Signature` | sim         | HMAC-SHA256 em hex da string canônica |

**Observações**

* Formato canônico: `timestamp\nMETHOD\npath\nquery\nsha256(body)`
* `path` é o caminho **como está escrito no contrato**. Inclua o prefixo `/api/v1` quando a rota o tiver, mas **não** o prefixo de transporte `/v1`, que é removido antes de sua assinatura ser verificada. Chamar `…/v1/markets` significa assinar `/markets`; chamar `…/api/v1/tickers` significa assinar `/api/v1/tickers`.
* O timestamp precisa estar a até ±30 segundos da hora do servidor (milissegundos desde a epoch).
* Em requisições GET sem corpo, faça o hash da string vazia.

{% 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 %}

**Resposta**

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

{% hint style="info" %}
Na documentação interativa, esta etapa tem um botão "Try it" ao vivo para `GET /markets`.
{% endhint %}

***

## Negociação

Os passos 4–8 adicionam fundos à conta, abrem uma posição e a monitoram.

## 4. Adicionar fundos à conta

`POST /account/credit`. **Exige chave de API HMAC.** Somente na testnet.

Credite USDX sintético para começar a negociar. Cada chave de API pode resgatar até 500 USDX por dia. Omita `"amount"` para resgatar todo o limite diário restante.

{% hint style="warning" %}
O faucet de crédito existe apenas na **testnet**. Na implantação de mainnet com fundos reais, este endpoint retorna `403` e a adição de fundos é feita apenas pela ponte. Veja a variante de mainnet abaixo.
{% endhint %}

**Observações**

* Os valores são strings decimais, como todos os valores monetários da API.
* Retorna 429 quando o limite diário se esgota. O limite é renovado no dia UTC seguinte.

{% 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 %}

**Corpo da requisição**

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

**Resposta**

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

### Passo 4 na mainnet: adicione fundos com garantia real

Na implantação de mainnet com fundos reais (planejada, ainda não está no ar), um depósito real substitui o passo 4. A implantação de testnet, para testes, tem um faucet de crédito sintético, e a implantação de mainnet com fundos reais não tem nenhum. Você não precisa tratar essa diferença por conta própria. Um endpoint responde "como esta implantação aceita garantia", e a resposta traz o modo.

[`GET /account/deposit-target`](https://docs.nexus.xyz/api-reference/account/fetch-deposit-address). **Exige chave de API HMAC.**

Não há crédito sintético na mainnet. Pergunte à plataforma para onde enviar a garantia, envie-a e consulte periodicamente até que seu saldo reflita o depósito.

**Não fixe no código o método de adição de fundos.** A resposta é uma união discriminada em `mode`. O modo que você recebe é uma propriedade da implantação, não da sua requisição, e nenhum parâmetro o seleciona. Uma implantação com um contrato de depósito real configurado responde `onchain`. Todas as outras implantações respondem `testnet-faucet` e apontam para seus endpoints de crédito sintético. Ramifique pelo `mode`, e o mesmo código de cliente adiciona fundos a si mesmo em qualquer uma das implantações.

**Observações**

* Apenas descoberta. `GET /account/deposit-target` não movimenta fundos nem cria depósito. Agir com base na instrução retornada é uma etapa separada e explícita.
* No modo `onchain`, `onchain.address` é o endereço do contrato de depósito e `onchain.chain` é a rede onde ele está. Os dois são configuração da implantação, então leia-os e não os fixe no código.
* **`403 EARLY_ACCESS_REQUIRED` significa que ainda não é possível adicionar fundos à sua conta aqui.** Quando uma implantação restringe a adição de fundos a participantes do acesso antecipado, ela recusa uma conta não inscrita, e a recusa é **permanente até que a conta seja inscrita. Não tente novamente.** A restrição espelha `POST /account/credit` e `POST /faucet` de propósito, para que uma conta que não pode receber fundos não seja informada de como recebê-los.
* O endpoint nunca inventa um endereço para preencher o formato `onchain`. Uma implantação configurada para depósitos on-chain cujo endereço esteja malformado retorna `503 DEPOSIT_TARGET_MISCONFIGURED` em vez de publicá-lo, porque depositar em um endereço inválido queima os fundos. Isso é um erro de configuração do operador, não uma falha transitória, e tentar novamente não o resolve.
* `min_amount` é **indicativo, não obrigatório**. É o piso que torna viável uma primeira negociação; nada rejeita um depósito on-chain menor.
* `confirm` é idêntico nos dois modos, então funciona em qualquer implantação. Consulte `GET /account` periodicamente até que `balance` reflita os fundos antes de negociar.
* `POST /account/credit` é um faucet **somente de testnet**, e o USDX creditado é sintético. A orientação do próprio contrato é não construir um fluxo de adição de fundos que presuma que a operação existe em todas as redes. A mainnet não tem crédito sintético algum.
* [`GET /api/v1/bridge/assets`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-assets) lista as redes suportadas e, para cada rede, os ativos depositáveis com suas casas decimais, valor mínimo e confirmações exigidas.
* Acompanhe um depósito entre redes com [`GET /api/v1/bridge/deposits`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-deposits), ou um único depósito pelo seu ID `{tx_hash}:{log_index}` via [`GET /api/v1/bridge/deposits/{id}`](https://docs.nexus.xyz/api-reference/bridge/fetch-bridge-deposit). O watcher escreve esse modelo de leitura, e os endpoints apenas o leem.
* Transferências on-chain são irreversíveis. Envie apenas o ativo que a instrução indica, a partir de uma carteira que você controla.
* O ciclo completo é: adicione fundos aqui, negocie (próximas etapas) e depois saque. `GET /withdrawals` lista seus registros e [`POST /withdrawals`](https://docs.nexus.xyz/api-reference/account/withdraw) inicia um saque. Ele é autenticado por uma `WithdrawIntent` EIP-712 assinada com a própria chave da carteira, **não** por uma chave de API, então não reutiliza as credenciais HMAC acima. Um saque pela ponte é uma operação separada, [`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" %}
Ainda não disponível em Rust. Use o exemplo em cURL. O wrapper de cliente de alto nível para a etapa da ponte ainda está em desenvolvimento.
{% endtab %}

{% tab title="Python" %}
Ainda não disponível em Python. Use o exemplo em cURL.
{% endtab %}

{% tab title="TypeScript" %}
Ainda não disponível em TypeScript. Use o exemplo em cURL.
{% endtab %}

{% tab title="CLI" %}
Ainda não disponível na CLI. Use o exemplo em cURL.
{% endtab %}
{% endtabs %}

**Corpo da requisição**

Nenhum. `GET /account/deposit-target` não recebe parâmetros nem corpo.

**Resposta** (modo `onchain`, o exemplo do contrato para `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. Explorar mercados

`GET /markets/{market_id}/ticker`. **Exige chave de API HMAC.**

Liste os mercados de futuros perpétuos disponíveis e confira os preços atuais.

{% 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 %}

**Resposta**

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

{% hint style="info" %}
O comentário original desta etapa diz `# List markets (all 32)`. Esse é o número de mercados configurados, não o de mercados ativos. A testnet está negociando **4** mercados no momento, então o comentário acima foi corrigido. Consulte [Testnet da Exchange](https://docs.nexus.xyz/exchange/exchange-testnet) para ver o conjunto atual.

Na implantação de mainnet, o conjunto de mercados é diferente. A mainnet é lançada com 3 mercados (`BTC-USDX-PERP`, `ETH-USDX-PERP`, `SOL-USDX-PERP`), expandindo para 32+. O comentário do cURL ali diz `# List markets (3 at internal launch: BTC, ETH, SOL — expanding to 32+)`.

Na documentação interativa, esta etapa tem um botão "Try it" ao vivo para `GET /markets/BTC-USDX-PERP/ticker`.
{% endhint %}

### Precisão de preço e tamanho

Arredonde antes de enviar. Todo mercado declara três regras de quantização, e a plataforma rejeita uma ordem que não as cumpra em vez de arredondá-la por você.

| Campo em `GET /markets` | Regra                                                  |
| ----------------------- | ------------------------------------------------------ |
| `tick_size`             | O preço limite precisa ser um múltiplo exato dele.     |
| `lot_size`              | O tamanho da ordem precisa ser um múltiplo exato dele. |
| `min_order_size`        | O tamanho da ordem precisa ser pelo menos este valor.  |

Para `BTC-USDX-PERP`, esses valores são `0.5`, `0.001` e `0.001`. Então um preço de `83000.25` é inválido, porque não é múltiplo de `0.5`, e um tamanho de `0.0005` também é, porque fica abaixo tanto do lote quanto do mínimo. `83000.00` e `0.001` são válidos.

Leia os valores de cada mercado em vez de fixá-los no código. Eles variam por mercado (`ETH-USDX-PERP` é `0.10` e `0.01`, `SOL-USDX-PERP` é `0.01` e `0.1`) e são configuração definida na listagem. [Especificações de mercado](https://docs.nexus.xyz/exchange/trading/perpetuals/market-specifications) publica a tabela atual de todos os mercados listados.

**Arredonde para o lado seguro.** Arredonde um preço de compra *para baixo* e um preço de venda *para cima* até o tick, e arredonde os tamanhos para baixo até a grade do lote. Arredondar um tamanho para cima pode levar a ordem além da margem que seu patrimônio sustenta, e a ordem é então rejeitada por outro motivo.

## 6. Enviar uma ordem

`POST /orders`. **Exige chave de API HMAC.**

Envie uma ordem limite ou a mercado. A resposta confirma o aceite.

**Observações**

* Use `"type": "market"` para executar imediatamente ao melhor preço disponível.
* Agrupe várias ordens em uma única chamada `POST /orders/batch`. A plataforma as processa em sequência, e os resultados mantêm a ordem da requisição.

{% 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 %}

**Corpo da requisição**

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

**Resposta**

```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. Cancelar ou editar

`DELETE /orders/{order_id}` · `DELETE /orders` · `PATCH /orders/{order_id}`. **Exige chave de API HMAC.**

São três operações separadas:

| Operação                    | Efeito                                                                                           |
| --------------------------- | ------------------------------------------------------------------------------------------------ |
| `DELETE /orders/{order_id}` | Cancela uma ordem em repouso no livro.                                                           |
| `DELETE /orders`            | Cancela todas as ordens em repouso no livro, ou todas as ordens de um mercado com `?market_id=`. |
| `PATCH /orders/{order_id}`  | **Cancelamento e substituição atômicos**: altera o preço e/ou o tamanho em uma única chamada.    |

**Observações**

* **Uma edição retorna uma ordem substituta com um ID novo.** O corpo `200` é a nova ordem; o ID que você editou deixa de existir. Acompanhe o ID que você recebe, não o que você enviou.
* Pelo menos um entre `price` e `size` precisa ser informado em uma edição.
* A verificação de margem pré-negociação da edição **exclui a reserva ainda mantida pela ordem que está sendo substituída**, então ela é dimensionada pela margem que a substituta acrescenta. Alterar o preço mantendo o tamanho não exige margem adicional, e reduzir o tamanho libera margem em vez de exigir mais.
* Ordens de liquidação não podem ser editadas.
* Um `409` em uma edição significa que a ordem mudou depois que você a leu. Ela foi executada ou cancelada entre sua leitura e sua escrita.
* **Cancelamentos usam uma cota de limite de requisições separada da de envios.** Esgotar sua cota de ordens nunca bloqueia um cancelamento. Um `429` com `bucket: cancel` é a única recusa que significa que o seu próprio canal de cancelamento está saturado. Consulte [Limites de requisições](/api-reference/pt-br/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. Monitorar posições

`GET /positions`. **Exige chave de API HMAC.**

Confira as posições abertas, o PnL não realizado e a saúde da conta.

{% 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 %}

**Resposta**

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

{% hint style="info" %}
Na documentação interativa, esta etapa tem um botão "Try it" ao vivo para `GET /account`.
{% endhint %}

***

## WebSockets

Consultas periódicas (polling) bastam para começar. Um livro ao vivo ou um feed de execuções deve usar o stream.

Há dois sockets, e eles não são intercambiáveis:

* [`GET /stream`](https://docs.nexus.xyz/api-reference/websocket/connect-stream) traz dados de mercado públicos e **não exige token**. Envie uma mensagem `{"subscribe": [...]}`. Os frames do livro são snapshots completos dos 20 primeiros níveis, então não há nada a reproduzir após uma reconexão.
* [`GET /ws`](https://docs.nexus.xyz/api-reference/websocket/connect-web-socket) exige um token de [`POST /ws/token`](https://docs.nexus.xyz/api-reference/websocket/create-ws-token) e transporta os canais por conta, além dos públicos, com envelopes `op`, números de sequência e um cursor de reconexão.

Cada página traz a lista de canais, os formatos das mensagens e as regras de reconexão.

Antes de desenvolver com base nele:

* **O cancelamento na desconexão é opcional, por conta, e vem desativado por padrão.** Ative-o com `PUT /account/cancel-on-disconnect` e leia-o com o `GET`. É um dead-man's switch. Quando sua última conexão autenticada cai e não se reconecta dentro da janela de tolerância, a plataforma cancela suas ordens em repouso no livro. Sem ele, uma conexão perdida deixa suas ordens ativas.
* **Verifique `active`, não apenas `enabled`.** `enabled` é a sua própria adesão. `active` também exige a chave de funcionalidade do lado da exchange, então `active` indica se o cancelamento na desconexão vai disparar. Uma conta pode ler `enabled: true` e ainda assim não estar protegida.
* **O stream não é a fonte oficial do estado das posições.** Reconcilie com `GET /positions` e `GET /account` após qualquer reconexão em vez de reproduzir a partir de onde parou.

## Clientes

Os trechos acima usam estes pacotes:

| Cliente    | Pacote / crate           |
| ---------- | ------------------------ |
| Rust       | `nexus_exchange`         |
| Python     | `nexus_exchange`         |
| TypeScript | `@nexus-xyz/exchange-ts` |
| CLI        | o comando `nexus`        |

A CLI e os SDKs das linguagens são distribuídos fora do monorepo da Exchange. O passo a passo guiado não informa os repositórios deles, então as instruções de instalação não são reproduzidas aqui.

## Próximos passos

* [Visão geral](/api-reference/pt-br/readme.md): o que a API da Exchange cobre e como ela está organizada
* [Autenticação](/api-reference/pt-br/guides/authentication.md): tokens de sessão, canonicalização HMAC e gerenciamento de chaves de API em detalhes
* [Tipos de ordem](/api-reference/pt-br/guides/order-types.md): a matriz de requisitos dos oito tipos de ordem, e as páginas de Trading na barra lateral da Referência
* [`GET /stream`](https://docs.nexus.xyz/api-reference/websocket/connect-stream) (público, sem token) e [`GET /ws`](https://docs.nexus.xyz/api-reference/websocket/connect-web-socket) (token de `POST /ws/token`): canais, formatos de mensagem e reconexão


---

# 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/pt-br/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.
