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
Real-time notifications
Base URL
https://api.verifybitcoin.ioAll 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.
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: 1640995200When rate limit is exceeded, the API returns a 429 Too Many Requests status code.
API Endpoints
Create Verification
POSTPOST /public/verificationsCreates 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
GETGET /public/verifications?page=1&limit=20&status=pendingRetrieves 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
GETGET /public/verifications/:idRetrieves 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
DELETEDELETE /public/verifications/:idCancels 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
GETGET /public/verifications/:id/reportRetrieves 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
GETGET /public/verifications/:id/report/downloadDownloads 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.pdfValidate BIP-127 Reserve Proof
POSTPOST /public/proof-of-reserves/validateValidates 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
Bad Request - Invalid parameters
Unauthorized - Invalid API key
Not Found - Resource not found or not owned by this API key
Too Many Requests - Rate limit exceeded
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.
OpenAPI 3.0 JSON
Machine-readable API specification
Download Spec
Interactive Documentation
Explore the API interactively with Swagger UI:
https://api.verifybitcoin.io/api-docsNeed Help?
If you have questions or need assistance integrating the VerifyBTC API, please contact our support team or check out additional resources: