xbullion API (v1.0)

Overview

This documentation describes the rules by which your applications can interact with xbullion via our API (Application Programming Interface). Use of the API must abide by xbullion's Token Terms of Sale for both GOLD & SILV.

The documentation also includes information providing guidance on how to interpret the response to your request, and example code for retrieving specific information from the server.

Intended use of the xbullion API is to allow clients to:

Important guidelines:
The API has both public and authenticated endpoints. Public endpoints are accessible to anyone i.e. no account or credentials are required, whereas Authenticated endpoints require the user to provide a valid access token. Endpoints can be retrieved using different methods such as a cURL entered in your browser, or running code – examples of both are provided in the documentation.

When placing an order, the minimum quantity is 0.00000001. The price precision for all endpoints is up to five significant digits e.g. 0.7249 or 14.378.

Regarding authentication, the following details are important to note.

Request formulation:
Requests to the API will always consist of the url of the endpoint you are accessing, as well as the header of your request. For some endpoints, a request payload is also required.

The base url for all endpoints is https://api.prod.xbullion.io. This is pre-pended to the path url listed in the documentation for a specific request. As an example, the url to test connectivity to the server is /api/v1/ping. Pre-pending the base url to the path url gives a complete url of https://api.prod.xbullion.io/api/v1/ping
NOTE: The ‘order’ and ‘quote’ endpoints have a trailing slash in the path url i.e. https://api.prod.xbullion.io/api/v1/order/, which must be present in order for a response to be received.

If additional path parameters are listed in the documentation of an endpoint, these are to be appended to the full request url. E.g., retrieving data on a specific order, with order_id = a1b2c3, the complete url becomes: https://api.prod.xbullion.io/api/v1/order/a1b2c3.

The header of your request must include the key:value pair of ‘accept’: ‘application/json’ to specify content type. Your access token will also need to be included in the header object, if retrieving data from an authenticated endpoint.

For endpoints requiring a payload, a body object will need to be included in the request, with the key:value pairs specified. The request body schema is application/json. Query parameters are also specified in the documentation of some endpoints, which will need to be included as a params object in your request.
NOTE: The parameters for a request (symbols, side etc.) are case-sensitive (‘GOLDUSD’ ≠ ‘goldusd’) and only uppercase inputs will be accepted.

Responses:
Successful requests return a 200 or 201 HTTP status code. Requests that generate errors return 4xx or 5xx status codes. More information on error codes is provided below, to assist with debugging.

Code
Status
Description
400
Bad Request
Invalid request or format
401
Unauthorized
Invalid authentication credentials
403
Forbidden
Access to the requested resource is not permitted
404
Not Found
Resource could not be located
422
Unprocessable Entity
Request format is valid, but the request did not succeed
500
Internal Server Error
Unexpected server error - not necessarily indicative of a faulty request

Public Endpoints

Public endpoints do not require authentication, so are limited in scope of what can be accessed:

Ping

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/ping"
response = (requests.get(url)).json()
print(response)
# Response = {'status': 'Success', 'msg': 'OK'}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/ping' \
-H 'accept: application/json'
Try it out →

Response samples

Content type
application/json
{
"status": "string",
"msg": "string"
}

Get Time

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/time"
response = (requests.get(url)).json()
print(response)
# Response = {'status': 'Success', 'msg': 'OK', 'data': '1632353645'}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/time' \
-H 'accept: application/json'
Try it out →

Response samples

Content type
application/json
{
"status": "string",
"msg": "string"
"data": "string"
}

Private Endpoints

Authenticated endpoints require the user to provide a valid access token, and hence allows broader access, including retrieving/updating account information, creating/cancelling orders and retrieving symbol orderbooks and quotes.

To generate your individualised access token, post a login access token request. If successful, your OAuth2 compatible token will be returned, similar to:
Bearer ebJhbAciOjJIUzI1NiIsInR5cCI8IkpXVCJ9.eyJleHAiOjE2MzI0MDA4MzEsInN1YiI6IjkifQ.taf5KHPeHrBBFc-3eRcG6AZyUrceU05-UzBkgbah7hk
Incorporate your token into the HTTP header as a key:value pair for all future authenticated calls to the API i.e. ‘Authorization’ : ‘Bearer <your-access-token>’. This will grant you permission to access any of the authenticated endpoints.

Once authenticated, you can send a request to get a new api key. A successful request will return a string resembling: "fUisFvdurFOrc--P5co69MB4p3a", which in any future authenticated requests, you can include in the HTTP header as the key:value pair {"X-Access-Token": "your_api_key"} instead of the OAuth2 token.

Login Access Token

Request Body Schema: application/x-www-form-urlencoded
Parameter
Type
Required
Default
Description
username
string
Yes
-
Account username
password
string
Yes
-
Account password
grant_type
string
No
-
scope
string
No
""
client_id
string
No
-
client_secret
string
No
-
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/login/access-token"
headers = {'accept': 'application/json'}
body = {'username': "example@email.com", 'password':"pwd"}
response = (requests.post(url, headers=headers, data=body)).json()
print(response)
# Response = {'access-token': '<your-access-token>', 'token-type': 'bearer'}
curl -X 'POST' \
'https://api.prod.xbullion.io/api/v1/login/access-token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \  
-d 'grant_type=&username=un&password=pwd&scope=&client_id=&client_secret='
Try it out →

Response samples

Content type
application/json
{
"access_token": "string",
"token_type": "string"
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Test Token

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/login/test-token"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.post(url, headers=headers)).json()
print(response)
# Response = {'status': 'Success', 'msg': 'User has valid token'}
curl -X 'POST' \
'https://api.prod.xbullion.io/api/v1/login/test-token' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>' \  
-d ''
Try it out →

Response samples

Content type
application/json
{
"status": "string",
"msg": "string"
}

New API Key

Query Parameters
Parameter
Type
Required
Default
Description
never_expire
boolean
Yes
False
Whether the new key will ever expire
expire_days
int
Yes
90
How many days until  key expires (If never_expire is True, is ignored)
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/apikey/new"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.get(url, headers=headers)).json()
print(response)
# Response = {'api_key': 'yourKey', 'api_key_is_active': True, 'api_key_never_expire': False, 'api_key_expiration_date': ['2022-09-10T02:30:12'], 'message': 'created'}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/apikey/new?never_expire=false&expire_days=90' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"api_key": "string",
"api_key_is_active": True,
"api_key_never_expire": False, "api_key_expiration_date": [null],
"message": "string"}

}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Revoke API Key

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/apikey/remove"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.get(url, headers=headers)).json()
print(response)
# Response = {'api_key': 'null', 'api_key_expiration_date': '2022-09-10T02:30:12', 'api_key_is_active': False, 'message': 'revoked'}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/apikey/remove' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"api_key": null,
"api_key_expiration_date": "string"
"api_key_is_active": false,  
"message": "string"}

}

Renew API Key

Request Body Schema: application/json
Parameter
Type
Required
Default
Description
api_key
string
No
-
The API key to renew
expire_days
int
Yes
1
The new expiration date in ISO format
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/apikey/renew"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
body = {'expire_days': 5}
j = json.dumps(body)
response = (requests.put(url, headers=headers, data=j)).json()
print(response)
# Response = {'api_key_is_active': True, 'api_key_expiration_date': '2022-09-06T03:06:07', 'message': 'renewed'}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/apikey/renew?expire_days=5' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"api_key_is_active": True,
"api_key_expiration_date": [null],
"message": "string"}

}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Read User Information

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/user"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.get(url, headers=headers)).json()
print(response)
# Response = {'email': example@email.com', 'full_name': 'John Smith', 'customer_name': John, 'id': 1, 'tradable_instruments': ['GOLDUSD', 'SILVUSD']}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/user' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"email": "user@example.com",
"full_name": "string",
"customer_name": "string",
"id": 0,
"tradable_instruments": [null]

}

Update User

Request Body Schema: application/json
Parameter
Type
Required
Default
Description
full_name
string
No
-
New username
email
string
No
-
New email
customer_name
string
No
-
New customer name
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/user"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
body = {'full_name': "John Smith", 'customer_name': "john"}
j = json.dumps(body)
response = (requests.put(url, headers=headers, data=j)).json()
print(response)
# Response = {'email': example@email.com', 'full_name': 'John Smith', 'customer_name': john, 'id': 1, 'tradable_instruments': ['GOLDUSD', 'SILVUSD']}
curl -X 'PUT' \
'https://api.prod.xbullion.io/api/v1/account/user' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \  
-d '{"full_name": "John Smith", "email": "example@email.com",  "customer_name": "john"}'
Try it out →

Response samples

Content type
application/json
{
"email": "user@example.com",
"full_name": "string",
"customer_name": "string",
"id": 0,
"tradable_instruments": [null]
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Update Password

Query Parameters
Parameter
Type
Required
Default
Description
password
string
Yes
-
New password
import requests
import json
url = 'https://api.prod.xbullion.io/api/v1/account/user/password'
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
params = {"password": 'new_password'}
response = (requests.put(url, headers=headers, params=params)).json()
print(response)
# Response = {'status': 'Success', 'msg': 'Password Updated'}
curl -X 'PUT' \
'https://api.prod.xbullion.io/api/v1/account/user/password?password=new_password' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"status": "string",
"msg": "string"
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Get User Balance

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/balance"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.get(url, headers=headers)).json()
print(response)
# Response = {'SILV': {'locked': 0, 'available': 1.0}, 'USD': {'locked': 0, 'available': 0}}
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/user' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
null

Get User Ledger Entries

Query Parameters
Parameter
Type
Required
Default
Description
skip
int
No
0
Number of entries to skip
limit
int
No
100
Number of entries to retrieve
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/account/ledger"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
params = {"limit": 50}
response = (requests.get(url, headers=headers, params=params)).json()
print(response)
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/account/ledger?skip=0&limit=50' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
[
{"amount": 0,
"asset": "string",
"from_account": "string",
"note": "string",
"to_account": "string",
"id": 0,
"createddate": "2019-08-24T14:15:22Z",
"customer_id": 0,
"transaction_id": "string",
"updateddate": "2019-08-24T14:15:22Z"}
]
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Get Orders

Query Parameters
Parameter
Type
Required
Default
Description
skip
int
No
0
Number of orders to skip
limit
int
No
100
Number of orders to retrieve
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/order/"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
params = {"limit": 50}
response = (requests.get(url, headers=headers, params=params)).json()
print(response)
# Response = [
{'createddate': '2021-09-22T11:09:14.461806+00:00', 'order_id': 'd723ae36-c2a3-49fc-b4df-3279021f64d3''order_type': 'MARKET', 'qty': 1.0, 'side': 'BUY', 'status': 'FILLED', 'symbol': 'SILVUSD', 'updateddate': '2021-09-22T11:09:21.610711+00:00', 'average_price': 0.7332, 'executed_qty': 1.0, 'message': None, 'total_cost': 0.73}
]

curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/order/?skip=0&limit=50' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
[
{"createddate": "2019-08-24T14:15:22Z",
"order_id": "string",
"order_type": "string",
"qty": 0,
"side": "string",
"status": "string",
"symbol": "string",
"updateddate": "2019-08-24T14:15:22Z",
"average_price": 0,
"executed_qty": 0,
"message": "string",
"total_cost": 0}
]
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Create Order

Request Body Schema: application/json
Parameter
Type
Required
Default
Description
order_type
string
Yes
-
The type of order. Options are: ‘MARKET’
qty
int
Yes
-
The quantity of the symbol (min. is 1)
side
string
Yes
-
The side of the orderbook. Options are: ‘BUY’,‘SELL’
symbol
string
Yes
-
The symbol for which the order is to be placed. Options are: ‘GOLDUSD’,‘SILVUSD’
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/order/"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
body = {'order_type': "MARKET", 'qty': 1, 'side': "BUY", 'symbol': "GOLDUSD"}
j = json.dumps(body)
response = (requests.post(url, headers=headers, data=j)).json()
print(response)
curl -X 'POST' \
'https://api.prod.xbullion.io/api/v1/order/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \  
-d '{"order_type": "MARKET", "qty": 1, "side": "BUY", "symbol": "GOLDUSD"}'
Try it out →

Response samples

Content type
application/json
{
"createddate": "2019-08-24T14:15:22Z",
"order_id": "string",
"order_type": "string",
"qty": 0,
"side": "string",
"status": "string",
"symbol": "string",
"updateddate": "2019-08-24T14:15:22Z"
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Read Order By ID

Path Parameters
Parameter
Type
Required
Default
Description
order_id
string
Yes
-
Order ID for the order to be retrieved
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/order/"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
order_id = "d123ab12-c1a1-49fc-b4df-3389021f64d6"
full_url = url + "/" + order_id
response = (requests.get(full_url, headers=headers)).json()
print(response)
# Response =
{'createddate': '2021-09-22T11:09:14.461806+00:00', 'order_id': 'd723ae36-c2a3-49fc-b4df-3279021f64d3''order_type': 'MARKET', 'qty': 1.0, 'side': 'BUY', 'status': 'FILLED', 'symbol': 'SILVUSD', 'updateddate': '2021-09-22T11:09:21.610711+00:00', 'average_price': 0.7332, 'executed_qty': 1.0, 'message': None, 'total_cost': 0.73
}

curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/order/d723ae36-c2a3-49fc-b4df-3389021f64d6' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"createddate": "2019-08-24T14:15:22Z",
"order_id": "string",
"order_type": "string",
"qty": 0,
"side": "string",
"status": "string",
"symbol": "string",
"updateddate": "2019-08-24T14:15:22Z",
"average_price": 0,
"executed_qty": 0,
"message": "string",
"total_cost": 0
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Get Instruments

Parameters: None

import requests
import json
url = "https://api.prod.xbullion.io/api/v1/instrument/"
headers = {'accept': 'application/json', 'Authorization':'Bearer <access-token>’}
response = (requests.get(url, headers=headers)).json()
print(response)
# Response = [
{'base_asset': 'GOLD', 'order_sides': ['BUY', 'SELL'], 'order_time_in_force': ['IOC'], 'order_types': ['MARKET'], 'price_precision': 4, 'qty_max_trade_size': 5000, 'qty_min_trade_size': 1, 'qty_precision': 2, 'quote_asset': 'USD', 'symbol': 'GOLDUSD', 'total_cost_precision': 2},

{'base_asset': 'SILV', 'order_sides': ['BUY', 'SELL'], 'order_time_in_force': ['IOC'], 'order_types': ['MARKET'], 'price_precision': 4, 'qty_max_trade_size': 5000, 'qty_min_trade_size': 1, 'qty_precision': 2, 'quote_asset': 'USD', 'symbol': 'SILVUSD', 'total_cost_precision': 2}
]
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/instrument/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
[
{
"base_asset": "string",
"order_sides": ["string"],
"order_time_in_force": ["string"],
"order_types": ["string"],
"price_precision": 0,
"qty_max_trade_size": 0,
"qty_min_trade_size": 0,
"qty_precision": 0,
"quote_asset": "string",
"symbol": "string",
"total_cost_precision": 0
}
]

Get Orderbook Market Data

Path Parameters
Parameter
Type
Required
Default
Description
symbol
string
Yes
-
The symbol for which the orderbook will be retrieved. Options are: ‘GOLDUSD’,‘SILVUSD’
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/orderbook"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
symbol = "GOLDUSD"
full_url = url + "/" + symbol
response = (requests.get(full_url, headers=headers)).json()
print(response)
curl -X 'GET' \
'https://api.prod.xbullion.io/api/v1/orderbook/GOLDUSD' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>'
Try it out →

Response samples

Content type
application/json
{
"order_book_id": "string",
"provider_id": "string",
"symbol": "string",
"createddate": "2019-08-24T14:15:22Z",
"updateddate": "2019-08-24T14:15:22Z",
"quotes":
[
{
"condition": "string",
"order_book_id": "string",
"order_book_position": 0,
"price": 0,
"qty_units": "string",
"quote_id": "string",
"side": "string",
"qty": 0,
"updateddate": "2019-08-24T14:15:22Z"
}
]
}
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}

Get Orderbook Quotes

Request Body Schema: application/json
Parameter
Type
Required
Default
Description
symbol
string
Yes
-
The symbol the quote is specific to:
'GOLDUSD', 'SILVUSD'
side
string
Yes
-
The side of the orderbook. Options are: ‘BUY’,‘SELL’
qty
int
Yes
-
The symbol amount
import requests
import json
url = "https://api.prod.xbullion.io/api/v1/quote/"
headers = {'accept': 'application/json', 'Authorization': 'Bearer <access-token>’}
body = {'symbol': "GOLDUSD", 'side': "BUY", 'qty': 1}
j = json.dumps(body)
response = (requests.post(url, headers=headers, data=j)).json()
print(response)
# Response =
{'total_cost': 0, 'average_price': 0, 'qty': 0, 'side': 'BUY', 'status': 'MARKET_CLOSED', 'symbol': 'GOLDUSD', 'createddate': '2021-09-24T21:43:02.768403', 'updateddate': '2021-09-24T21:43:02.768409'}

curl -X 'POST' \
'https://api.prod.xbullion.io/api/v1/quote/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \  
-d '{"symbol": "GOLDUSD", "side": "BUY", "qty": 1}'
Try it out →

Response samples

Content type
application/json
null
Content type
application/json
{
"detail": [
{
"loc": ["string"],
"msg": "string",
"type": "string"
}
]
}