Test Mode

API Reference

Webhooks

VerifyBTC API Documentation

A comprehensive guide to integrating Bitcoin signature verification into your applications using the VerifyBTC API.

Authentication

Get started with API keys

Rate Limits

Understand request limits

Security

Best practices & HTTPS

Base URL

https://api.verifybitcoin.io

All API requests should be made to this base URL. HTTPS is required for all requests.

Standards and Network Mode

VerifyBTC separates address-control proofs from reserve proofs. Address verifications use BIP-137 or BIP-322 message signing. Reserve workflows can use BIP-127 proof-of-reserves structure.

BIP-137: legacy recoverable ECDSA message signatures.

BIP-322: generic message signing for SegWit, Taproot, and script-based addresses.

BIP-127: proof-of-reserves transactions and proof metadata for reserve attestations.

Production mode accepts mainnet Bitcoin addresses. Test mode accepts test-network addresses such as tb1..., m..., n..., and 2.... Network mismatches are rejected before signature verification.

Production: mainnetTest mode: test networkBIP-127: mainnet/testnet magic

Authentication

The VerifyBTC API uses API keys to authenticate requests. Include your API key in the X-API-Key header with every request.

Getting an API Key

1. Log in to your Dashboard

2. Open API Keys from the sidebar

3. Click "Create New API Key"

4. Select only the permissions your integration needs

