API Documentation

Getting Started

This documentation is meant to be an overview of all the capabilities of the BTC.com Wallet API/SDK and Webhooks.
For all Data API related docs please refer to: https://btc.com/api-doc

We currently provide SDK Libraries for PHP and (Node)JS.

If you need any help with your implementation or you have suggestions/requests for features and changes, feel free to contact us at support@btc.com.

Bitcoin Values

The BTC.com API returns all Bitcoin values in Satoshi!

Bitcoin supports 8 decimals and the smallest possible value of 0.00000001 BTC is called 1 Satoshi (named after the creator of Bitcoin).

Integers & Floats

It's best practice to always do financial (and thus also Bitcoin) values in integers instead of floats in programming.Our API returns all values in Satoshi and also expects Satoshi as input.We also strongly recommend that you follow this best practice on your end and only convert from Satoshi to Bitcoin when outputting the value for display.

Floats are Evil!

Be very careful when converting Floats to Integers and Integers to Floats! In a lot of programming languages you can get very weird rounding errors! Check out how our SDK handles it or search what the best practice for your language is!

Conversion helpers

To make your life easy you can use the helpers in the SDK (see the example),when you're working (or communicating) with the Bitcoin value.If you're not using the SDK then defining a constant or variable yourself with the value of 100000000 to divide/multiply by,but make sure to check how to deal with floats in your language of choice!

var blocktrail = require('blocktrail-sdk');

console.log("123456789 Satoshi to BTC: ",
            blocktrail.toBTC(123456789));
console.log("1.23456789 BTC to Satoshi: ",
            blocktrail.toSatoshi(1.23456789));

Network & TestNet

The 'network' you operate on is determined by the 'network' argument when you init the SDK.

  • BTC for Bitcoin
  • tBTC for Bitcoin TestNet
  • BCH for Bitcoin Cash
  • tBCH for Bitcoin Cash TestNet

TestNet

There is an alternative network to use for bitcoin called TestNet which allows you to easily test bitcoin without actual value involved (read more).

We urge you to use TestNet while building and testing your application to avoid waisting real Bitcoin!
We consider our testnet infrastructure equally important as our mainnet infrastructure and it's treated with the same care and urgency.

Rate Limits

Developer accounts are limited to 432,000 API requests per 24 hours, at a rate of 300 request per minute.

When you reach the rate limit you will get an error response with the 429 status code. We will send you a notification when you're getting close to the rate limit, so you can upgrade in time or contact us to request an extension.

If you don't backoff when 429 responses are being returned you can get banned.

SDK Manual

We currently provide SDK Libraries for PHP and NodeJS.

Bitcoin Transactions Made Easy

To use the Payments API there's more complex logic involved than just calling the API method, such as encrypting and decrypting your private key, creating and signing transactions, etc.

Our SDK makes all this very easy so that you don't have to become a bitcoin-wizard just to be able to send a Bitcoin transaction.

Installation

Our SDKs are available through the commonly used package manager for their particular language. You can also find the source code on github!

Packages

Packagist version NPM version

Source

BlockTrail PHP SDK BlockTrail NodeJS SDK

$ npm install blocktrail-sdk 3.*

Initializing the SDK

You should initialise the API Client SDK with your API_KEY and API_SECRET. The API_SECRET will be used to sign requests as an extra security measure.

TestNet

For testing we strongly recommend that you set the SDK to work with TestNet instead of the main bitcoin network. That way you can play around without using your precious Bitcoin or excidently sending them to a wrong address.

blocktrail = require('blocktrail-sdk');
client = blocktrail.BlocktrailSDK({apiKey: "MY_APIKEY", apiSecret: "MY_APISECRET", network: "BTC", testnet: false});

client.address('1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T',
    function(err, address) { console.log(address.balance); });
client.blockLatest(
    function(err, block) { console.log(block.hash); });

Using The Payments API SDK

We urge you to use TestNet while building and testing your application to avoid transaction costs and errors with real Bitcoin!

Multi-Signature Hierarchical Deterministic (HD) Wallet

The BTC.com Payment API is built using Multi-Signature HD Wallets, this means that there are 3 keys in total, 2 of which are necessary to get access to your Bitcoin!

  • Primary Key: The SDK generates a strong random Private Key for you and encrypts it with your passphrase before storing it on the BTC.com server. Whenever you (re)initialise the wallet you will receive the encrypted Prviate Key from the API and on your end the SDK decrypts it with your passphrase to get the actual Private Key.
  • Backup Key: The SDK helps you generate another strong random Private Key and you should store this securely (offline preferably). You shouldn't need to use this key unless something 'bad' happens, but if it's every neccesary this will help you get your Bitcoin wihout requiring the BTC.com API. For the Backup Key there's no passphrase used, that way if you ever loose the passphrase the backup key will allow you to recover your Bitcoin!
  • BTC.com Key: This key is used to 'co-sign' your transactions to add an extra layer of security. This is the only key BTC.com has access to and this one key is never enough to access your Bitcoin.

Creating a Wallet

To be able to send and receive Bitcoin you need to create a wallet with a unique identifier and a passphrase. The SDK will return you a wallet object - which you can interact with. And it will return the information you need to backup to be able to access you wallet at all times!

The Backup Key

You should store the backup key somewhere safe (offline or at least somewhere outside of your application). This backup key can be used to get access to your Bitcoin if you've lost your primary key or passphrase, or it can be used in case you want to access your Bitcoin without the help of BTC.com.

It's very important that you store the backup key when creating the wallet!
Neither you nor BTC.com can recover the backup key when lost (or not stored)!
Bitcoin is a decentralised system, there is nobody who can help you recover your Bitcoin if you don't have your backup key!

Extra Backup Information

If it's ever neccesary to get your Bitcoin without requiring the BTC.com API you can do this with the combination of your Primary Key and your Backup Key. Besides the Backup Key that you should store somewhere securely, you will need some more information that is normally provided by the BTC.com API such as your encrypted Primary Key and the BTC.com Public Key. When you create your wallet this information is provided and we advise you to store it together with your Backup Key. Your passphrase is still required before anyone can use your Primary Key so as long as you don't add the passphrase to the backup, someone stealing this backup from you will still have to crack your password!

When you create your wallet you only have 1 chance to store the Backup Key! If you failed to do so, you should delete the wallet and create a new one!

The rest of the backup information can still get from the BTC.com API or from the BTC.com dashboard at a later stage.

client.createNewWallet("mywallet", "mypass",
    function(err, wallet, backupInfo) {});

Initialise Existing Wallet

After you've created the wallet, you can (re)initialise the wallet object at any time using the unique identifier and passphrase. You will receive the encrypted primary key from the BTC.com API and the SDK will decrypt the key on your side.

client.initWallet("mywallet", "mypass",
    function(err, wallet) {});

Receiving Transactions

To start receiving transactions with a wallet you need to create an address where the Bitcoin is sent to.

It's best practice to generate a new address for every transaction, this will increase the anonymity / privacy of your wallet.

Addresses are generated using the Hierarchical Deterministic (HD) Wallet which means you can generate as many addresses as you'd like with just 1 key and never need to backup more keys than the ones initially generated when creating the wallet!

The Hierarchical Deterministic Wallet is a bitcoin standard of which the spec. can be found here: BIP32

wallet.getNewAddress(function(err, address) {});

Wallet Balance

See the next section about Wallet Webhooks on how to be notified automatically when you receive a transaction on one of your addresses.

Once a transaction has been made to one of your addresses you can check the balance of your wallet.

Incoming transactions need to be confirmed by the bitcoin blockchain before you can spend them safely. Confirmations take an average of 10 minutes (when a new block is mined). You can check the unconfirmed balance to see how much Bitcoin is pending confirmation.

All Bitcoin values are in Satoshi (integers)

All Bitcoin values are in Satoshi, read more about this in the API Reference - Coin Values section.

wallet.getBalance(
    function(err, confirmedBalance, unconfirmedBalance) {
        console.log('Balance: ', blocktrail.toBTC(confirmedBalance));
        console.log('Unconfirmed Balance: ', blocktrail.toBTC(unconfirmedBalance));
    }
);

Wallet Webhook

You can setup a Webhook URL that we call every time a transaction is made to one of your addresses.
This will work exactly like the normal BTC.com API webhooks, except that we will subscribe your webhook automatically to each address you create for your wallet.

wallet.setupWebhook('https://user:pass@example.com/');

Wallet Webhook Data

The data POSTed to your webhook will also contain additional data if it's a webhook created specifically for a wallet. It will list all the addresses from your wallet involved in the transaction and the netto balance change for you wallet as a result of the transaction.

{
    "network" : "BTC",
    "data" : {
        "hash": "8fa29a1db30aceed2ec5afb2bcdf6196207975780b4ca5f3f1d6313cab855fe7",
        "time": "2014-08-25T09:29:28+0000",
        "confirmations": 3948,

        "...etc..." : "...etc..."
    },
    "wallet" : {
        "addresses" : [
            "1qMBuZnrmGoAc2MWyTnSgoLuWReDHNYyF"
        ],
        "balance" : -347328
    },
    "addresses": {
        "1qMBuZnrmGoAc2MWyTnSgoLuWReDHNYyF": −347328,
        "1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T": 347328,
    }
}

