$1Bitcoin‑only • Free • No API Key • Open Source$3

Build on Bitcoin with absolute clarity

Use Your Wallet API to create wallets, query balances, estimate fees, and broadcast transactions. Designed with simplicity first: every concept is explained, every response is predictable, and every error is actionable.

Authentication

No authentication required. All APIs are free to use, open source, and require no API keys.

curl -X POST https://bitcoinapi.dev/api/wallet \
  -H "Content-Type: application/json" \
  -d '{ "key": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", "gapLimit": 20, "batchSize": 40 }'
Security note.

This endpoint accepts your mnemonic (seed phrase) and returns WIF private keys. Treat these as secrets. For production funds, prefer self‑hosting the open‑source code and call it locally.

Quickstart

  1. Prepare a TEST mnemonic (never share a real wallet seed with third‑party services).
  2. Send a POST to /api/wallet with JSON: {"key": "...", "gapLimit": 20, "batchSize": 40}.
  3. Read your next receive address: purposes.bip84.receive.fresh.address (Native SegWit).
  4. See balances & activity: per purpose under summary.balance and used[].
  5. Totals live under totals.balance.totalSats.

Use mock responses for a safe demo. Turn off to make a real request.

Response appears below
{ "status": "idle" }
$1
POST /api/wallet — Scan an HD wallet (BIP44/49/84/86), get balances, used addresses, and next receive pointer

Name: Wallet Scanner.
Description: Derives addresses for legacy (44), wrapped SegWit (49), native SegWit (84), and Taproot (86); queries Electrum for history/balances; returns used addresses, a single fresh address per branch, and summaries.

Body

{
  "key": "<mnemonic>",        // required: 12+ words, BIP39-valid
  "gapLimit": 20,               // optional: stop after N consecutive unused (1..100)
  "batchSize": 40               // optional: addresses checked in parallel (5..200)
}
curl -X POST "$BASE_URL/api/wallet" \
  -H "Content-Type: application/json" \
  -d '{"key":"abandon abandon ... about","gapLimit":20,"batchSize":40}'

Response (truncated)

{
  "ok": true,
  "meta": {
    "generatedAt": "2025-09-03T12:00:00Z",
    "network": "bitcoin-mainnet",
    "electrum": { "server": "host:50002", "tls": true, "selection": "random" },
    "derivation": { "coinType": 0, "account": 0, "purposes": [44,49,84,86], "branches": { "receive": 0, "change": 1 } },
    "scan": { "gapLimit": 20, "batchSize": 40, "strategy": "history-first; rolling gap; single-fresh; reused scripthash" },
    "security": { "includeWif": true }
  },
  "purposes": {
    "bip84": {
      "receive": {
        "used": [{ "address": "bc1q...", "path": "m/84'/0'/0'/0/0", "index": 0, "wif": "L1...", "tx": { "total": 1, "unconfirmed": 0 }, "balance": { "confirmedSats": "50000", "unconfirmedSats": "0", "totalSats": "50000" } }],
        "fresh": { "address": "bc1q...", "path": "m/84'/0'/0'/0/1", "index": 1, "wif": "Kx...", "tx": { "total": 0, "unconfirmed": 0 }, "balance": { "confirmedSats": "0", "unconfirmedSats": "0", "totalSats": "0" } },
        "summary": { "totalAddressesChecked": 80, "usedAddressCount": 1, "txTotalCount": 1, "txUnconfirmedCount": 0, "balance": { "confirmedSats": "50000", "unconfirmedSats": "0", "totalSats": "50000" } }
      },
      "change": { ... },
      "summary": { ... }
    },
    "bip44": { ... }, "bip49": { ... }, "bip86": { ... }
  },
  "totals": { "totalAddressesChecked": 320, "usedAddressCount": 1, "txTotalCount": 1, "txUnconfirmedCount": 0, "balance": { "confirmedSats": "50000", "unconfirmedSats": "0", "totalSats": "50000" } }
}

How to read it

  • bip84 = Native SegWit (bech32 bc1...) — recommended.
  • receive / change = branches /0 and /1.
  • used[] = addresses that have history (with per‑address balances).
  • fresh = the first unused address after the last used — the next one you should display to receive funds.
  • summary = counts and totals for that branch or purpose.
  • totals = aggregate across all purposes.
Privacy & safety.

Never send a live wallet seed to a third party. Use test mnemonics here, or self‑host the open‑source server. Returned wif fields are private keys—keep them secret.

$2
GET /v1/health — Check API status

Returns API liveness and current network height.

curl "$BASE_URL/v1/health" -H "Authorization: Bearer $API_KEY"

Response

{
  "ok": true,
  "network": "mainnet",
  "chain_height": 857432
}
GET /v1/wallets/{wallet_id}/balance — Get wallet balance

Returns confirmed and unconfirmed satoshi balances for a wallet.

Path Parameters

wallet_id (string) — Required
curl "$BASE_URL/v1/wallets/abcd1234/balance" \
  -H "Authorization: Bearer $API_KEY"

Response

{
  "confirmed_sats": 125000,
  "unconfirmed_sats": 2000,
  "total_sats": 127000
}
POST /v1/transactions/estimate-fee — Estimate network fees

Body

{
  "priority": "fastest" | "fast" | "economy",
  "vbytes": 250
}
curl -X POST "$BASE_URL/v1/transactions/estimate-fee" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"priority":"fast","vbytes":250}'

Response

{
  "fee_rate_sat_per_vb": 19,
  "estimated_fee_sats": 4750
}
POST /v1/transactions — Broadcast a signed transaction

Body

{
  "tx_hex": "...rawhex..."
}

Response

{
  "txid": "f5c3...",
  "status": "broadcasted"
}
GET /v1/transactions/{txid} — Fetch transaction status

Response

{
  "txid": "f5c3...",
  "confirmations": 3,
  "block_height": 857429,
  "fee_sats": 4768
}

Webhooks

Receive real‑time callbacks for events like incoming confirmations and transaction failures.

Events

  • wallet.confirmed — A transaction to your wallet confirmed.
  • tx.failed — Broadcast failed permanently.

Signature

We sign each webhook with an HMAC SHA‑256 secret. Verify via the X‑Wallet‑Signature header.

Example

POST https://yourapp.com/webhooks
X-Wallet-Signature: t=1699999999,v1=31b1c...
{
  "event": "wallet.confirmed",
  "data": { "txid": "f5c3...", "confirmations": 1 }
}

Errors

Errors are standard JSON with an error.code and human‑readable error.message. HTTP status codes are meaningful.

{ "ok": false, "error": { "code": "invalid_mnemonic", "message": "mnemonic must be at least 12 words" } }
400 — invalid_content_type
Content‑Type must be application/json.
400 — invalid_json
Body is not valid JSON.
400 — missing_key
body.key (mnemonic) is required.
400 — invalid_mnemonic
Mnemonic must be 12+ words.
400 — invalid_mnemonic_checksum
BIP39 checksum failed.
405 — method_not_allowed
Use POST only.
503 — electrum_unavailable
Could

Rate Limits

Default rate limit is 60 requests per minute per API key. Responses include headers to help you pace requests:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1699999999

SDKs

JavaScript

npm i @yourorg/wallet-api

import { Wallet } from '@yourorg/wallet-api'
const client = new Wallet(process.env.WALLET_API_KEY)
const health = await client.health()

Dart / Flutter

dependencies:
  your_wallet_api: ^1.0.0

final client = WalletApi(apiKey: '...')
final status = await client.health()

Changelog

  • 2025‑09‑03 — Initial public API design and docs template.
  • 2025‑08‑24 — Added webhook signatures and fee estimator.

Support

Email support@yourdomain.com or visit the #dev‑support channel in your workspace. For production incidents, include request IDs from the X‑Request‑Id header.