5. Copy and store your key securely (it won't be shown again)

API Key Permissions

Keys can be limited to reading cases, creating or closing cases, downloading reports, or validating proof files. Existing keys keep full public API access until you replace them with narrower keys.

cURL Example

curl -X POST https://api.verifybitcoin.io/public/verifications \ -H "X-API-Key: btcv_abc123..." \ -H "Content-Type: application/json" \ -d '{"bitcoin_address": "bc1q...", "amount": 100000, "context_note": "Escrow file VB-1042"}'

Node.js Example

const response = await fetch('https://api.verifybitcoin.io/public/verifications', { method: 'POST', headers: { 'X-API-Key': process.env.VERIFYBTC_API_KEY, 'Idempotency-Key': 'escrow-vb-1042-create', 'Content-Type': 'application/json' }, body: JSON.stringify({ bitcoin_address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', amount: 100000, context_note: 'Escrow file VB-1042' }) }); const verification = await response.json(); console.log(verification.id, verification.verification_token);

Python Example

import os import requests response = requests.post( 'https://api.verifybitcoin.io/public/verifications', headers={ 'X-API-Key': os.environ['VERIFYBTC_API_KEY'], 'Idempotency-Key': 'escrow-vb-1042-create', 'Content-Type': 'application/json' }, json={ 'bitcoin_address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'amount': 100000, 'context_note': 'Escrow file VB-1042' } ) verification = response.json() print(verification['id'], verification['verification_token'])

Security Best Practices: Never expose your API key in client-side code. Store it in environment variables and only use it from your server.

Rate Limits

API rate limits are configurable per API key. Default limits apply if not specified.

Response Headers

X-RateLimit-Limit: 100 X-RateLimit-Remaining: 99 X-RateLimit-Reset: 1640995200

When rate limit is exceeded, the API returns a 429 Too Many Requests status code.

API Endpoints

Create Verification

POST
POST /public/verifications

Creates a new Bitcoin signature verification request.

Send an Idempotency-Key header for safe retries. Reusing the same key with the same request returns the original verification. Reusing it with different request data returns a conflict.

Request Body

{ "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "amount": 100000, "customer_email": "client@example.com", "context_note": "Escrow file VB-1042" }

Response (200 OK)

{ "id": "550e8400-e29b-41d4-a716-446655440000", "client_id": "123e4567-e89b-12d3-a456-426614174000", "amount": 100000, "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "challenge_message": "VerifyBTC — Ownership Verification\nBroker: broker@example.com\nContext: Escrow file VB-1042\nVerification ID: 550e8400-e29b-41d4-a716-446655440000\nTimestamp: 2026-06-01T15:00:00Z", "challenge_hash": "6d9678f2d8d7c705e1c1d25ee3f1c6f615b475bbf7f3c9f9f01c5d5f2e8a9123", "broker_context": "Escrow file VB-1042", "signature": null, "verification_token": "7a2f6d7e-3d0d-41e6-b8f5-8a7a95b91c10", "expires_at": "2026-08-30T15:00:00Z", "status": "pending", "created_at": "2026-06-01T15:00:00Z", "updated_at": "2026-06-01T15:00:00Z", "verified_at": null, "signature_method": null, "address_type": "P2PKH", "spending_conditions": "Unrestricted", "spending_conditions_warning": null, "multisig_config": null, "rejection_reason": null, "balance_snapshot": null }

Example with cURL

curl -X POST https://api.verifybitcoin.io/public/verifications \ -H "X-API-Key: btcv_abc123..." \ -H "Content-Type: application/json" \ -d '{ "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "amount": 100000, "customer_email": "client@example.com", "context_note": "Escrow file VB-1042" }'

Multisig Request Body

{ "bitcoin_address": "bc1q5vme3pxfjx0g4cm62688dd90n4etpy5t75h4a28975cry6gaz7lqq8mx8p", "amount": 25000000, "context_note": "Custody account review", "multisig": { "threshold": 2, "total": 3, "pubkeys": [ "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", "02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337" ] } }

List Verifications

GET
GET /public/verifications?page=1&limit=20&status=pending

Retrieves a paginated list of verifications with optional filtering.

Query Parameters

page

(optional) - Page number (default: 1)

limit

(optional) - Results per page (default: 20, max: 100)

status

(optional) - Filter by status (pending, verified, failed, expired, cancelled)

Response (200 OK)

{ "verifications": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "client_id": "123e4567-e89b-12d3-a456-426614174000", "amount": 100000, "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "challenge_message": "VerifyBTC — Ownership Verification...", "challenge_hash": "6d9678f2d8d7c705e1c1d25ee3f1c6f615b475bbf7f3c9f9f01c5d5f2e8a9123", "broker_context": "Escrow file VB-1042", "signature": null, "verification_token": "7a2f6d7e-3d0d-41e6-b8f5-8a7a95b91c10", "expires_at": "2026-08-30T15:00:00Z", "status": "pending", "created_at": "2026-06-01T15:00:00Z", "updated_at": "2026-06-01T15:00:00Z", "verified_at": null, "signature_method": null, "address_type": "P2PKH", "spending_conditions": "Unrestricted", "spending_conditions_warning": null, "multisig_config": null, "rejection_reason": null, "balance_snapshot": null } ], "total": 42, "page": 1, "limit": 20, "has_more": true }

Get Verification

GET
GET /public/verifications/:id

Retrieves details of a specific verification.

Response (200 OK)

{ "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "challenge_message": "VerifyBTC — Ownership Verification\nBroker: broker@example.com\nContext: Escrow file VB-1042\nVerification ID: 550e8400-e29b-41d4-a716-446655440000\nTimestamp: 2026-06-01T15:00:00Z", "amount": 100000, "broker_context": "Escrow file VB-1042", "status": "failed", "created_at": "2026-06-01T15:00:00Z", "expires_at": "2026-08-30T15:00:00Z", "signature_method": "bip322-simple", "address_type": "P2WPKH", "spending_conditions": "Unrestricted", "spending_conditions_warning": null, "multisig_progress": null, "rejection_reason": "Insufficient confirmed balance: 10000 satoshis confirmed, 5000 satoshis unconfirmed (required: 50000)", "balance_snapshot": { "confirmed": 10000, "unconfirmed": 5000, "total": 15000, "required": 50000, "checked_at": "2026-06-01T15:37:13Z" } }

Cancel Verification

DELETE
DELETE /public/verifications/:id

Cancels a pending verification.

Response (200 OK)

{ "id": "550e8400-e29b-41d4-a716-446655440000", "client_id": "123e4567-e89b-12d3-a456-426614174000", "amount": 100000, "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "challenge_message": "VerifyBTC — Ownership Verification...", "challenge_hash": "6d9678f2d8d7c705e1c1d25ee3f1c6f615b475bbf7f3c9f9f01c5d5f2e8a9123", "broker_context": "Escrow file VB-1042", "signature": null, "verification_token": "7a2f6d7e-3d0d-41e6-b8f5-8a7a95b91c10", "expires_at": "2026-08-30T15:00:00Z", "status": "cancelled", "created_at": "2026-06-01T15:00:00Z", "updated_at": "2026-06-01T15:15:00Z", "verified_at": null, "signature_method": null, "address_type": "P2PKH", "spending_conditions": "Unrestricted", "spending_conditions_warning": null, "multisig_config": null, "rejection_reason": null, "balance_snapshot": null }

Get Verification Report

GET
GET /public/verifications/:id/report

Retrieves stored report metadata for a verification owned by this API key. Report metadata is returned only after a report has been generated.

Response (200 OK)

{ "report_url": "https://api.verifybitcoin.io/public/verifications/550e8400-e29b-41d4-a716-446655440000/report/download", "verification_hash": "4b68ab3847feda7d6c62c1fbcbeebfa35eab7351ed5e78f4ddadea5df64b8015" }

Download Verification Report

GET
GET /public/verifications/:id/report/download

Downloads the stored PDF report for a verification owned by this API key. The bucket stays private; the API authorizes the request and streams the PDF.

curl -L https://api.verifybitcoin.io/public/verifications/550e8400-e29b-41d4-a716-446655440000/report/download \ -H "X-API-Key: btcv_abc123..." \ -o verifybtc-report.pdf

Validate BIP-127 Reserve Proof

POST
POST /public/proof-of-reserves/validate

Validates a BIP-127 commitment message and proof transaction package. In test mode the backend expects testnet network magic; otherwise it validates production reserve packages.

curl -X POST https://api.verifybitcoin.io/public/proof-of-reserves/validate \ -H "X-API-Key: btcv_abc123..." \ -H "Content-Type: application/json" \ -d '{ "commitment_message": "VerifyBTC reserves 2026-06-01", "proof_transaction_hex": "0200000002...", "network_magic": 3652501241 }'{ "valid": true, "standard": "BIP-127", "network": "mainnet", "network_magic": "0xD9B4BEF9", "commitment_hash": "30896246cd560f641d84e2ddcd9ee0f8fd74e4547be75aa7d6464f75dd372dff", "proven_input_count": 12, "output_count": 1, "summary": "Valid BIP-127 mainnet proof with 12 proven reserve inputs." }

Error Responses

All errors return a JSON response with an error message and appropriate HTTP status code.

Error Response Format

{ "error": "Invalid API key", "code": "AUTH_ERROR" }

Common Error Codes

400

Bad Request - Invalid parameters

401

Unauthorized - Invalid API key

404

Not Found - Resource not found or not owned by this API key

429

Too Many Requests - Rate limit exceeded

500

Internal Server Error - Server error

OpenAPI Specification

Download the OpenAPI 3.0 specification to generate client SDKs in your preferred programming language, import into API testing tools like Postman, or integrate with other development workflows.

Interactive Documentation

Explore the API interactively with Swagger UI:

https://api.verifybitcoin.io/api-docs

Ready to Get Started?

Start verifying Bitcoin ownership in minutes. Create a free account and get your API key — no credit card required.

Questions? Email us at support@verifybtc.com

Need Help?

If you have questions or need assistance integrating the VerifyBTC API, please contact our support team or check out additional resources: