NAV
shell python javascript ruby

Overview

This is the reference documentation for all Button APIs. Some of these APIs may be subject to change, in particular the following APIs are currently still under development and may change without notice:

Client Libraries

We’ve developed client libraries for node.js, Python, and Ruby to simplify integrating. Consider using one if you are on a supported stack. If not, let us know! We may be able to support your runtime.

Installation

pip install pybutton
npm install @button/button-client-node
gem install button

Our client libraries can be installed with your language’s standard package manager. Use the toggles in the upper-right to select your preferred language.

Initialization

from pybutton import Client

client = Client('sk-XXX')
var client = require('@button/button-client-node')('sk-XXX');
require 'button'

client = Button::Client.new('sk-XXX')

A client is instantiated with your Organization’s API Key, sk-xxx in these examples.

Options

from pybutton import Client

client = Client("sk-XXX", {
  'hostname': 'api.testsite.com',
  'port': 80,
  'secure': False,
  'timeout': 5, # seconds
})
var client = require('@button/button-client-node')('sk-XXX', {
  hostname: 'api.testsite.com',
  port: 80,
  secure: false,
  timeout: 3000 // 3 seconds
});
require 'button'

client = Button::Client.new('sk-XXX', {
  hostname: 'api.testsite.com',
  port: 3000,
  secure: false,
  timeout: 5 # seconds
})

The client instance can be configured with the following options:

Protocol

Request Format

Request

from pybutton import Client

client = Client('sk-XXX')

response = client.orders.create({
    'total': 50,
    'currency': 'USD',
    'order_id': '2007',
    'finalization_date': '2017-08-02T19:26:08Z',
    'btn_ref': 'srctok-XXX',
    'customer': {
        'id': 'mycustomer-1234',
        'email_sha256': hashlib.sha256("user@example.com".lower().strip()).hexdigest(),
    },
})

var client = require('@button/button-client-node')('sk-XXX');

client.orders.create({
  total: 50,
  currency: 'USD',
  order_id: '1989',
  finalization_date: '2017-08-02T19:26:08Z',
  btn_ref: 'srctok-XXX',
  customer: {
    id: 'mycustomer-1234',
    email_sha256: crypto.createHash('sha256').update('user@example.com'.toLowerCase().trim()).digest('hex')
  }
}, function(err, res) {
    // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.orders.create({
  total: 50,
  currency: 'USD',
  order_id: '1994',
  finalization_date: '2017-08-02T19:26:08Z',
  btn_ref: 'srctok-XXX',
  customer: {
    id: 'mycustomer-1234',
    email_sha256: Digest::SHA256.hexdigest('user@example.com'.downcase.strip)
  }
})

curl https://api.usebutton.com/v1/order \
  -X POST \
  -u your_api_key: \
  -H "Content-Type: application/json" \
  -d '{
    "total": 50,
    "currency": "USD",
    "order_id": "1994",
    "finalization_date": "2017-08-02T19:26:08Z",
    "btn_ref": "srctok-XXX",
    "customer": {
      "id": "mycustomer-1234",
      "email_sha256": "'`echo -n "user@example.com" | openssl dgst -sha256`'"
    }
  }'

The Button API is designed around REST. Request parameters must be given as JSON-encoded request body.

The only unusual request parameter is api_key (access it on your Button dashboard) which is sent as a basic authentication username.

Authentication

Button uses your API key for API endpoint access. Additionally, certain endpoints are available through the SDK with a user session.

For requests that require an API key, Button expects the API key via Basic Auth.

The Authorization header field is constructed as follows:

  1. Add a colon to the end of the api key (e.g. apiKey + ":")
  2. Base64 encode the resulting string
  3. The authorization method and a space i.e. “Basic ” is then put before the encoded string. (e.g. "Basic " + base64Encode(apiKey + ":"))

Response Format

Success (single)

{
    "meta": {
        "status": "ok"
    },
    "object": {
        "id": "f00b4r",
        "active": true
    }
}

Error

