Skip to content

Authentication

Your browser creates an Ed25519 key pair. Novrinex receives only the public key, which can verify requests but cannot sign them. The private key is available only when the key is created and is included in the downloaded key file. Keep that file secret.

  1. Sign in to Novrinex with the account-owner wallet.
  2. Open Settings > Developer API.
  3. Create a key and select its scopes.
  4. Add optional IP, market, notional, and expiry restrictions.
  5. Approve the key once with your wallet.
  6. Download the key file.
import asyncio
from novrinex import NovrinexClient
async def main():
async with NovrinexClient.from_key_file("novrinex-key.json") as client:
account = await client.account()
print(account["total_equity"], account["available"])
asyncio.run(main())
import { readFile } from "node:fs/promises";
import { NovrinexClient } from "@novrinex/trading-api";
const keyFile = JSON.parse(
await readFile("novrinex-key.json", "utf8"),
);
const client = NovrinexClient.fromKeyFile(keyFile);
const account = await client.account<{
total_equity: string;
available: string;
}>();
console.log(account.total_equity, account.available);

The clients create the timestamp and nonce, encode the query, hash the request body, and add the signature headers.

Custom clients must send these headers with every private request:

NVRX-API-KEY: nvrx_...
NVRX-TIMESTAMP: 1789038828000
NVRX-NONCE: unique-random-value
NVRX-SIGNATURE: base64url-ed25519-signature
NVRX-SIGNATURE-VERSION: 1

Sign the UTF-8 bytes of this payload:

NVRX1
<key_id>
<timestamp_ms>
<nonce>
<uppercase_method>
<normalized_path>
<canonical_query>
<sha256_hex_of_exact_body_bytes>

The canonical query is sorted by decoded key and value, then encoded with RFC 3986 percent encoding. The body hash must match the exact bytes sent on the wire. Use an empty byte string when the request has no body.

Scope Allows
account:read Account totals, balances, positions, and readiness
orders:read Orders, simulations, and request recovery
orders:write New orders, amendments, and position closes
orders:cancel Single-order cancellation, cancel-all, and cancel-all-after
fills:read Fill history
events:read Private event replay

Grant only the scopes needed by the application.

{
"error": {
"code": "INVALID_SIGNATURE",
"message": "Request signature is invalid.",
"request_id": "req_01J9...",
"retryable": false,
"details": {}
}
}

Common codes are INVALID_SIGNATURE, KEY_REVOKED, KEY_EXPIRED, SCOPE_REQUIRED, and IP_NOT_ALLOWED.