Security

To avoid someone other than the BTC.com API submitting data to your Webhook URL by simply guessing the URL you should add a secret token or HTTP Basic Authentication to the Webhook URL.

Of course it's also advised to use SSL for your Webhook URLs!

https://basic-auth-user:basic-auth-pass@your-server.com/webhook-events
https://your-server.com/webhook-events?secret=RANDOM_SECRET

Sending Transactions

Sending a transaction is just a single line of code, specifying the receiving address(es) and the amount to send. The SDK handles all the logic of creating the transaction, signing it with your primary key and sending it to the API so BTC.com can co-sign the transaction and send it to the bitcoin network.

All Bitcoin values should be in Satoshi (integers)

All Bitcoin values should be in Satoshi, read more about this in the API Reference - Coin Values section.

value = blocktrail.toSatoshi(1.1);
wallet.pay({'1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T': value},
    function(err, result) {});

Fee Strategy

As of v1.3.x of our SDKs the default behaviour is to use dynamic fees to get the optimal fee to end up in the next block. To use the old behaviour of using a fixed 0.0001 BTC / Kb you should specify the 'feeStrategy' as BASE_FEE

value = blocktrail.toSatoshi(1.1);
wallet.pay({'1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T': value}, null, false, true, blocktrail.Wallet.FEE_STRATEGY_BASE_FEE,
    function(err, result) {});
wallet.pay({'1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T': value}, null, false, true, blocktrail.Wallet.FEE_STRATEGY_LOW_PRIORITY,
    function(err, result) {});

Listing Transaction History

You can list all the incoming and outgoing transactions for your wallet.

wallet.transactions(function(err, result) {});
{
    "data": [
        {
            "hash": "fb8c164a42e527543cbdb40dc28d561b24b50f8c1f1fc65cc1696c42a078f688",
            "time": "1421250896",
            "block_height": "318331",
            "addresses": [
                "2N1DiuwM3jmmmsxD7Jzwgqotrg2dujbUGyi",
                "2NCsE3WYwNZSxAi7CjVuRNCSRmCCMrSkHDw",
                "2N1qzaMa6enNkvjKQRMeysuUNdcogcaKTYY"
            ],
            "fee": "10000",
            "wallet_value_change": "-10000"
        },
        { /* ... */ }
    ],
    "current_page": 1,
    "per_page": 20,
    "total": 69
}

Using the Webhooks API SDK

Webhooks help you keep up with everything happening on the bitcoin blockchain in real-time, without the need of running your own node.

You simply set up a URL which we will POST some data to when an event happens.

Set up a Webhook URL

When you set up a Webhook URL to our API you can also add a unique identifier to it. If one is not provided we will generate one for you. You will need to use this unique ID to subscribe to the events which you want to receive; this way you can easily update the URL of the Webhook or delete all the events for that Webhook with 1 API call.

client.setupWebhook('https://user:pass@example.com/',
    function(err, result) {/*...*/});
client.setupWebhook('https://user:pass@example.com/', 'my-webhook-id',
    function(err, result) {/*...*/});

Subscribe to Events

You can subscribe to events that you want to receive data for. Possible events are:

  • block: when a new block is found
  • address-transactions: when an address receives a new transaction

Address Transactions and Confirmations

When subscribing to Address transaction events you can specify how many 'confirmations' you want to receive (between 1 and 10). We will send you the first event when an unconfirmed transaction comes in and then repeat that event every time it gets another confirmation up to your configured 'confirmations'.

client.subscribeAddressTransactions('my-webhook-id',
    '1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp', 6, function(err, result) {/*...*/});
client.subscribeNewBlocks('my-webhook-id', function(err, result) {/*...*/});

Receiving Events

When an event happens on the blockchain we will send a POST request to your Webhook URL with the data as JSON string.

Apart from the 'raw' data we'll also include some metadata that can make your life easier.

For the address-transactions we include a list of addresses that are part of the transaction and that you're subscribed to And their netto balance change as a result of the transaction.

Receiving the JSON data in PHP

A small side note for PHP users
in PHP versions lower than PHP 5.6 you can only read from php://input once
so if you have a framework/CMS than you need to check if it doesn't already read it before you and if it does you need to get it from the framework instead of directly from php://input