{
    "meta": {
        "status": "error"
    },
    "error": {
        "message": "Missing merchant approval",
        "type": "MissingApproval",
        "details": {
          "merchant_id": "org-XXX"
        }
    }
}

Responses are delivered in JSON, and may have the following fields:

Error Handling

The service uses standard HTTP response code conventions to indicate success or failure:

Orders

Orders are objects used to represent a user purchase in a commerce application. It is preferable to report all orders to the Button API, regardless of whether you have a known Button btn_ref to enable seamless investigation and support in cases of Loyalty & Rewards publishers.

Order Statuses

open: An order can be modified or deleted by the Merchant.

finalized: Order’s adjustment period has ended and no more changes can be made.

deleted: Order is deleted.

POST /v1/order

Request

import hashlib
from pybutton import Client

client = Client('sk-XXX')

hashed_email = hashlib.sha256('user@example.com'.lower().strip()).hexdigest()

response = client.orders.create({
    'total': 50,
    'currency': 'USD',
    'order_id': '2007',
    'finalization_date': '2017-08-02T19:26:08Z',
    'btn_ref': 'srctok-XXX',
    'customer': {
        'id': 'mycustomer-1234',
        'email_sha256': hashed_email,
    },
})

var crypto = require('crypto');
var client = require('@button/button-client-node')('sk-XXX');

var hashedEmail = crypto.createHash('sha256')
  .update('user@example.com'.toLowerCase().trim())
  .digest('hex');

client.orders.create({
  total: 50,
  currency: 'USD',
  order_id: '1989',
  finalization_date: '2017-08-02T19:26:08Z',
  btn_ref: 'srctok-XXX',
  customer: {
    id: 'mycustomer-1234',
    email_sha256: hashedEmail
  }
}, function(err, res) {
    // ...
});
require 'digest'
require 'button'

client = Button::Client.new('sk-XXX')

hashed_email = Digest::SHA256.hexdigest('user@example.com'.downcase.strip)

response = client.orders.create({
  total: 50,
  currency: 'USD',
  order_id: '1994',
  finalization_date: '2017-08-02T19:26:08Z',
  btn_ref: 'srctok-XXX',
  customer: {
    id: 'mycustomer-1234',
    email_sha256: hashed_email
  }
})

curl https://api.usebutton.com/v1/order \
  -X POST \
  -u your_api_key: \
  -H "Content-Type: application/json" \
  -d '{
    "total": 50,
    "currency": "USD",
    "order_id": "1994",
    "finalization_date": "2017-08-02T19:26:08Z",
    "btn_ref": "srctok-XXX",
    "customer": {
      "id": "mycustomer-1234",
      "email_sha256": "'`echo -n "user@example.com" | openssl dgst -sha256`'"
    }
  }'

Create an order.

Request Parameters

Advanced Request Parameters

Response

Response Object

{
    "meta": {
        "status": "ok"
    },
    "object": {
        "btn_ref": "srctok-12877f131651a0d6",
        "button_order_id": "btnorder-52ffa8ac59e48412",
        "currency": "USD",
        "order_id": "29",
        "total": 7000,
        "status": "open",
        "customer": {
          "id": "cust-123456"
        },
        "line_items": [
            {
                "identifier": "sku-1234",
                "amount": 2000,
                "quantity":2,
                "description": "T-shirts",
                "attributes":{
                    "size": "M",
                    "upc": "400000000001"
                }
            },{
                "identifier": "sku-4567",
                "amount": 3000,
                "quantity":1,
                "description": "Pants",
                "attributes":{
                    "size": "L",
                    "upc": "400000000002"
                }
            }
        ],
        "finalization_date": "2016-07-29T01:45:43Z"
    }
}

You will be returned an object that corresponds to your POST-ed order along with a Button Order ID. You do not need to store this ID as you can always manage orders in Button using the Order ID that you reported with the Order (your Order ID).

GET /v1/order/:id

Request

from pybutton import Client

client = Client('sk-XXX')

