Website
Dashboard
Website
Dashboard
  • 👉 Welcome
  • 🧐 How to set up an account
  • 📈 Monitoring and analytics
  • 🔍 Introducing coins vs tokens
  • 👨‍💼 The meaning of owning crypto
  • 💰 Wallets
  • 📜 Supported Blockchains
  • GITHUB
    • 🐘 SDK PHP
    • 📝 SDK Python
    • 👨‍💻 SDK GOLANG
    • ✳️ SDK NODE JS
    • ✳️ PHP Wallet
  • API REFERENCE
    • 🔑 Authentication & base URL
    • Bitcoin
      • 🔍 Info
        • 🧐 Check BTC node health
        • 📜 Get latest Bitcoin block
      • 🆎 Block
        • 📈 Get Bitcoin block by height
        • 👨‍💻 Get Bitcoin block by hash
        • 📑 Get transaction count in block by height
        • 📑 Get transaction count in block by hash
      • 💰 Transactions
        • 👨‍💻 Get Bitcoin transaction by hash
        • 📝 Send pre-signed raw Bitcoin transaction
      • 👨‍💼 Account
        • 💰 List BTC addresses managed by node wallet
        • 🆎 Get BTC received amount for address
      • 🔐 Watch-only addresses
        • 🔐 Register an account zpub
        • 📜 List registered extended public keys
        • 🆎 Issue the next BTC address
        • 📑 History of issued BTC addresses
        • ❌ Delete a registered zpub
      • 🔍 JSON-RPC
        • 🔍 JSON-RPC
    • Ethereum
      • 🔍 Info
        • 🧐 Check ETH node health
        • 📜 Get latest Ethereum block
      • 🆎 Block
        • 📈 Get Ethereum block by height
        • 👨‍💻 Get Ethereum block by hash
        • 📑 Get transaction count in block by height
        • 📑 Get transaction count in block by hash
      • 💰 Transactions
        • 👨‍💻 Get Ethereum transaction by hash
        • 👨‍💻 Get Ethereum transaction receipt by hash
        • 📝 Send pre-signed raw Ethereum transaction
      • 👨‍💼 Account
        • 🔍 List ETH accounts managed by node
        • 🆎 Get ETH balance for address
        • 🆎 Get transaction count (nonce) for address
        • 👉 Estimate gas for transaction
        • 📑 Read-only contract call (eth_call)
        • 👨‍💼 Send transaction from node-managed account
      • 🔐 Watch-only addresses
        • 🔐 Register an account xpub
        • 📜 List registered extended public keys
        • 🆎 Issue the next ETH address
        • 📑 History of issued ETH addresses
        • ❌ Delete a registered xpub
      • 🔍 JSON-RPC
        • 🔍 JSON-RPC
    • Tron
      • 🔍 Info
        • 📑 Get TRX node info
        • 🧐 Check Tron node health
        • 🪙 List supported TRC20 tokens
      • 🆎 Block
        • 📜 Get latest Tron block
        • 📜 Get latest N blocks
        • 🟠 Get block by number
        • 👨‍💻 Get block by hash
      • 💰 Transactions
        • 👨‍💻 Get transaction by hash
        • 🆎 Get all transactions for an address
        • 📝 Create an unsigned transaction
        • 📡 Broadcast a signed transaction
      • 👨‍💼 Account
        • 🆎 Validate a Tron address
        • 🔍 Get account information
        • 💰 Get account balance
        • 💰 Get all asset balances
        • 💵 Get a single TRC20 balance
        • ⚠️ Create a new Tron address (deprecated)
        • ⚠️ Generate a private key from a mnemonic (deprecated)
        • ⚠️ Send TRX from one address to another (deprecated)
        • ⚠️ Send USDT (TRC20) from one address to another (deprecated)
      • 📊 Schemas
      • 🔍 JSON-RPC
    • Webhooks
      • ✳️ Management
        • 👨‍📜 List webhooks
        • 🧐 Create webhook
        • 👉 Get webhook
        • 👨‍🔁 Update webhook
        • ❌ Delete webhook
        • 🔑 Rotate signing secret
      • 📨 Receiving notifications

🔑 Authentication & base URL

Everything you need to make your first successful call, and the four things that trip up most integrations.

Base URL

https://settla.net

There is one environment. There is no sandbox and no testnet — every endpoint talks to a mainnet node, so treat read calls as free and write calls as real.

Every path in this reference is absolute and already includes the prefix:

PrefixWhat it talks to
/api/v1/btc/…Bitcoin Core node
/api/v1/eth/…Ethereum (Erigon) node
/api/v1/trx/…java-tron node, plus Settla's own Tron indexer
/api/v1/webhooks…Settla itself — no coin segment, webhooks are shared across all coins

Getting a key

Create one in the dashboard at settla.net/app/keys. The key is shown once, at creation. It is a 40-character alphanumeric string:

UgyARw47HVR7WyXHqFsDJOQlIPHieCngwTkBEZdb

A key is bound to your account, not to a coin — the same key works for /btc, /eth, /trx and /webhooks. Deactivating a key in the dashboard takes effect on the next request.

Sending the key

Put it in the X-API-Key header. Header names are case-insensitive, so x-api-key works identically.

