NAV
python

Buda.com's API

Great! You found the API documentation for Buda.com. If you are not a software developer you might be a little lost 😀. We offer REST and Websocket APIs to suit your needs.

REST API

Introduction

An example using the requests library

import requests # install requests with `pip install requests`

url = 'https://www.buda.com/api/v2/markets/eth-btc/ticker'
response = requests.get(url)
print(response.json())

Like many other cryptocurrency exchanges, Buda.com's API has public endpoints and private endpoints:

Our API's URLs usually have this format

https://www.buda.com/api/[version]/[path].[format]

Where currently:

Parameter Value
version v2
format json

Open Source Libraries

Clients

If you want to save some time, these are some clients for our API in various languages.

These libraries are not official nor have been tested by us, but we have spoken to their creators who seem like good people 😉.

Language Link
Go https://github.com/niedbalski/go-buda
Java https://github.com/FeroSalgado/java-surbtc-api
Java https://github.com/daplay/jsurbtc
Javascript https://github.com/ajunge/buda-promise
Python https://github.com/delta575/trading-api-wrappers
Python https://github.com/CriptoPagos/surbtc-api-client-python

If you want to share your own library with the community, contact us at [email protected].

Other libraries

CCXT is a very useful library that facilitates connecting to over 100 exchanges (including Buda ❤️) using Python, Javascript, or PHP. Yes, really.

Public Endpoints

Markets

import requests

url = 'https://www.buda.com/api/v2/markets'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "markets": [
    {
      "id": "BTC-CLP",
      "name": "btc-clp",
      "base_currency": "BTC",
      "quote_currency": "CLP",
      "minimum_order_amount": ["0.001", "BTC"],
      "taker_fee": "0.8",
      "maker_fee": "0.4"
    },
    {
      "id": "BTC-COP",
      "name": "btc-cop",
      "base_currency": "BTC",
      "quote_currency": "COP",
      "minimum_order_amount": ["0.001", "BTC"],
      "taker_fee": "0.8",
      "maker_fee": "0.4"
    },
    ...
  ]
}

Obtain market details

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "market": {
    "id": "BTC-CLP",
    "name": "btc-clp",
    "base_currency": "BTC",
    "quote_currency": "CLP",
    "minimum_order_amount": ["0.001", "BTC"],
    "taker_fee": "0.8",
    "maker_fee": "0.4"
  }
}

A given market separates the buys and sells by currency. In each market, the base_currency is bought or sold, and the quote_currency is used to pay for these trades. We use these two currencies to identify each market.

For example, the market in which bitcoins (BTC) are traded against dollars (USDC) is: btc-usdc.

HTTP Request

GET /markets

GET /markets/<market_id>

Path Parameters

Parameter Description
market_id (optional) The market ID (for example: btc-clp, eth-btc, etc).
You can obtain a complete list of all markets by leaving this parameter blank.

Response Details

Key Type Description
id [string] Market identifier
name [string] Market name
base_currency [string] Currency traded
quote_currency [string] Currency paid
minimum_order_amount [amount, currency] Minimumm order amount accepted
taker_fee [amount] Fee paid by a taker order
maker_fee [amount] Fee paid by a maker order

Transacted Volume

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/volume'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "volume": {
    "ask_volume_24h": ["4.97241513", "BTC"],
    "ask_volume_7d": ["43.15391694", "BTC"],
    "bid_volume_24h": ["8.03642037", "BTC"],
    "bid_volume_7d": ["35.77704356", "BTC"],
    "market_id": "BTC-CLP"
  }
}

This endpoint accesses all the transacted volume in a given market, where ask_volume is the volume traded in sell orders, while bid_volume is the volume traded by buy orders.

HTTP Request

GET /markets/<market_id>/volume

Response Details

Key Type Description
ask_volume_24h [amount, currency] Amount transacted in sell orders in the last 24 hours
ask_volume_7d [string] Amount transacted in sell orders in the last 7 days
bid_volume_24h [amount, currency] Amount transacted in buy orders in the last 24 hours
bid_volume_7d [string] Amount transacted in buy orders in the last 7 days
market_id [string] Requested market ID

Ticker

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/ticker'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "ticker": {
    "last_price": ["879789.0", "CLP"],
    "market_id": "BTC-CLP",
    "max_bid": ["879658.0", "CLP"],
    "min_ask": ["876531.11", "CLP"],
    "price_variation_24h": "0.005",
    "price_variation_7d": "0.1",
    "volume": ["102.0", "BTC"]
  }
}

This endpoint gives access to the current state of a given market. This response includes the best buy and sell price currently available (bid and ask) and the last traded price (last_price) for the selected market. There is also information related to the daily volume and price change.

HTTP Request

GET /markets/<market_id>/ticker

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

Response Details

Key Type Description
market_id [currency] Requested market ID
last_price [amount, currency] Last traded price
min_ask [amount, currency] Min sell price
max_bid [amount, currency] Max buy price
volume [amount, currency] Transacted volume in the last 24 hours
price_variation_24h [float] Percentage variation of price in the last 24 hours
price_variation_7d [float] Percentage variation of price in the last 7 days

Order Book

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/order_book'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "order_book": {
    "asks": [
      ["836677.14", "0.447349"],
      ["837462.23", "1.43804963"],
      ["837571.89", "1.41498541"],
      ["837597.23", "0.13177617"],
      ["837753.25", "1.40724154"],
      ["837858.51", "1.40988433"],
      ["837937.0", "1.46619702"],
      ["838000.57", "1.4527277"],
      ["838305.78", "0.8317892"],
      ...
    ],
    "bids": [
      ["821580.0", "0.25667389"],
      ["821211.0", "0.27827307"],
      ["819882.39", "1.40003128"],
      ["819622.99", "1.40668862"],
      ["819489.9", "1.41736995"],
      ["818942.2", "1.41001753"],
      ["818820.29", "0.93677863"],
      ["816879.83", "1.44022295"],
      ...
    ]
  }
}

Get a list of all the limit buy and sell orders currently placed in a given market.

HTTP Request

GET /markets/<market_id>/order_book

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

Response Details

Key Type Description
asks [price, amount] Array with sell orders
bids [price, amount] Array with buy orders

Trade History

import time
import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/trades'
response = requests.get(url, params={
    'timestamp': int(time.time()) - 60 * 60 * 24 * 7,
    'limit': 50,
})
print(response.json())

This call returns an object with the following format:

{
  "trades": {
    "timestamp": "1476905551698",
    "last_timestamp": "1476380738941",
    "market_id": "BTC-CLP",
    "entries": [
      ["1476905551687", "0.00984662", "435447.12", "buy"],
      ["1476905551676", "3.01572553", "435283.3", "buy"],
      ...
    ]
  }
}

Get a list of all recent trades in a given market.

HTTP Request

GET markets/<market_id>/trades

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

URL Parameters

Included at the end of the URL For example: GET /markets/BTC-CLP/trades?timestamp=1502472564

Parameter Description
timestamp (optional) Unix timestamp indicating trade to request
limit (optional) Amount of trades requested [default: 50, max: 100]

Response Details

Key Type Description
entries [timestamp, amount, price, direction] Array with transaction history
timestamp [timestamp] Most recent Unix timestamp for the given response
last_timestamp [timestamp] Least recent Unix timestamp for the given response
market_id [currency] Market ID being requested

Simulate Orders

import requests

market = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market}/quotations'
response = requests.post(url, json={
    'type': 'bid_given_size',
    'amount': 1,
})
print(response.json())

This call returns an object with the following format:

{
  "quotation": {
    "amount": ["1.0", "BTC"],
    "base_balance_change": ["0.99200003", "BTC"],
    "base_exchanged": ["1.0", "BTC"],
    "fee": ["0.00799997", "BTC"],
    "incomplete": false,
    "limit": null,
    "order_amount": ["1.0", "BTC"],
    "quote_balance_change": ["-4872696.01", "CLP"],
    "quote_exchanged": ["4872696.01", "CLP"],
    "type": "bid_given_size"
  }
}

Get a simulated quote for an order in a given market using the current order book.

Quote types

This endpoint can simulate many different types of quotes.

For this, you can choose a specific market for the simulation, where our market IDs are in the <base_currency>-<quote_currency> format (we will use the eth-btc market as an example). You can simulate what a buy or sell order would be for a certian amount of the base_currency or quote_currency. (If you want more detail about what is a buy or sell order you con go check My Orders)

For the simulation, you need to choose one of the following types and send it as the type payload parameter.

Quote type Description
bid_given_size or bid_given_earned_base Simulates a buy order to receive a certain amount of base_currency (for example: How much btc is requiered to obtain a certain amount of eth?)
bid_given_value or bid_given_spent_quote Simulates a buy order to spend a certain amount of quote_currency (for example: How much eth will I receive if I buy a certain amount of btc?)
ask_given_size or ask_given_spent_base Simulates a sell order to spend a certain amount of base_currency (for example: How much btc would I receive if I sell a certain amount of eth?)
ask_given_value or ask_given_earned_quote Simulates a sell order to receive a certain amount of quote_currency (for example: How much eth is requiered to obtain a certain amount of btc?)

HTTP Request

POST '/markets/<market_id>/quotations

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

Request Payload

Key Required Description
type Yes Quote type being requested (see previous table)
amount Yes Amount to simulate quote (represents base_currency or quote_currency) depending on the type parameter
limit No Price requested for the currency in which the amount parameter is expressed in

Response Details

Key Type Description
amount [amount, currency] The amount value sent in the payload.
base_balance_change [amount, currency] How much your base_currency balance would change after fees. This can be either positive or negative.
base_exchanged [amount, currency] Total base_currency amount that would be traded. This is always positive.
fee [amount, currency] Fee charged for trade.
incomplete [boolean] Indicates whether or not your simulated order would be completely filled given current market conditions (order book and your current balance).
limit [amount, currency] The limit value sent in the payload.
order_amount [amount, currency] The same value as base_exchanged.
quote_balance_change [amount, currency] How much your quote_currency balance would change after fees. This can be either positive or negative.
quote_exchanged [amount, currency] Total quote_currency amount that would be traded. This is always positive.
type [string] Quote type requested.

About fee calculations (fee)

Deposit/Withdrawal Fees

import requests

currency = 'btc'
transaction_type = 'withdrawal'
url = f'https://www.buda.com/api/v2/currencies/{currency}/fees/{transaction_type}'
response = requests.get(url)
print(response.json())

This call returns an object with the following format:

{
  "fee": {
    "name": "withdrawal",
    "percent": 0,
    "base": ["0.00000015", "BTC"]
  }
}

Provides all the related fees to the deposit or withdrawal of a given currency.

Keep in mind:

HTTP Request

GET /currencies/<currency>/fees/<transaction_type>

Path Parameters

Parameter Description
currency Acronym of the currency being requested
transaction_type Transaction type. It can be either deposit or withdrawal

Response Details (JSON)

Key Type Description
name [string] Transaction type
percent [number] Variable cost per transaction (percantage)
base [amount, currency] Fixed cost per transaction

Private Endpoints

Private endpoints access a user's private information, place/cancel orders, and deposit/withdraw funds.

In order to access these endpoints, it is necessary to authenticate the user. This is done by using an API-KEY and a signature derived from an API-SECRET.

Authentication

Authentication example using the Requests library

import base64
import hmac
import time
import requests.auth

class BudaHMACAuth(requests.auth.AuthBase):
    """Appends the HMAC Buda authentication to the Request object"""

    def __init__(self, api_key: str, secret: str):
        self.api_key = api_key
        self.secret = secret

    def get_nonce(self) -> str:
        # 1. Generate nonce (timestamp in microseconds)
        return str(int(time.time() * 1e6))

    def sign(self, r, nonce: str) -> str:
        # 2. Prepare string for signing
        components = [r.method, r.path_url]
        if r.body:
            encoded_body = base64.b64encode(r.body).decode()
            components.append(encoded_body)
        components.append(nonce)
        msg = ' '.join(components)
        # 3. Get the signature
        h = hmac.new(key=self.secret.encode(),
                        msg=msg.encode(),
                        digestmod='sha384')
        signature = h.hexdigest()
        return signature

    def __call__(self, r):
        nonce = self.get_nonce()
        signature = self.sign(r, nonce)
        # 4. Append API-KEY, nonce and signature to request header
        r.headers['X-SBTC-APIKEY'] = self.api_key
        r.headers['X-SBTC-NONCE'] = nonce
        r.headers['X-SBTC-SIGNATURE'] = signature
        return r

# To authenticate an API call the `auth` parameter must be included in the request
request = requests.post(url, auth=BudaHMACAuth(api_key, secret))

We did our best to make a secure but simple authentication process. I think it ended up being more secure than simple, but don't worry, there are many great examples.

The first step is to generate an API-KEY for the authenticated API calls. This can be done in "Mi cuenta", where you can generate an API-KEY and an API-SECRET.

Once you have your API-KEY you can use it to request private endpoints. Buda.com expects all private calls to be signed following these steps:

1. Generate a nonce

The nonce is an integer that must be greater than the most recently used nonce. This protects you from a "Man in the middle" attack. The recommended way to do this is by using timestamps.

2. Prepare string for signing

The string content is as follows:

{GET|POST|PUT} {path} {base64_encoded_body} {nonce}

Where:

For example:

GET /api/v1/orders?open=true 423874932432

3. Get the signature

The signature is an authentication message based on an HMAC hash, which is generated using the SHA-384 hash function on the API-SECRET and string generated on the previous step 😱. This string must be encoded in hexadecimal format.

Don't worry, most programming languages have an HMAC generator function included in standard libraries. An example can be seen over to your right -->.

4. Append API-KEY, nonce and signature to request header

For example:

Header Value
X-SBTC-APIKEY 0faea2f360a508a6d105a3bb60247af0
X-SBTC-NONCE 145511231131231
X-SBTC-SIGNATURE 5c873eddb1117b930b1caa058ada3f7...

Pagination

This is an example of a paginated response

{
  "orders": [
    {
      "id": 1,
      "type": "Ask",
      "state": "traded",
      "created_at": "2017-03-10T21:11:42.131Z",
      "market_id": "BTC-CLP",
      "account_id": 5,
      "fee_currency": "CLP",
      "price_type": "limit",
      "limit": ["700000.0", "CLP"],
      "amount": ["0.0", "BTC"],
      "original_amount": ["5.0", "BTC"],
      "traded_amount": ["5.0", "BTC"],
      "total_exchanged": ["3625000.0", "CLP"],
      "paid_fee": ["19937.5", "CLP"]
    },
    ...
  ],
  "meta": {
    "total_pages": 3,
    "total_count": 50,
    "current_page": 1
  }
}

Some responses may include a lot of data, so in order to prevent our server from being overworked and delaying the response, we use pagination to separate the response into smaller segments.

If an endpoint uses pagination, then it will accept the following query parameters:

Query Parameters

Parameter Default Description
per 20 Elements per page [min: 1, max: 300]
page 1 The number of pages to receive. The first page received is 1

Response Details (JSON)

Estos endpoints siempre devolverán, además de los elementos solicitados, un objeto meta dentro de la respuesta, cuya estructura es la siguiente:

These endpoint's response will additionally include a meta object with the following format:

Key Type Description
total_pages [int] Total page count that represents the complete response
total_count [int] Total element count the represents the complete response
current_page [int] Page number that represents the data in the current response

Account Information

import requests
url = f'https://www.buda.com/api/v2/me'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth)
print(response.json())

This call returns an object with the following format:

{
  "user": {
    "id": "current",
    "email": "[email protected]",
    "category": "personal",
    "display_name": "Satoshi Nakamoto",
    "account_data": {
      "names": "Satoshi",
      "surnames": "Nakamoto",
      "nationality": "CL",
      "document_type": "Documento Nacional de Identidad",
      "document_number": "209999999",
      "birth_date": "2008-10-31",
      "profession": "Economista",
      "residence_address": "Unknown",
    },
    "monthly_transacted": [
      "57157.95",
      "USD"
    ],
    "pubsub_key": "xxxx-xxxx-xxxx-xxxx",
  }
}

Shows your account's personal information.

HTTP Request

GET /me

Response Details (JSON)

Key Type Description
id [string] Account ID
email [string] Email address associated to account
display_name [string] Full name associated to account
monthly_transacted [amount, currency] Amount transacted in the last 30 days
pubsub_key [string] PubSub Key for WebSocket authentication

Balances

import requests

url = f'https://www.buda.com/api/v2/balances'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth)
print(response.json())

This call returns an object with the following format:

{
  "balances": [
    {
      "id": "BTC",
      "amount": ["11.5274815", "BTC"],
      "available_amount": ["10.5274815", "BTC"],
      "frozen_amount": ["1.0", "BTC"],
      "pending_withdraw_amount": ["0.0", "BTC"]
    },
    {
      "id": "CLP",
      "amount": ["7349002.46", "CLP"],
      "available_amount": ["7349002.46", "CLP"],
      "frozen_amount": ["0.0", "CLP"],
      "pending_withdraw_amount": ["0.0", "CLP"]
    },
    ...
  ]
}

Example for one currency:

import requests

currency = 'btc'
url = f'https://www.buda.com/api/v2/balances/{currency}'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth)
print(response.json())

This call returns an object with the following format:

{
  "balance": {
    "id": "BTC",
    "amount": ["11.5274815", "BTC"],
    "available_amount": ["10.5274815", "BTC"],
    "frozen_amount": ["1.0", "BTC"],
    "pending_withdraw_amount": ["0.0", "BTC"]
  }
}

This endpoint shows your account's balance for each currency.

HTTP Request

GET /balances

GET /balances/<currency>

Path Parameters

Parameter Description
currency (optional) - Acronym for given currency: btc, eth, clp,...
If no currency is provided then all currencies are considered

Response Details (JSON)

Key Type Description
id [currency] Acronym for given currency
amount [amount, currency] Total balance for the account
available_amount [amount, currency] Available amount for order placement and withdrawals
frozen_amount [amount, currency] Frozen amount due to placed limit orders
pending_withdrawal_amount [amount, currency] Frozen amount due to withdrawal request

My Orders

Example:

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/orders'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth, params={
    'state': 'traded',
    'per': 20,
    'page': 1,
})
print(response.json())

This call returns an object with the following format:

{
  "orders": [
    {
      "id": 1,
      "type": "Bid",
      "state": "traded",
      "created_at": "2017-06-30T02:14:45.368Z",
      "market_id": "BTC-CLP",
      "fee_currency": "BTC",
      "price_type": "limit",
      "limit": ["1728000.0", "CLP"],
      "amount": ["0.001", "BTC"],
      "original_amount": ["0.001", "BTC"],
      "traded_amount": ["0.0", "BTC"],
      "total_exchanged": ["0.0", "CLP"],
      "paid_fee": ["0.0", "BTC"]
    },
    {
      "id": 2,
      "type": "Ask",
      "state": "traded",
      "created_at": "2017-03-10T21:11:42.131Z",
      "market_id": "BTC-CLP",
      "fee_currency": "CLP",
      "price_type": "limit",
      "limit": ["700000.0", "CLP"],
      "amount": ["0.0", "BTC"],
      "original_amount": ["5.0", "BTC"],
      "traded_amount": ["5.0", "BTC"],
      "total_exchanged": ["3625000.0", "CLP"],
      "paid_fee": ["19937.5", "CLP"]
    },
    ...
  ],
  "meta": {
    "current_page": 1,
    "total_count": 50,
    "total_pages": 3
  }
}

An order is a fundamental part of any exchange. It consists of either a sell or buy offer (type) for a ciertain amount of a market's base_currency (usually cypto) at a limit or market price.

Market orders

If the order type (price_type) is market, the order will be immediatly executed at the best possible price, taking account the order amount, with the current order book. These orders are traded against the current limit orders.

Limit orders

If the order type (price_type) is limit, an order is created at the desired price, using the limit parameter, which will execute only if it can trade against an opposing market order.

These orders are programed to execute immediately after their creation, but this process occurs asynchronously since each order enters a FIFO queue. A limit order can be partially filled, since an opposing market order may not cover it entirely.

Order state

An order has many states during its life cycle:

State Description
received The order has been received but hasn't been processed yet.
pending The max amount an order can cost is frozen from your balance, and the order can start matching with other orders.
traded The order has been completely traded.
canceled The order has been canceled and the max cost is unfrozen from the balance.
unprepared There aren't sufficient funds to process the order (only for limit orders).

HTTP Request

GET /markets/<market_id>/orders

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).

Query Parameters

Parameter Default Description
state None Request order with certain state

Response Details (JSON)

Key Type Description
amount [amount, currency] Pending order volume
created_at [string] Order creation timestamp
fee_currency [currency] Currency in which the fee is payed in (For example: "BTC", "CLP" ,"COP")
id [int] Order ID
limit [amount, currency] Order price
market_id [string] Market ID
original_amount [amount, currency] Original order volume
paid_fee [amount, currency] Fee paid by the order
price_type [string] Order type (limit / market)
state [string] Order state
total_exchanged [amount, currency] Total traded
traded_amount [amount, currency] Volume transacted
type [string] Order side (Bid / Ask)

Order Details

Example:

import requests

order_id = 1
url = f'https://www.buda.com/api/v2/orders/{order_id}'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth)
print(response.json())

This call returns an object with the following format:

{
  "order": {
    "id": 1,
    "type": "Bid",
    "state": "traded",
    "created_at": "2017-06-30T02:14:45.368Z",
    "market_id": "BTC-CLP",
    "fee_currency": "BTC",
    "price_type": "limit",
    "limit": ["1728000.0", "CLP"],
    "amount": ["0.001", "BTC"],
    "original_amount": ["0.001", "BTC"],
    "traded_amount": ["0.0", "BTC"],
    "total_exchanged": ["0.0", "CLP"],
    "paid_fee": ["0.0", "BTC"]
  }
}

Provides all details relevant to an order.

HTTP Request

GET /orders/<id>

Path Parameters

Parameter Description
id Order ID to request

Response Details (JSON)

Key Type Description
amount [amount, currency] Pending order volume
created_at [string] Order creation timestamp
fee_currency [currency] Currency in which the fee is payed in (For example: "BTC", "CLP" ,"COP")
id [int] Order ID
limit [amount, currency] Order price
market_id [string] Market ID
original_amount [amount, currency] Original order volume
paid_fee [amount, currency] Fee paid by the order
price_type [string] Order type (limit / market)
state [string] Order state
total_exchanged [amount, currency] Total traded
traded_amount [amount, currency] Volume transacted
type [string] Order side (Bid / Ask)

New Order

import requests

market_id = 'btc-clp'
url = f'https://www.buda.com/api/v2/markets/{market_id}/orders'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'type': 'Bid',
    'price_type': 'limit',
    'limit': 1000000,
    'amount': 0.05,
})
print(response.json())

This call returns an object with the following format:

{
  "order": {
    "id": 2,
    "amount": ["0.05", "BTC"],
    "created_at": "2017-04-18T19:54:24.611Z",
    "fee_currency": "BTC",
    "limit": ["1000000.0", "CLP"],
    "market_id": "BTC-CLP",
    "original_amount": ["0.05", "BTC"],
    "paid_fee": ["0.0", "BTC"],
    "price_type": "limit",
    "state": "received",
    "total_exchanged": ["0.0", "CLP"],
    "traded_amount": ["0.0", "BTC"],
    "type": "Bid"
  }
}

Create a new order.

HTTP Request

POST /markets/<market_id>/orders

Path Parameters

Parameter Description
market_id The market ID (for example: btc-clp, eth-btc, etc).

Request Payload

Key Required Description
type Yes Order side (Bid / Ask)
price_type Yes Order type (limit / market)
limit Limit Order price
amount Yes Order size

Response Details (JSON)

Key Type Description
amount [amount, currency] Pending order volume
created_at [string] Order creation timestamp
fee_currency [currency] Currency in which the fee is payed in (For example: "BTC", "CLP" ,"COP")
id [int] Order ID
limit [amount, currency] Order price
market_id [string] Market ID
original_amount [amount, currency] Original order volume
paid_fee [amount, currency] Fee paid by the order
price_type [string] Order type (limit / market)
state [string] Order state
total_exchanged [amount, currency] Total traded
traded_amount [amount, currency] Volume transacted
type [string] Order side (Bid / Ask)

Cancel Order

import requests

order_id = 2
url = f'https://www.buda.com/api/v2/orders/{order_id}'
auth = BudaHMACAuth(api_key, secret)
response = requests.put(url, auth=auth, json={
    'state': 'canceling',
})
print(response.json())

This call returns an object with the following format:

{
  "order": {
    "id": 2,
    "amount": ["0.05", "BTC"],
    "created_at": "2017-04-18T19:54:24.611Z",
    "fee_currency": "BTC",
    "limit": ["1000000.0", "CLP"],
    "market_id": "BTC-CLP",
    "original_amount": ["0.05", "BTC"],
    "paid_fee": ["0.0", "BTC"],
    "price_type": "limit",
    "state": "pending",
    "total_exchanged": ["0.0", "CLP"],
    "traded_amount": ["0.0", "BTC"],
    "type": "Bid"
  }
}

Provides endpoint for canceling an order. If the request provides a correct response, then the order is guaranteed to have been submitted for cancelation. This process can have a delay depending on the trading engine's load.

HTTP Request

PUT /orders/<id>

Path Parameters

Parameter Description
id Order ID requested for cancelation

Request Payload

Key Required Description
state Yes Must indicate "canceling"

Response Details (JSON)

Key Type Description
amount [amount, currency] Pending order volume
created_at [string] Order creation timestamp
fee_currency [currency] Currency in which the fee is payed in (For example: "BTC", "CLP" ,"COP")
id [int] Order ID
limit [amount, currency] Order price
market_id [string] Market ID
original_amount [amount, currency] Original order volume
paid_fee [amount, currency] Fee paid by the order
price_type [string] Order type (limit / market)
state [string] Order state
total_exchanged [amount, currency] Total traded
traded_amount [amount, currency] Volume transacted
type [string] Order side (Bid / Ask)

Batch Orders

import requests

url = f'https://www.buda.com/api/v2/orders'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'diff': [{'mode': 'cancel', 'order_id': 1000},
             {'mode': 'cancel', 'order_id': 1003},
             {'mode': 'place', 'order': {'amount': 1.5,
                                         'limit': 3500000.0,
                                         'market_name': 'btc-clp',
                                         'price_type': 'limit',
                                         'type': 'Ask'}},
             {'mode': 'place', 'order': {'amount': 10.5,
                                         'market_name': 'eth-clp',
                                         'price_type': 'market',
                                         'type': 'Bid'}}]
})
print(response.json())

This call returns an object with the following format:

{
  "success": true
}

Create or cancel orders by batches.

HTTP Request

POST /orders

Request Payload

Key Required Description
mode Yes Batch order type (place / cancel)
type Yes order side (Bid / Ask)
price_type Yes Order type (limit / market)
limit Limit Order price
amount Yes Order volume
market_name Yes The market ID (for example: btc-clp, eth-btc, etc).

Response Details (JSON)

Key Type Description
success [bool] true when the batch order has been successful

Deposit/Withdrawal History

Deposit example:

import requests

currency = 'btc'
url = f'https://www.buda.com/api/v2/currencies/{currency}/deposits'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth, params={
    'state': 'confirmed',
    'per': 20,
    'page': 1,
})
print(response.json())

This call returns an object with the following format:

{
  "deposits": [
    {
      "id": 1,
      "created_at": "2017-06-09T02:05:24.374Z",
      "amount": ["0.4", "BTC"],
      "currency": "BTC",
      "fee": ["0.0", "BTC"],
      "state": "confirmed",
      "deposit_data": {
        "type": "btc_deposit_data",
        "address": "mo366JJaDU5B1hmnPygyjQVMbUKnBC7DsY",
        "tx_hash":
          "51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015"
      }
    },
    ...
  ],
  "meta": {
    "current_page": 1,
    "total_count": 50,
    "total_pages": 3
  }
}

Withdrawal example:

import requests

currency = 'btc'
url = f'https://www.buda.com/api/v2/currencies/{currency}/withdrawals'
auth = BudaHMACAuth(api_key, secret)
response = requests.get(url, auth=auth, params={
    'state': 'confirmed',
    'per': 20,
    'page': 1,
})
print(response.json())

This call returns an object with the following format:

{
  "withdrawals": [
    {
      "id": 1,
      "created_at": "2017-11-11T17:17:57.845Z",
      "state": "confirmed",
      "amount": ["0.35", "BTC"],
      "fee": ["0.00001", "BTC"],
      "currency": "BTC",
      "withdrawal_data": {
        "type": "btc_withdrawal_data",
        "target_address": "mo366JJaDU5B1hmnPygyjQVMbUKnBC7DsY",
        "tx_hash":
          "51eaf04f9dbbc1417dc97e789edd0c37ecda88bac490434e367ea81b71b7b015"
      }
    },
    ...
  ],
  "meta": {
    "current_page": 1,
    "total_count": 50,
    "total_pages": 3
  }
}

Provides deposit and withdrawal history for fiat and crypto.

Each deposit or withdrawal can have one of the following states:

State Description
pending_confirmation The deposit hasn't yet been confirmed
confirmed The deposit has been confirmed and added to your account
rejected The deposit has been rejected
retained The deposit has been retained, usually because it has breached the terms of service agreement

HTTP Request

GET /currencies/<currency>/deposits

GET /currencies/<currency>/withdrawals

Path Parameters

Parameter Description
currency Acronym of the currency being requested

Query Parameters

Parameter Default Description
state None Request deposit or withdrawal with certain state

Response Details (JSON)

Key Type Description
id [int] Deposit/withdrawal ID
created_at [time] Creation timestamp
amount [amount, currency] Amount requested for deposit/withdrawal
currency [currency] Currency for deposit/withdrawal
fee [amount, currency] Fee incurred by deposit/withdrawal
state [string] Request current state (For example: confirmed, rejected)
deposit_data / withdrawal_data [object] Object with deposit/withdrawal details
type [string] Data type delivered (For example: btc_deposit_data,fiat_withdrawal_data)
address [address] Deposit address
target_address [address] Withdrawal address
tx_hash [string] Transaction ID

New Fiat Deposit

import requests

currency = 'clp'
url = f'https://www.buda.com/api/v2/currencies/{currency}/deposits'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'simulate': True,
    'amount': 25000,
})
print(response.json())

This call returns an object with the following format:

{
  "deposit": {
    "id": null,
    "amount": ["250000.0", "CLP"],
    "created_at": "2018-07-18T03:24:08.121Z",
    "currency": "CLP",
    "deposit_data": {
      "created_at": "2018-07-18T03:24:08.106Z",
      "type": "fiat_deposit_data",
      "updated_at": "2018-07-18T03:24:08.106Z",
      "upload_url": null
    },
    "fee": ["0.0", "CLP"],
    "state": "pending_confirmation"
  }
}

Generate a new depoist request.

The fiat deposit process has 2 steps:

  1. Make a bank deposit.
  2. Generate a new fiat deposit request for the deposited amount using this endpoint.

HTTP Request

POST /currencies/<currency>/deposits

URL Parameters

Parameter Description
currency Acronym of the currency being deposited

Request Payload

Key Required Description
amount Yes Depsit size
simulate No Allows for a deposit simulation

Response Details (JSON)

Key Type Description
id [int] Deposit/withdrawal ID
created_at [time] Creation timestamp
amount [amount, currency] Amount requested for deposit/withdrawal
currency [currency] Currency for deposit/withdrawal
fee [amount, currency] Fee incurred by deposit/withdrawal
state [string] Request current state (For example: confirmed, rejected)
deposit_data [array] Array with relevant data

New Crypto Deposit

import time
import requests

currency = 'btc'
auth = BudaHMACAuth(api_key, secret)

# Create a new address and obtain it's ID
url = f'https://www.buda.com/api/v2/currencies/{currency}/receive_addresses'
response = requests.post(url, auth=auth)
address_id = response.json()['receive_address']['id']

# Wait for the new address to be created
time.sleep(3)

# Obtain the new address
url = f'https://www.buda.com/api/v2/currencies/{currency}/receive_addresses/{address_id}'
response = requests.get(url, auth=auth)
print(response.json())

This call returns an object with the following format:

{
  "receive_address": {
    "id": 1,
    "created_at": "2017-04-26T13:47:42.000Z",
    "address": "mo366JJaDU5B1hmnPygyjQVMbUKnBC7DsY",
    "ready": true,
    "used": false
  }
}

Generate a new crypto deposit address from Buda.com.

Keep in mind that the address creation is an asynchronous process, so first, you have to request a deposit and then request the address using the id provided in the first request.

HTTP Request

Request Description
POST /currencies/<currency>/receive_addresses Request the creation of a new crypto deposit address.
GET /currencies/<currency>/receive_addresses/<id> Request the deposit address for the id generated from the previous endpoint.
GET /currencies/<currency>/receive_addresses Provides a list of all cypto addresses related to the account (uses pagination).

URL Parameters

Parameter Description
currency Acronym of the currency being deposited
id Receive address ID

Response Details (JSON)

Key Type Description
id [int] Receive address ID
created_at [time] Timestamp
address [address] Assigned address for deposit
ready [bool] Is the address is ready for use?
used [bool] Has the address already been used before?

New Withdrawal

import requests

currency = 'btc'
url = f'https://www.buda.com/api/v2/currencies/{currency}/withdrawals'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'amount': 0.05,
    'simulate': True,
    'amount_includes_fee': True,
    'withdrawal_data': {
        'target_address': 'mo366JJaDU5B1hmnPygyjQVMbUKnBC7DsY',
    },
})
print(response.json())

This call returns an object with the following format:

{
  "withdrawal": {
    "id": null,
    "amount": ["0.05", "BTC"],
    "created_at": "2017-04-26T13:47:42.000Z",
    "currency": "BTC",
    "fee": ["0.0", "BTC"],
    "state": "simulated",
    "withdrawal_data": {
      "target_address": "mo366JJaDU5B1hmnPygyjQVMbUKnBC7DsY",
      "tx_hash": null,
      "type": "btc_withdrawal_data"
    }
  }
}

Generate a new withdrawal request for a requested currency and amount.

HTTP Request

POST /currencies/<currency>/withdrawals

Path Parameters

Parameter Description
currency Acronym of the currency being withdrawn

Request Payload

Key Required Description
amount Yes Withdrawal size
withdrawal_data: target_address Yes Withdrawal target address
amount_includes_fee No Determines if the withdrawal fee should be subtracted from the withdrawal amount
simulate No Allows you to simulate withdrawal request

Response Details (JSON)

Key Type Description
id [int] Withdrawal ID
created_at [time] Creation timestamp
amount [amount, currency] Amount requested for withdrawal
currency [currency] Currency for withdrawal
fee [amount, currency] Fee incurred by withdrawal
state [string] Request current state (For example: confirmed, rejected)
withdrawal_data [object] Object with withdrawal data
withdrawal_data: type [string] Type of data provided (For example: btc_withdrawal_data,fiat_withdrawal_data)
withdrawal_data: target_address [address] Withdrawal target address
withdrawal_data: tx_hash [string] Transaction ID

New Lightning Withdrawal ⚡️

import requests

url = f'https://www.buda.com/api/v2/reserves/ln-btc/withdrawals'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'amount': 0.0022704,
    'withdrawal_data': {
        'payment_request': 'lnbc227040n1pdmvkw6pp5x7ws3aygr96w75l9z4qmw7z5n8s3ukkcfzmcegkjndlz9pm9fldqdq6ga6kjmrvv4ex6meqf4hhyetwducqzyswf2ey2yv92msm40rzy5wvcpd6t26smjk6k38wtj5gcl65jwttw7pezx8wrsl4h8qn852ltmtg32s8vmkchvt000n3wc6de22mmqtg6qqu7mpr6',
    },
})
print(response.json())

{
  "withdrawal": {
    "id": null,
    "amount": ["0.0022704", "BTC"],
    "created_at": "2017-04-26T13:47:42.000Z",
    "currency": "BTC",
    "fee": ["0.0", "BTC"],
    "state": "confirmed",
    "withdrawal_data": {
      "payment_request": "lnbc227040n1pdmvkw6pp5x7ws3aygr96w75l9z4qmw7z5n8s3ukkcfzmcegkjndlz9pm9fldqdq6ga6kjmrvv4ex6meqf4hhyetwducqzyswf2ey2yv92msm40rzy5wvcpd6t26smjk6k38wtj5gcl65jwttw7pezx8wrsl4h8qn852ltmtg32s8vmkchvt000n3wc6de22mmqtg6qqu7mpr6",
      "type": "lightning_network_withdrawal_data"
      'payment_error': "Description about payment error, if any."
    }
  }
}

Pay a Lightning Network Invoice ⚡️

This endpoint enables you to pay for services using Bitcoin through this network. You can check Mainnet lightning network stores for a list of available services.

Keep in mind that to pay through the Lightning Network you first need to request a payment Invoice from the receiver.

HTTP Request

POST /reserves/ln-btc/withdrawals

Request Payload

Key Required Description
amount Yes Payment amount (in BTCs)
withdrawal_data: payment_request Yes Lightning Network Invoice
simulate No Allows you to simulate payment request

Response Details (JSON)

Key Type Description
id [int] Withdrawal ID
created_at [time] Creation timestamp
amount [amount, currency] Amount requested for withdrawal
currency [currency] Currency for withdrawal
fee [amount, currency] Fee incurred by withdrawal
state [string] Request current state (For example: confirmed, rejected)
withdrawal_data [object] Object with withdrawal data
withdrawal_data: type [string] It will always say lightning_network_withdrawal_data
withdrawal_data: payment_request [address] Invoice used
withdrawal_data: payment_error [string] In case there is an error it will be shown here

New Lightning Deposit ⚡️

import requests

url = f'https://www.buda.com/api/v2/lightning_network_invoices'
auth = BudaHMACAuth(api_key, secret)
response = requests.post(url, auth=auth, json={
    'amount_satoshis': 5000,
    'currency': 'BTC',
    'memo': 'Un computador'
})
print(response.json())

{
  "lightning_network_invoice": {
    "id": 10000,
    "currency": "BTC",
    "encoded_payment_request": 'lnbc227040n1pdmvkw6pp5x7ws3aygr96w75l9z4qmw7z5n8s3ukkcfzmcegkjndlz9pm9fldqdq6ga6kjmrvv4ex6meqf4hhyetwducqzyswf2ey2yv92msm40rzy5wvcpd6t26smjk6k38wtj5gcl65jwttw7pezx8wrsl4h8qn852ltmtg32s8vmkchvt000n3wc6de22mmqtg6qqu7mpr6'
  }
}

Create a Lightning Network Invoice ⚡️

You can use this endpoint to request a Bitcoin payment using this network. Send this invoice to whoever you want.

HTTP Request

POST /lightning_network_invoices

Request Payload

Key Required Description
amount_satoshis Yes Invoice amount in satoshis.
currency Yes Must be BTC
memo No Invoice brief description
expiry_seconds No Invoice expiry time in seconds

Response Details (JSON)

Key Type Description
id [int] Invoice ID
currency [time] Invoice currency
encoded_payment_request [string] Encoded invoice

Rate Limits

We take some precautions to protect ourselves from DoS attacks or abuse of our API. This is done to ensure that our service is stable for all our users.

If your request reaches our limit, you will receive a response with the 429 code, and you must wait before trying again.

These limits are calculated in 1 minute and 1 second intervals. For 1 second intervals, as long as you do less than 20 requests/second you should not trigger our limit.

General

Anonymous (unauthenticated) calls will be limited by IP address at a rate of 120 requests/minute. Authenticated calls will be limited by api key at a rate of 220 requests/minute.

Trading (placing and canceling orders)

The endpoints used to create and cancel orders are limited by account at a rate of 40 orders/minute.

Errors

We do our best to adhere to the HTTP error conventions. If an error occurs, our API sends a JSON object containing more details.

Example error response (HTTP 403):

{
  "code": "forbidden",
  "message": "You dont have access to this resource"
}

Here is a more detailed explanation of HTTP errors you may encounter while using our API:

HTTP Code Explanation
400 Bad Request -- The request has an incorrect syntaxis. If you are making a POST request, be sure you are sending a JSON object in the body, and using the Content-Type: application/json header.
401 Unauthorized -- Your API Key has expired or is not authenticating in the correct format.
403 Forbidden -- The request is valid, but you don't have the required permission for this action.
404 Not Found -- Resource not found. Checck URL you are requesting.
405 Method Not Allowed -- The method received in the request-line is incorrect (for example: using GET instead of POST).
406 Not Acceptable -- You have requested an unsupported format. Check that your header's Accept paramter is requesting JSON format (Accept: application/json).
410 Gone -- The resource being requested is no longer available.
422 Unprocessable entity -- You have sent information in an unsupported format. Check that the object you are sending as body in the POST request is in line with the documentation. (for example: Most of the strings that you must send are case-sensitive).
429 Too Many Requests -- You have surpassed our Rate Limits
500 Internal Server Error -- There has been a problem with our server and are doing our best to fix it 🔥. Please try again later.
503 Service Unavailable -- We are temporarily out of service due to maintenance. Please try again later.

Websockets API

Introduction

WebSockets allow you to open channels between client and server, so that you can stream data in real-time. With this API you can communicate with our server and receive responses based on events, instead of having to constantly query.

We currently use Nchan for this real-time communication. You can find more information on how Nchan works with WebSockets at https://nchan.io/#subscriber-endpoints.

To access the authenticated WebSockets, you will need your pubsub_key, which can be found using the account information endpoint.

Our WebSocket's URLs usually have this format:

wss://realtime.buda.com/sub?channel=[channel]

For cases where authentication is required, they are formed like this:

wss://realtime.buda.com/sub?channel=[channel]@[pubsub_key]

Where:

Parameter Value
channel Channel to be used
pubsub-key Account's PubSub key

Public Channels

Order Book

import websocket

def on_message(ws, message):
    print(message)

def on_open(ws):
    print('web-socket connected.')

if __name__ == "__main__":
    SOCKET = "wss://realtime.buda.com/sub?channel=book%40btcclp"
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(SOCKET, on_message = on_message)
    ws.on_open = on_open
    ws.run_forever(ping_interval=10)

This channel's events have the following structure:

{
  ev: 'book-changed',
  change: [
    'asks'|'bids',
    <price level>,
    <amount change>
  ]
}

{
  ev: 'book-sync',
  order_book: <serialized order book>
}

Subscribe to the order book channel. A complete snapshot of the order book is sent every 5 minutes.

Channel endpoint

[email protected]<market_id>

Path Parameters

Parameter Description
market_id Market ID (for example: btcclp, ethbtc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

Public Trades

import websocket

def on_message(ws, message):
    print(message)

def on_open(ws):
    print('web-socket connected.')

if __name__ == "__main__":
    SOCKET = "wss://realtime.buda.com/sub?channel=trades%40btcclp"
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(SOCKET, on_message = on_message)
    ws.on_open = on_open
    ws.run_forever(ping_interval=10)

This channel's events have the following structure:

{
  ev: 'trade-created',
  trade: [
    <timestamp>,
    <traded amount>,
    <traded price>,
    'buy'|'sell',
    <id>
  ]
}

Subscribe to the public trades history channel.

Channel endpoint

[email protected]<market_id>

Path Parameters

Parameter Description
market_id Market ID (for example: btcclp, ethbtc, etc).
You can obtain a complete list of all markets by calling the Markets endpoint.

Event Details

Key Description
ev Event name
timestamp Unix timestamp of most recent trade
amount Most recent traded amount
price Most recent traded price

Private Channels

Balances

import websocket

def on_message(ws, message):
    print(message)

def on_open(ws):
    print('web-socket connected.')

if __name__ == "__main__":
    SOCKET = "wss://realtime.buda.com/sub?channel=balances%40{pubsub_key}"
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(SOCKET, on_message = on_message)
    ws.on_open = on_open
    ws.run_forever(ping_interval=10)

This channel's events have the following structure:

{
 ev: 'balance-updated',
 order: <serialized balance>
}

Subscribe to the balance change channel.

Channel endpoint

[email protected]<pubsub_key>

Path Parameters

Parameter Description
pubsub_key Account's PubSub key, which can be found in account information.

My Orders

import websocket

def on_message(ws, message):
    print(message)

def on_open(ws):
    print('web-socket connected.')

if __name__ == "__main__":
    SOCKET = "wss://realtime.buda.com/sub?channel=orders%40{pubsub_key}}"
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(SOCKET, on_message = on_message)
    ws.on_open = on_open
    ws.run_forever(ping_interval=10)

This channel's events have the following structure:

{
 ev: 'order-created'|'order-updated',
 order: <serialized order>
}

Subscribe to the order change channel.

Channel endpoint

[email protected]<pubsub_key>

Path Parameters

Parameter Description
pubsub_key Account's PubSub key, which can be found in account information.

Latest changes

May 30 2022

March 17 2022

February 17, 2022