Notifications

Notifications allow you to subscribe to updates for your OAuth application or API key. Notifications are sent as HTTP POST requests (webhooks) to a notification endpoint which you can set in your OAuth application or API key settings.

Once you have configured your notification endpoint you’ll receive notifications instantly as events are created for your account. You might use notifications to:

  • Get notified when your buy or sell is completed
  • Monitor payments and mispayments for your orders
  • Initiate actions when your bitcoin or ethereum addresses receive new transactions

See full list of notifications and corresponding payload information

New notification types will be added over time. If your application would benefit from a specific notification, please let us know by emailing us or posting in Coinbase Community.

Setting up notifications

API key

You can set up a notification endpoint for your API Key in your API key settings. These notifications affect only your own account and you need to remember to set up necessary read permissions to receive notifications. A full list is available in the API reference.

Coinbase Connect (OAuth2)

Coinbase Connect applications can also subscribe to notifications. Unlike API keys, notifications for Coinbase Connect applications are initialized for application users who have an active access token. The same restrictions apply, so you’ll need to have the necessary read permissions, and notifications will only be fired for accounts (wallets) for which the application has permissions.

As notifications from multiple users of your applications are posted to a single notification endpoint, you’ll need to use user and account fields to map them to specific users of your application.

Merchant settings

For merchant integrations, you can subscribe to a limited number of merchant related notifications from your Merchant Settings.

Read more about Merchant Notifications

Accessing Notifications API

Notifications are stored for future access via the API. Querying them via the API can be useful if you need to access notifications at a later date or when you’re testing your implementation.

Read more about Notifications API

Notification Retry Schedule

When posting notifications, Coinbase expects to receive a 200 response code from your website. If the response code is not 200, we will retry the notification hourly for up to three days.

This ensures that if your site experiences downtime or there is a problem with your integration, updates will not be lost. Most of the time your website will respond on the very first callback so subsequent callbacks will never need to be run.

You can always access notifications via our API using the list notifications endpoint.

Versioning

As notifications are delivered via webhooks, they don’t have access to CB-VERSION header which is used to define the version for API requests. Instead a version defined in user’s API settings is used. Before upgrading your service, ensure that your application is ready to accept the latest notification version.

Testing notifications

Since notifications must always be available in a publicly accessible URL, you might run into issues while starting to build your application in a local environment. The easiest way to get started testing notifications is to use a tool like RequestBin. Once you have created a temporary webhook, you can set it to your application settings. It’s important to use this only for development, as you should never leak notification data to public.

Securing Callbacks

Order callbacks originating from Coinbase will be signed using our merchant callback signing RSA private key. The corresponding public key for verification can be downloaded here.

If you are using the latest version of an official Coinbase API library, check your library’s documentation for verifying merchant callbacks.

If you would like to verify callbacks manually in the language of your choice, the message digest used is SHA256, the message that is signed is the POST body, the padding scheme is PKCS1_v1_5, and the signature to be verified is present in the ‘CB-SIGNATURE’ HTTP Header encoded as base64.

For example, here is the callback verification code from our official Ruby API library:

CALLBACK_DIGEST = OpenSSL::Digest.new("SHA256")
def self.verify_callback(body, signature)
  return false unless callback_signing_public_key
  callback_signing_public_key.verify(CALLBACK_DIGEST, signature.unpack("m0")[0], body)
rescue OpenSSL::PKey::RSAError, ArgumentError
  false
end

def self.callback_signing_public_key
  @@callback_signing_public_key ||= nil
  return @@callback_signing_public_key if @@callback_signing_public_key
  path = File.expand_path(File.join(File.dirname(__FILE__), 'coinbase-callback.pub'))
  @@callback_signing_public_key = OpenSSL::PKey::RSA.new(File.read(path))
end

To assist you in testing, the following is an example POST body with associated valid signature:

  body = '{"order":{"id":null,"created_at":null,"status":"completed","event":null,"total_btc":{"cents":100000000,"currency_iso":"BTC"},"total_native":{"cents":1000,"currency_iso":"USD"},"total_payout":{"cents":1000,"currency_iso":"USD"},"custom":"123456789","receive_address":"mzVoQenSY6RTBgBUcpSBTBAvUMNgGWxgJn","button":{"type":"buy_now","name":"Test Item","description":null,"id":null},"transaction":{"id":"53bdfe4d091c0d74a7000003","hash":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b","confirmations":0}}}'

  signature = "6yQRl17CNj5YSHSpF+tLjb0vVsNVEv021Tyy1bTVEQ69SWlmhwmJYuMc7jiDyeW9TLy4vRqSh4g4YEyN8eoQIM57pMoNw6Lw6Oudubqwp+E3cKtLFxW0l18db3Z/vhxn5BScAutHWwT/XrmkCNaHyCsvOOGMekwrNO7mxX9QIx21FBaEejJeviSYrF8bG6MbmFEs2VGKSybf9YrElR8BxxNe/uNfCXN3P5tO8MgR5wlL3Kr4yq8e6i4WWJgD08IVTnrSnoZR6v8JkPA+fn7I0M6cy0Xzw3BRMJAvdQB97wkobu97gFqJFKsOH2u/JR1S/UNP26vL0mzuAVuKAUwlRn0SUhWEAgcM3X0UCtWLYfCIb5QqrSHwlp7lwOkVnFt329Mrpjy+jAfYYSRqzIsw4ZsRRVauy/v3CvmjPI9sUKiJ5l1FSgkpK2lkjhFgKB3WaYZWy9ZfIAI9bDyG8vSTT7IDurlUhyTweDqVNlYUsO6jaUa4KmSpg1o9eIeHxm0XBQ2c0Lv/T39KNc/VOAi1LBfPiQYMXD1e/8VuPPBTDGgzOMD3i334ppSr36+8YtApAn3D36Hr9jqAfFrugM7uPecjCGuleWsHFyNnJErT0/amIt24Nh1GoiESEq42o7Co4wZieKZ+/yeAlIUErJzK41ACVGmTnGoDUwEBXxADOdA="

Your callback url should also use the https protocol for greater security. This allows us to ensure we are sending callbacks to the correct server and prevents any parameters from being read as they travel over the internet. Additionally, the merchant should reject all callbacks that do not originate from Coinbase’s network:

54.175.255.192/27

Previous versions of this documentation recommended adding a secret query parameter to your callback url. This method is no longer supported and all clients should verify the cryptographic signature as described above instead.

Confirmations

Bitcoin transactions arrive usually within a few seconds, but can take anywhere from 10 minutes to 1 hour to become 100% confirmed in the blockchain (bitcoin’s public ledger system). While this potential delay may seem challenging, Coinbase has several measures in place to eliminate the effect on merchants.

When Coinbase sends an order callback with a status of wallet:orders:paid, and you have instant-exchange enabled, it is safe to assume at this point that the payout is guaranteed by Coinbase. Even if the associated payment transaction does not confirm, Coinbase will always payout an order after sending a wallet:orders:paid notification.

Typically, Coinbase sends the notification within 1-2 seconds of the bitcoin transaction arriving. If we feel the transaction is at a higher risk for being double spent, we may delay sending the callback until we can be sure the transaction will be confirmed.