curl 'https://settla.net/api/v1/btc/health' \
  -H 'X-API-Key: YOUR_KEY' \
  -H 'Accept: application/json'
{
  "status": "ok",
  "time": "2026-09-02T07:38:18+00:00",
  "chain": "main",
  "blocks": 965138,
  "headers": 965138,
  "verificationProgress": 1
}

Authorization: Bearer YOUR_KEY is also accepted and returns the same data — the API key doubles as a personal access token. Prefer X-API-Key anyway: request statistics in the dashboard are only recorded on the X-API-Key path, so a Bearer-based integration shows up as zero usage on your account page.

If you send both, X-API-Key wins outright — a bad X-API-Key is rejected with 401 even when the Authorization header carries a valid key.

Authentication failures

Two distinct messages, both 401, both worth logging separately:

{ "message": "Unauthorized: API Key or Bearer token required" }

No key at all — header missing, or present but empty.

{ "message": "Unauthorized: Invalid or inactive API Key" }

Key was sent but does not match an active key. Covers "typo", "revoked" and "deactivated in the dashboard" alike; the API deliberately does not distinguish them.

Always send Accept: application/json

This is the single biggest source of surprise on this API.

Without Accept: application/json, framework-level failures render Laravel's HTML error page and validation failures come back as an opaque 500. Your JSON parser will throw on a response that has a perfectly good explanation in it.

Same three broken requests, with and without the header:

RequestWithout AcceptWith Accept: application/json
Path that matches no route404 + HTML page404 + {"message": "The route api/v1/trx/account/balance/nope could not be found."}
POST to a GET-only route405 + HTML page405 + {"message": "The POST method is not supported for route api/v1/btc/health. Supported methods: GET, HEAD."}
POST /api/v1/webhooks with a bad body500 + {"message": "Internal server error"}422 + full field-by-field errors map

That 500 is not a server fault. A validation failure without Accept produces a redirect, and /api/v1 converts every 3xx to 500 on purpose — a redirect is useless to a JSON client and would otherwise vanish from your usage statistics. Adding the header turns it back into the 422 you actually wanted:

{
  "message": "The coin field is required. (and 2 more errors)",
  "errors": {
    "coin": ["The coin field is required."],
    "webhook_url": ["The webhook url field is required."],
    "addresses": ["The addresses field is required."]
  }
}

Note also that a path parameter which fails its route constraint — a non-numeric block height, for instance — is a routing miss, not a validation error. It comes back as the 404 above, never as a 422.

Error shapes

There is no single error envelope. Which one you get depends on the endpoint, so check for the key you expect rather than assuming:

ShapeWhere
{"error": "Could not connect to BTC node."}Most /btc, /eth, /trx endpoints
{"message": "…"}Authentication failures, and framework 404/405
{"message": "…", "errors": {…}}422 validation failures (webhooks, request bodies)
{"status": "error", "message": "…"}The /health endpoints only
{"error": {"code": -32601, "message": "…"}}The /jsonrpc proxies

Two behaviours to code around specifically:

  • 500 does not reliably mean "the node is down". The node-backed endpoints collapse most upstream failures into Could not connect to <COIN> node. — an unknown txid, an unparseable address and a genuine outage all look identical. Check /health before concluding the node is unavailable.
  • 200 does not always mean success. POST /api/v1/trx/transactions/broadcast answers 200 even when java-tron rejects the transaction; branch on result === true in the body. The /jsonrpc proxies likewise put method-level failures in error while the transport succeeds.

Rate limits

There are none on /api/v1 today. No RateLimit-* or X-RateLimit-* headers are returned, and no 429 is issued. This is deliberate: adding an external throttle would break existing integrations.

That is not a licence to hammer the API — you are talking to real nodes, and getblock on a busy Bitcoin block expands to several megabytes of JSON. Poll on a sane interval, or better, use webhooks so the platform pushes to you instead.

Per-request usage is recorded per key and visible at settla.net/app/keys — again, only for requests sent with X-API-Key.

Quickstart

Three calls that prove your credentials, connectivity and parsing all work:

export SETTLA_API_KEY='YOUR_KEY'

# 1. Is the node up, and how far along is it?
curl 'https://settla.net/api/v1/btc/health' \
  -H "X-API-Key: $SETTLA_API_KEY" -H 'Accept: application/json'

# 2. Read a real transaction.
curl 'https://settla.net/api/v1/btc/transactions/5fc111d07140a808ba08ac28f61fd436efbfe9d84f5437abe980b42c8d9f0a5e' \
  -H "X-API-Key: $SETTLA_API_KEY" -H 'Accept: application/json'

# 3. Confirm your error handling: this one must come back 401.
curl -i 'https://settla.net/api/v1/btc/health' \
  -H 'X-API-Key: definitely-not-a-key' -H 'Accept: application/json'

Every endpoint page in this reference carries a ready-to-run curl block in the same form — copy it, export SETTLA_API_KEY, and it runs as-is.

Keys and custody

Settla never needs your private keys. The Bitcoin and Ethereum flows are build-and-sign-locally, then broadcast: POST /api/v1/btc/transactions/send-raw and POST /api/v1/eth/transactions/send-raw take a signed hex blob and nothing else.

Four Tron endpoints are the exception — they still accept or return a private key and are deprecated, with a sunset date of 2026-12-01. They are marked ⚠️ in the sidebar. Migrate to POST /api/v1/trx/transactions/create → sign locally → POST /api/v1/trx/transactions/broadcast.

Prev
GITHUB