{
    "network" : "BTC",
    "data" : {
        "hash": "8fa29a1db30aceed2ec5afb2bcdf6196207975780b4ca5f3f1d6313cab855fe7",
        "time": "2014-08-25T09:29:28+0000",
        "confirmations": 3948,

        "...etc..." : "...etc..."
    },
    "addresses": {
        "1qMBuZnrmGoAc2MWyTnSgoLuWReDHNYyF": −2501000
    }
}

Manage the Webhook and the Events

You can list, update, and delete your Webhook URLs and their Events. Check out the API Reference for the details.

client.webhookEvents('my-webhook-id', function(err, result) {/*...*/});

Security

To avoid someone other than the BTC.com API submitting data to your Webhook URL by simply guessing the URL you should add a secret token or HTTP Basic Authentication to the Webhook URL.

Of course it's also advised to use SSL for your Webhook URLs!

https://basic-auth-user:basic-auth-pass@your-server.com/webhook-events
https://your-server.com/webhook-events?secret=RANDOM_SECRET

API Reference

Authentication

TODO

Date Format

The BTC.com API returns date/time fields as strings following the ISO 8601 format, which can be natively parsed by all languages into their respective native Date object.

'2009-01-03T07:15:05+0000'

Errors

The BTC.com API returns standard HTTP response codes and a message containing more details about the error.

  • 200: Everything worked as expected
  • 400: Bad Request - Happens when you're missing a required parameter.
  • 401: Invalid Credentials - Either the API_KEY is not correct or the HTTP-Signature auth failed
  • 403: Permission Denied - You don't have the necessary permissions to carry out the request
  • 404: Missing Endpoint or Object Not Found
  • 429: Too Many Requests - The number of requests in the last 60 seconds were too many
  • 50*: Server Error - Something went wrong on the BTC.com side of the request

In case of an error the body of the response will be in the requested format and contain an error 'code' and 'msg'.

Errors in the SDK

The SDKs will parse the error and follow the 'normal' behaviour for a language in handling errors. In most cases this will be throwing an Exception, except for nodeJS where the first argument of a callback is always the error.

client.address('1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T', function(err, address) {
    if (err) {
        console.log(err);
        return;
    }
});

Webhooks API

Set up a Webhook URL

Will set up a Webhook URL to be used to subscribe events on.

POST method

Requires HTTP-Signature Authentication.

Arguments

url (string) The URL to receive the webhook events.
identifier (string) (optional) A unique identifier used for this webhook.

Return Value

url (string) The URL to receive the webhook events, will match the provided URL.
identifier (string) A unique identifier used for this webhook, either the provided id or a randomly generated one.
client.setupWebhook('https://user:pass@example.com/',
    function(err, result) {/*...*/});
client.setupWebhook('https://user:pass@example.com/', 'my-webhook-id',
    function(err, result) {/*...*/});
{
    "url": "https://user:pass@example.com/",
    "identifier": "my-webhook-id"
}

{
    "url": "https://user:pass@example.com/",
    "identifier": "random-new-id"
}

List All Webhooks

Will retrieve a paginated list of all webhooks created by the API user.

Arguments

page (integer) (optional) The pagination page to retrieve
limit (integer) (optional) the number of records to retrieve per page (default 20, max 200)

Return Value

data (array) An array of the paginated records, with the following properties:
identifier (string) A unique identifier used for this webhook.
url (string) The URL receiving the webhook events.
current_page (integer) pagination: current page of records
per_page (integer) pagination: the number of records being returned per page
total (integer) pagination: the total number of records found
client.allWebhooks(page, limit, function(err, result) {/*...*/});
{
    "data": [
        {
            "identifier": "my-webhook-id-1",
            "url" : "https://user:pass@example.com/"
        },
        {
            "identifier": "my-webhook-id-2",
            "url" : "https://user:pass@example.com/"
        }
        { /* ... */ }
    ],
    "current_page": 1,
    "per_page": 20,
    "total": 14
}

Get Existing Webhook

Will get an existing Webhook by the identifier given

GET method

Arguments

identifier (string) The unique identifier of the webhook to retrieve.

Return Value

identifier (string) A unique identifier used for this webhook.
url (string) The URL receiving the webhook events.
client.getWebhook('my-webhook-id', function(err, result) {/*...*/});
{
    "identifier": "my-webhook-id",
    "url" : "https://user:pass@example.com/"
}

Update an existing Webhook URL

Will update an existing Webhook's identifier or URL.

PUT method

Requires HTTP-Signature Authentication.

Arguments

identifier (string) The unique identifier of the webhook to update.
webhookData (object) An object containing the new identifier and/or the new url for the webhook.