try:
    response = client.orders.get("btnorder-XXX")
except ButtonClientError as e:
    print(e)

var client = require('@button/button-client-node')('sk-XXX');

client.orders.get('btnorder-XXX', function(err, res) {
  // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.orders.get('btnorder-XXX');

curl https://api.usebutton.com/v1/order/ord-xxxxx \
  -u my-api-key:

Response Object

{
    "meta": {
        "status": "ok"
    },
    "object": {
        "btn_ref": "srctok-12877f131651a0d6",
        "button_order_id": "btnorder-52ffa8ac59e48412",
        "currency": "USD",
        "order_id": "29",
        "total": 7000,
        "status": "open",
        "customer": {
          "id": "cust-123456"
        },
        "line_items": [
            {
                "identifier": "sku-1234",
                "amount": 2000,
                "quantity":2,
                "description": "T-shirts",
                "attributes":{
                    "size": "M",
                    "upc": "400000000001"
                }
            },{
                "identifier": "sku-4567",
                "amount": 3000,
                "quantity":1,
                "description": "Pants",
                "attributes":{
                    "size": "L",
                    "upc": "400000000002"
                }
            }
        ],
        "finalization_date": "2016-07-29T01:45:43Z"
    }
}

Retrieve an order.

Request Parameters

POST /v1/order/:id

Request

from pybutton import Client

client = Client('sk-XXX')

response = client.orders.update('btnorder-XXX', {
    'total': 1000,
})

var client = require('@button/button-client-node')('sk-XXX');

client.orders.update('btnorder-XXX', { total: 1000 }, function(err, res) {
  // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.orders.update('btnorder-XXX', total: 1000)

curl https://api.usebutton.com/v1/order/ord-xxxxx \
  -X POST \
  -u my-api-key: \
  -H "Content-Type: application/json" \
  -d '{
    "total": 1000
  }'

Response Object

{
    "meta": {
        "status": "ok"
    },
    "object": {
        "btn_ref": "srctok-12877f131651a0d6",
        "button_order_id": "btnorder-52ffa8ac59e48412",
        "currency": "USD",
        "order_id": "29",
        "total": 1000,
        "status": "open",
        "customer": {
          "id": "cust-123456"
        },
        "line_items": [
            {
                "identifier": "sku-1234",
                "amount": 2000,
                "quantity":2,
                "description": "T-shirts",
                "attributes":{
                    "size": "M",
                    "upc": "400000000001"
                }
            },{
                "identifier": "sku-4567",
                "amount": 3000,
                "quantity":1,
                "description": "Pants",
                "attributes":{
                    "size": "L",
                    "upc": "400000000002"
                }
            }
        ],
        "finalization_date": "2016-07-29T01:45:43Z"
    }
}

Update an order.

Request Parameters

Advanced Request Parameters

Note: you’ll need to authenticate.

DELETE /v1/order/:id

Request

from pybutton import Client

client = Client('sk-XXX')

response = client.orders.delete("btnorder-XXX")
var client = require('@button/button-client-node')('sk-XXX');

client.orders.del('btnorder-XXX', function(err, res) {
  // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.orders.delete('btnorder-XXX');

curl https://api.usebutton.com/v1/order/ord-xxxxx \
  -X DELETE \
  -u my-api-key:

Response Object

{
    "meta": {
        "status": "ok"
    },
    "object": null
}

Delete an order.

Orders can be deleted only during the order adjustment period, which defaults to 7 days from when the order was created.

Request Parameters

Note: you’ll need to authenticate.

Accounts

GET /v1/affiliation/accounts

Request

from pybutton import Client

client = Client('sk-XXX')

response = client.accounts.all()

print(response)
# <class pybutton.Response [2 elements]>
var client = require('@button/button-client-node')('sk-XXX');

client.accounts.all(function(err, res) {
    // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.accounts.all

puts response
# => Button::Response(2 elements)
curl https://api.usebutton.com/v1/affiliation/accounts \
  -u my-api-key:

Response Object

{
   "meta": {
        "status": "ok"
    },
    "objects": [
        {
            "id": "acc-130060b42a047270",
            "name": "Button Account",
            "currency": "USD",
            "organization": "org-63cd58a1a2a8b543"
        }
    ]
}

Gets a list of available accounts. An account is similar to a bank account, it has a specific currency and has a list of transactions.

Note: you’ll need to authenticate.

Transactions

GET /v1/affiliation/accounts/:id/transactions

Request

from pybutton import Client

client = Client('sk-XXX')

response = client.accounts.transactions('acc-XXX',
    cursor='cXw',
    start='2016-07-15T00:00:00.000Z',
    end='2016-09-30T00:00:00.000Z',
)

print(response)
# <class pybutton.Response [100 elements]>
var client = require('@button/button-client-node')('sk-XXX');

client.accounts.transactions('acc-XXX', {
  cursor: 'cXw',
  start: '2015-01-01T00:00:00Z',
  end: '2016-01-01T00:00:00Z'
}, function(err, res) {
    // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.accounts.transactions('acc-XXX', {
  cursor: 'cXw',
  start: '2015-01-01T00:00:00Z',
  end: '2016-01-01T00:00:00Z'
})
cursor = response.next_cursor

puts response
# => Button::Response(75 elements)
# without optional arguments
curl https://api.usebutton.com/v1/affiliation/accounts/:id/transactions \
  -u my-api-key:

# with optional arguments
curl https://api.usebutton.com/v1/affiliation/accounts/:id/transactions?cursor=cXw&start=2015-01-01T00%3A00%3A00Z&end=2016-01-01T00%3A00%3A00Z \
  -u my-api-key:

Response Object

{
    "meta": {
        "status": "ok",
        "next": "https://api.usebutton.com/v1/affiliation/acc-130060b42a047270/transactions?cursor=cD0yMDE2LTAyLTExKzE3JTNBMDUlM0ExNyUyQjAwJTNBMDA3",
        "previous": null
    },
    "objects": [
        {
            "id": "tx-070dd05f5db6e4ec",
            "amount": 600,
            "currency": "USD",
            "category": "new-user-order",
            "created_date": "2015-11-18T19:49:17Z",
            "modified_date": "2015-11-18T19:49:17Z",
            "validated_date": null,
            "account_id": "acc-123",
            "btn_ref": "srctok-123",
            "pub_ref": null,
            "button_order_id": "btnorder-52ffa8ac59e48412",
            "order_id": "order-1",
            "order_currency": "USD",
            "order_total": 6000,
            "customer": {
                "id": "customer-1234"
            },
            "order_line_items": [
                {
                    "identifier": "sku-1234",
                    "amount": 2000,
                    "quantity":3,
                    "description": "T-shirts",
                    "attributes": {
                        "size": "M",
                        "upc": "400000000001"
                    }
                }
            ],
            "publisher_organization": "org-63cd58a1a2a8b543",
            "publisher_customer_id": "6815467b-93ca-47ce-97ae-bcf8b4292a87",
            "button_id": "btn-59722058ab439774",
            "commerce_organization": "org-44ae5a8149efe050",
            "status": "pending",
            "advertising_id": "02840796-66B3-4C96-AF72-84393B4925BF"
        }, {
            "id": "tx-40d9fe33d8e3d5ea",
            "amount": 1000,
            "currency": "USD",
            "category": "app-install",
            "created_date": "2015-11-18T19:49:17Z",
            "modified_date": "2015-11-18T19:49:17Z",
            "validated_date": "2015-11-18T19:49:17Z",
            "account_id": "acc-123",
            "btn_ref": "srctok-123",
            "pub_ref": null,
            "button_order_id": null,
            "order_id": null,
            "order_currency": null,
            "order_total": null,
            "order_line_items": null,
            "publisher_organization": "org-63cd58a1a2a8b543",
            "publisher_customer_id": "6815467b-93ca-47ce-97ae-bcf8b4292a87",
            "button_id": "btn-59722058ab439774",
            "commerce_organization": "org-44ae5a8149efe050",
            "status": "validated",
            "advertising_id": "02840796-66B3-4C96-AF72-84393B4925BF"
        }
    ]
}

Get a list of transactions. A transaction is a record of a commission owed or earned. A transaction is created when a user moves from one app to another and takes an action like installing the app, or purchasing an item (API details for a Commerce app to report an order). This is so that we can credit the Publisher app for driving the user, and debit the Commerce app as they received something they wanted (a new user or an order).

Request Parameters

If you want to paginate across your transactions, utilize the meta.next URL as your next request URL until it is null.

Note: you’ll need to authenticate.

Customers

The Customers API lets you tell us about your Customers to unlock Customer Segments, as well as other upcoming features.

POST /v1/customers

Request

curl https://api.usebutton.com/v1/customers \
  -X POST \
  -u my-api-key: \
  -H "Content-Type: application/json" \
  -d '{
    "id": "customer-1234",
    "email_sha256": "'`echo -n "user@example.com" | openssl dgst -sha256`'",
  }'
import hashlib
from pybutton import Client

client = Client('sk-XXX')

hashed_email = hashlib.sha256('user@example.com'.lower().strip()).hexdigest()

response = client.customers.create({
    'id': 'customer-1234',
    'email_sha256': hashed_email,
})
var crypto = require('crypto');
var client = require('@button/button-client-node')('sk-XXX');

var hashedEmail = crypto.createHash('sha256')
  .update('user@example.com'.toLowerCase().trim())
  .digest('hex');

client.customers.create({
  id: 'customer-1234',
  email_sha256: hashedEmail
}, function(err, res) {
    // ...
});
require 'digest'
require 'button'

client = Button::Client.new('sk-XXX')

hashed_email = Digest::SHA256.hexdigest('user@example.com'.downcase.strip)

response = client.customers.create({
  id: 'customer-1234',
  email_sha256: hashed_email
})

Response Object

{
  "id": "customer-1234"
}

Create a new Customer in Button. If the Customer already exists, it will be updated with the identifying factors provided.

Request Parameters

Parameter Required Description
id Required Your unique, stable identifier for this customer. Typically this is a numeric ID or unique string.
email_sha256 Optional The SHA-256 hash of the customer’s lowercase email, as a 64-character hex string. Note: The value of the e-mail address must be converted to lowercase before computing the hash. The hash itself may use uppercase or lowercase hex characters. Internally, Button always normalizes the hash to lowercase.
emails_sha256 Optional An array of SHA-256 hashed customer lowercase emails, as 64-character hex strings. Note: The value of the e-mail addresses must be converted to lowercase before computing the hash. The hash itself may use uppercase or lowercase hex characters. Internally, Button always normalizes the hash to lowercase.

GET /v1/customers/:id

Request

curl https://api.usebutton.com/v1/customers/customer-1234 \
  -u my-api-key:
from pybutton import Client

client = Client('sk-XXX')

response = client.customers.get('customer-1234')

print(response)
# <class pybutton.Response id: customer-1234, ...>
var client = require('@button/button-client-node')('sk-XXX');

client.customers.get('customer-1234', function(err, res) {
  // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.customers.get('customer-1234')

puts response
# => Button::Response(id: customer-1234, ...)

Response Object

{
  "meta": {
    "status": "ok"
  },
  "object": {
    "id": "customer-1234",
    "created_at": "2017-07-17T21:52:21.748Z",
    "emails_sha256": [
      "b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"
    ],
    "segment": "new"
  }
}

Retrieve a Customer from the Button API. You can lookup by either your Customer ID, or the Button Customer ID.

Response Object

Key Description
id Your unique, stable identifier for this customer. Typically this is a numeric ID or unique string.
segments An array of zero or more maps that describe segments of which the Customer a member.

Merchants

GET /v1/merchants

Request

curl https://api.usebutton.com/v1/merchants?status=approved&currency=USD
from pybutton import Client

client = Client('sk-XXX')

response = client.merchants.all(status='approved', currency='USD')
var client = require('@button/button-client-node')('sk-XXX');

client.merchants.all({
  status: 'approved',
  currency: 'USD'
}, function(err, res) {
    // ...
});
require 'button'

client = Button::Client.new('sk-XXX')

response = client.merchants.all(status: 'approved', currency: 'USD')

Response Object

{
  "objects": [
    {
      "id": "org-xxxxxxxxxxxxx",
      "name": "Deals Merchant",
      "categories": [
        "Deals"
      ],
      "urls": {
        "homepage": "https://merchant.com"
      },
      "metadata": {
        "description": "Deals and Coupons for Restaurants, Fitness, and more.",
        "icon_url": "https://www.usebutton.com/no-image.png",
        "banner_url": "https://www.usebutton.com/no-image.png"
      },
      "active_rates": [
        {
          "action": "install",
          "segment": "default",
          "currency": "USD",
          "commission": [
            {
              "from": 0,
              "rule": {
                "base": 210,
                "numerator": 0,
                "denominator": 1,
                "percent": 0
              },
              "description": "commission = 210"
            }
          ],
          "commission_window_seconds": "not_applicable"
        },
        {
          "action": "order",
          "segment": "new",
          "currency": "USD",
          "commission": [
            {
              "from": 0,
              "rule": {
                "base": 0,
                "numerator": 1,
                "denominator": 5,
                "percent": 20.0
              },
              "description": "when price below 7500: commission(price) = 1 * price / 5",
              "to": 7500
            },
            {
              "from": 7500,
              "rule": {
                "base": 1500,
                "numerator": 1,
                "denominator": 10,
                "percent": 10.0
              },
              "description": "when price above 7500: commission(price) = 1500 + 1 * price / 10"
            }
          ],
          "commission_window_seconds": 604800
        }
      ],
      "available_platforms": ["ios", "android"],
      "status": "approved"
    }
  ]
}

Fetch all Partners and associated information that is available for this app with optional ability to specify user details to access segmented rates.

HTTP Request

GET https://api.usebutton.com/v1/merchants

Query Parameters

Parameter Required Description
status false Status of merchants to retrieve. (approved, pending or available)
currency false The ISO currency code for a currency to filter rates to. e.g. USD

Rate model

As part of the response, an array of active_rates is returned for each merchant. Each rate follow the following structure:

Links

The Links endpoint is used to generate an attributed link for a particular merchant or request metadata about how a given link will perform in our system.

POST /v1/links

Request

{
  "url": "https://partner.com/goods/123"
}

Response Object

{
  "meta": {
    "status": "ok"
  },
  "object": {
    "universal": "https://r.bttn.io?btn_url=https%3A%2F%2Fpartner.com%2Fgoods%2F123&btn_ref=org-XXX",
    "affiliate": null,
    "merchant_id": "org-3573c6b896624279"
  }
}

Generate and return a link to a merchant identified by their url. This link can then be used by a single user to link to the merchant and make attributed purchases.

HTTP Request

POST https://api.usebutton.com/v1/links

Post Parameters

Parameter Required Description
url true

POST /v1/links/info

Request

{
  "url": "https://partner.com/goods/123"
}

Response Object

{
  "meta": {
    "status": "ok"
  },
  "object": {
    "organization_id": "org-XXX",
    "approved": true,
    "ios_support": {
      "app_to_web": true,
      "app_to_app": true,
      "web_to_web": true,
      "web_to_app": true,
      "web_to_app_with_install": false
    },
    "android_support": {
      "app_to_web": true,
      "app_to_app": true,
      "web_to_web": true,
      "web_to_app": true,
      "web_to_app_with_install": false
    }
  }
}

Fetch attributes of a URL. This includes the id of the merchant in Button’s namespace (organization_id), approval status, and supported flows.

HTTP Request

POST https://api.usebutton.com/v1/links/info

Post Parameters

Parameter Required Description
url true