Return Value

identifier (string) The updated identifier for this webhook.
url (string) The updated URL for receiving the webhook events.
var webhookData = {
    identifier:'new-webhook-id',
    url:'https://user:pass@example.com/new-url'
};
client.updateWebhook('my-webhook-id', webhookData,
    function(err, result) {/*...*/});
{
    "identifier": "my-updated-webhook-id",
    "url" : "https://user:pass@example.com/updated-url"
}

Delete a Webhook and all it's Events

Will delete a webhook and all the events the webhook is subscribed to.

DELETE method

Arguments

identifier (string) The unique identifier of the webhook to delete.

Return Value

result (boolean) Success!
client.deleteWebhook('my-webhook-id', function(err, result) {/*...*/});

Create Webhook Event

Will subscribe a Webhook URL to an event.

POST method

Requires HTTP-Signature Authentication.

Arguments

identifier (string) The unique identifier used for this webhook.

POST Data

event_type (string) The event type to subscribe to.Can be address-transactions or block
address (string) (address-transactions only). A bitcoin address hash.
confirmations (string) (address-transactions only)(default 6, max 10). The amount of times you want to receive data about each transaction when it gets +1 confirmation

Return Value

event_type (string) The type of event subscription (address-transactions or block)
address (string) (address-transactions only). The bitcoin address hash.
confirmations (integer) (address-transactions only). The amount of confirmations to send.
client.subscribeAddressTransactions('my-webhook-id',
    '1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp', 6, function(err, result) {/*...*/});
client.subscribeNewBlocks('my-webhook-id', function(err, result) {/*...*/});
{
    "event_type": "block",
    "address" : null,
    "confirmations" : null
}


{
    "event_type": "address-transactions",
    "address": "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp",
    "confirmations": 6
}

Batch Create Webhook Event

Will subscribe a Webhook URL to a batch of event.

POST method

Requires HTTP-Signature Authentication.

Arguments

identifier (string) The unique identifier used for this webhook.

POST Data

A list / array of event data:

event_type (string) The event type to subscribe to.Can be only be address-transactions
address (string) A bitcoin address hash.
confirmations (string) (default 6, max 10) The amount of times you want to receive data about each transaction when it gets +1 confirmation

Return Value

event_type (string) The type of event subscription (address-transactions or block)
address (string) (address-transactions only). The bitcoin address hash.
confirmations (integer) (address-transactions only). The amount of confirmations to send.
client.batchSubscribeAddressTransactions(
    'my-webhook-id',
    [
        {"address": "1NcXPMRaanz43b1kokpPuYDdk6GGDvxT2T", "confirmations": 6},
        {"address": "1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp"},
    ],
    function(err, result) {/*...*/});

List Webhook Events

Will retrieve a paginated list of all events the webhook is subscribed to.

Arguments

identifier (string) A unique identifier used for this webhook.
page (integer) (optional) The pagination page to retrieve
limit (integer) (optional) the number of records to retrieve per page (default 20, max 200)

Return Value

data (array) An array of the paginated records, with the following properties:
event_type (string) The type of event subscribed to (address-transactions or block)
address (string) (address-transactions only)
The bitcoin address hash.
confirmations (integer) (address-transactions only)
The amount of confirmations to send.
current_page (integer) pagination: current page of records
per_page (integer) pagination: the number of records being returned per page
total (integer) pagination: the total number of records found
client.allWebhooks(page, limit, function(err, result) {/*...*/});
{
    "data": [
        {
            "identifier": "my-webhook-id-1",
            "url" : "https://user:pass@example.com/"
        },
        {
            "identifier": "my-webhook-id-2",
            "url" : "https://user:pass@example.com/"
        }
        { /* ... */ }
    ],
    "current_page": 1,
    "per_page": 20,
    "total": 14
}

Delete Webhook Event

Will unsubscribe a Webhook URL from an event.

DELETE method

Requires HTTP-Signature Authentication.

Arguments

identifier (string) The unique identifier used for this webhook.
event_type (string) The event type to subscribe to. Can be address-transactions or block
address (string) (address-transactions only). A bitcoin address hash.

Return Value

result (boolean) Success!
client.unsubscribeAddressTransactions('my-webhook-id', '1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp',
    function(err, result) {/*...*/});
client.unsubscribeNewBlocks('my-webhook-id', function(err, result) {/*...*/});

Market API

Price Index

Will retrieve the current price index.Price Index based on CoinDesk Price Index.

Return Value

USD (float) The current USD price
client.price(function(err, price) {});
{
    "USD": 287.30
}