NAVNavbar

shell <python <javascript

Overview

Welcome to the SFOX API!

SFOX offers a REST API, as well as a websocket feed, to access market data, manage your account, and create/cancel orders.

REST Endpoints

Endpoint Description
Production https://api.sfox.com
OHLCV https://chartdata.sfox.com
Sandbox Contact support

Authentication

To authorize, use this code:

# With shell, you can just pass the correct header with each request
$ curl -u "<api token>:" api_endpoint_here
import requests
auth = requests.auth.HTTPBasicAuth("<api_token>", "")
requests.get("api_endpoint_here", auth=auth)

Make sure to replace <api_key> with your API key, and don’t forget the colon in the shell example

SFOX uses API keys to grant access. You can create a new SFOX API key at our developer portal.

The API key should be included in all API requests to the server in the Authorization header that looks like the following:

Authorization: Bearer <api_key>

Account Management

Get Account Balance

$ curl "https://api.sfox.com/v1/user/balance" \
  -u "<api_key>:"
requests.get("https://api.sfox.com/v1/user/balance", auth=requests.auth.HTTPBasicAuth("<api_key>", "")).json()

The above command returns JSON structured like this:

[
  {
    "currency":"btc",
    "balance":0.627,
    "available":0
  },
  {
    "currency":"usd",
    "balance":0.25161318,
    "available":0.23161321
  }
]

Use this endpoint to access your account balance. It returns an array of objects, each of which has details for a single asset.

You will get Balance and Available balance. Balance is your total balance for this asset. Available, on the other hand, is what is available to you to trade and/or withdraw. The difference is amount that is reserved either in an open trade or pending a withdrawal request.

HTTP Request

GET /v1/user/balance

Response Body

Key Description
currency
balance Amount of the currency in an account (available + held)
available Amount of the currency available for trading
held Amount of the currency “on hold”
WalletTypeId ignore

Get Transaction History

curl "https://api.sfox.com/v1/account/transactions?from=0=250&to=1565114130000" \
  -u "<api_key>:"
requests.get(
    "https://api.sfox.com/v1/account/transactions",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
    params={"from": 0, "to": 1565114130000}
).json()

The above command returns JSON structured like this:

[
  {
    'id': 12224191,
    'order_id': '67662454',
    'client_order_id': '',
    'day': '2018-07-29T21:30:10.000Z',
    'action': 'Buy',
    'currency': 'usd',
    'memo': '',
    'amount': -438.34854806,
    'net_proceeds': -438.34854806,
    'price': 465.19547184,
    'fees': 1.53,
    'status': 'done',
    'hold_expires': '',
    'tx_hash': '',
    'algo_name': 'Smart',
    'algo_id': '200',
    'account_balance': 3929.90349381,
    'AccountTransferFee': None
  }
]

Use this endpoint to access your transaction history, including trades and transfers. It returns an array of objects, each of which has details for each individual transaction.

HTTP Request

GET /v1/account/transactions

Query Parameters

Parameter Default Description
from 0 Starting timestamp (in millis)
to utcnow Ending timestamp (in millis)
type Withdraw: ‘Withdraw’,
Deposit: ‘Deposit’,
Charge: ‘Charge’,
Buy: ‘Buy’,
Sell: ‘Sell’,
Unknown: ‘Unknown’,

Response Body

This endpoint returns an array of objects, each of which has the details of the transaction:

Key Example Description
id Transaction ID
order_id Order ID, if applicable
client_order_id The order ID that the client specified when placing an order
day 2019-07-31T17:26:30.000Z The timestamp of the transaction, in ISO8601 format
action Deposit The action, this can be one of “Deposit”, “Withdraw”, “Buy”, “Sell”
currency btc The base currency
memo
amount 0.00262916 Amount of the transaction of the currency
net_proceeds Net amount after fees
price Price per unit of the base currency
fees Amount of fees paid in the transaction
status
hold_expires
tx_hash
algo_name
algo_id
account_balance
AccountTransferFee
Description
wallet_display_id

Request an ACH transfer

SFOX allows users to transfer funds using ACH. First, set up your bank account by navigating to Deposit/Withdraw. Once your account is connected, use this call to initiate the transfer request.

curl "https://api.sfox.com/v1/user/bank/deposit" \
  -H "Authorization: <api_key>" \
  -d "amount=1"
requests.post(
    "https://api.sfox.com/v1/user/bank/deposit",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
    json={"amount": 1}
).json()

The above command returns JSON structured like this:

{
  "tx_status": 0000,
  "success": true
}

HTTP Request

POST /v1/user/bank/deposit

Form/JSON Parameters

Parameter Description
amount The amount you wish to deposit from your bank account

Deposit

List Available Crypto Addresses

List the available crypto asset addresses for deposits to your account.

curl "https://api.sfox.com/v1/user/deposit/address/{currency}" \
  -H "Authorization: <api_key>"
requests.get(
    "https://api.sfox.com/v1/user/deposit/address/{currency}",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
).json()

The above command returns JSON structured list like this:

[
    {
      "address": "<address>",
      "currency": "<currency>"
    },
    {
        "address": "<address>",
        "currency": "<currency>"
    }
]

HTTP Request

GET /v1/user/deposit/address/{currency}

Response Body

This returns a list of available addresses to deposit crypto assets

key description
address Crypto address to use for deposits
currency Crypto asset

Create a Deposit Address

Generate a new deposit address for the crypto asset of your choosing

Create a new address

curl "https://api.sfox.com/v1/user/deposit/address/{currency}" \
  -H "Authorization: <api_key>" \
  -X POST
requests.post(
    "https://api.sfox.com/v1/user/deposit/address/{currency}",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
).json()

HTTP Request

POST /v1/user/deposit/address/{currency}

Form Parameters

Parameter Description
currency Currency of choice: btc, bch, eth, ltc, bsv, etc

Response Body

Key Description
address Created crypto address
currency Crypto asset

Withdraw

Initiate a withdrawal from your SFOX account.

curl "https://api.sfox.com/v1/user/withdraw" \
  -H "Authorization: <api_key>" \
  -d "amount=1" \
  -d "address=" \
  -d "currency=usd"
requests.post(
    "https://api.sfox.com/v1/user/withdraw",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
    json={
        "amount": 1,
        "address": "<address if crypto>",
        "currency": "<currency>"
    }
).json()

The above command returns JSON structured like this:

{
  "success": true
}

HTTP Request

POST /v1/user/withdraw

Form/JSON Parameters

Parameter Description
amount The amount you wish to withdraw
currency Currency is one of: usd, btc, eth
address If the “currency” is a crypto asset, this field has to be a valid mainnet address. Otherwise leave it out or empty

Post-Trade Settlement


    $ curl "https://api.sfox.com/v1/post-trade-settlement" \
  -u "<api_key>:"

    requests.get("https://api.sfox.com/v1/post-trade-settlement", auth=requests.
    auth.HTTPBasicAuth("<api_key>", "")).json()

The above command returns JSON structured like this:

{
    "exposure":"1000378.13",
    "available_exposure":1999489.96,
    "exposure_limit":2000000.00,
    "equity": 100221.12,
    "equity_for_withdrawals":8000.42
}

Business Accounts Only

If your account has post-trade settlement enabled, use this endpoint to access your account post-trade settlement data. It returns an object, which has details for each datapoint.

HTTP Request

GET v1/post-trade-settlement

Response Body

Key Description
exposure The current USD value of the amount of credit used
available_exposure The USD value of credit available
exposure_limit The maximum value in USD of credit that may be borrowed
equity The portion of the portfolio owned by you
equity_for_withdrawals The amount of equity that is available for withdrawals

Fetching Whitelist Withdrawal Addresses


  $ curl -X GET \
  -H 'Authorization: Bearer < API_TOKEN >' \
  'https://api.sfox.com/v1/whitelisted-addresses'

Custody Accounts Only

HTTP Request

GET /v1/whitelisted-addresses

Creating Whitelist Withdrawal Addresses


  $ curl -X POST \
  -H 'Content-type: application/json' \
  -H 'Authorization: Bearer < API_TOKEN >' \
  --data '{ "alias": "Satoshis Fund",
          "currency_symbol": "btc",
          "address": "1NLqQmwkGxxQmzS9uwtCGXxbxrcNW4FpYp"}' \
  'https://api.sfox.com/v1/whitelisted-addresses'

Custody Accounts Only

HTTP Request

POST /v1/whitelisted-addresses

Custody Approval Rules

Fetching Account Approval Rules


  $ curl -X GET \
  -H 'Authorization: Bearer < API_TOKEN >' \
  'https://api.sfox.com/v1/approval-rules'
{
    "data": [
      {
        "id": 3,
        "available_approver_count": 2,
        "date_added": "2021-03-17T16:19:47.000Z",
        "required_approvals": 2,
        "rule_type": "WITHDRAW",
        "status": "Pending Approval",
        "threshold": 20
      }
    ]
}

HTTP Request

GET /v1/approval-rules

Creating Approval Rules


  $ curl -X PATCH \
  -H 'Content-type: application/json' \
  -H 'Authorization: Bearer < API_TOKEN >' \
  --data '{ "rule_type":  "WITHDRAW" , "required_approvals":  2 , "threshold":  100 }'  \
  'https://api.sfox.com/v1/approval-rules'

HTTP Request

POST /v1/approval-rules

Expected Request Body:

{"rule_type" , "required_approvals": number, "threshold": number }

Supported rule types: "WITHDRAW", "ADD_ALTER_COLL", or "ALTER_SAFE"

Editing Approval Rules


  $ curl -X PATCH \
  -H 'Content-type: application/json' \
  -H 'Authorization: Bearer < API_TOKEN >' \
  --data '{ "required_approvals":  3 , "threshold":  500 }'  \
  'https://api.sfox.com/v1/approval-rules/1'

HTTP Request

PATCH /v1/approval-rules/:rule-id

Expected Request Body:

{"required_approvals": number, "threshold": number }

Fetching Approval Requests

# Fetches all approvals, both complete and pending


  $ curl -X GET \
  -H Authorization: Bearer < API_TOKEN >' \
  'https://api.sfox.com/v1/approvals'
{
    "data": [
      {
        "approval_id": 1,
        "requested_by_username": "example@email.com",
        "requested_by_uaid": "6ea3fb9e-7797-11eb-aa51-0242ac120002",
        "date_added": "2021-03-03T20:28:41.000Z",
        "status": "Pending",
        "approval_type": "WITHDRAW",
        "required_approvals": 2,
        "received_approvals": 0,
        "action_details": {
          "atx_currency_code": "btc",
          "atx_amount": 5,
          "atx_dest_address": "0x1232131223",
          "threshold": 1
        },
        "approval_responses": {
          "ua_display_id": "3fb9e6ea-7797-11eb-aa51-200020242ac1",
          "username": "collaborator@email.com",
          "approved": true
        }
    ]
}

HTTP Request

GET /v1/approvals

Optional query params:

pending=true|false

By default this route will return all approvals completed and pending. If you supply a query parameter of `pending=true` only pending approvals will be returned.

Responding to Pending Approvals


  $ curl -X POST \
  -H 'Content-type: application/json' \
  -H 'Authorization: Bearer < API_TOKEN >' \
  --data '{ "approve": true}'  \
  'https://api.sfox.com/v1/approvals/1'

HTTP Request

POST /v1/approvals/:id

Expected Request Body:

`{"approve": true | false }`

Orders

Place an Order

You can place eight types of orders, specified by an Algorithm ID. Orders can only be placed if your account has sufficient funds. Once an order is placed, your account funds will be put on hold for the duration of the order. How much and which funds are put on hold depends on the order type and parameters specified.

curl "https://api.sfox.com/v1/orders/buy" \
  -u "<api_key>:" \
  -d "quantity=1" \
  -d "currency_pair=btcusd"
requests.post(
    "https://api.sfox.com/v1/orders/buy",
    auth=requests.auth.HTTPBasicAuth("<api_key>", ""),
    json={
        "quantity": 1,
        "currency_pair": "<currency_pair>"
    }
).json()

The above command returns the same JSON object as the Order Status API, and it is structured like this:

{
  "id": 666,
  "quantity": 1,
  "price": 10,
  "o_action": "Buy",
  "pair": "btcusd",
  "type": "Limit",
  "vwap": 0,
  "filled": 0,
  "status": "Started"
}

HTTP Request

POST /v1/orders/buy or POST /v1/orders/sell

Common Parameters

These parameters are common to all order creation requests. See Special Parameters for exceptions.

Parameter Required? Default Description
quantity Y The quantity to trade. The minimum quantity is 0.001 for crypto-denominated pairs, and price*quantity must be greater than $5 for USD-denominated pairs. Not required for market orders.
currency_pair Y The pair or product to trade in the format: <base currency><quote currency> (i.e. btcusd, ethbtc, usdtusd)
price Y The limit price (Precision: 8 decimal places for crypto, 2 decimal places for fiat). Not required for market orders. Note: the executed price will always be better than or equal to this price; if the market conditions do not allow it, the order will not execute.
algorithm_id N 200 Specifies the algorithm you wish to use to execute the order.
routing_type Y How SFOX will route your order. For more info, see Routing Types.
client_order_id N An optional field that can hold a user-specified ID.

Special Parameters

Some of SFOX’s algorithms require different parameters that define execution.

Parameter Algorithms Default Description
amount Market, IOC, Stop Trailing Stop The amount (quote currency) to spend when buying. Note: required for buy orders using the applicable algorithms – in this case, quantity is not required and is ignored..
interval TWAP 900 The frequency at which TWAP trades are executed (in seconds).
total_time TWAP The maximum time a TWAP order will stay active (in seconds). Must be >= 15 minutes and the interval.
routing_option [Hare, Gorilla] Fast Specify how SFOX will trade your order – choose BestPrice or Fast.
stop_amount OR stop_percent Trailing Stop Set the amount (in USD) or percentage (i.e. 0.1 = 10%) that the trigger price of a trailing stop order will trail the price of an asset
max_slippage Market, Stop, Trailing Stop A risk management parameter that will limit the slippage of an order in basis points (i.e. setting max_slippage to 5 = 0.05%)

Cancel an Order

This endpoint will start cancelling the order specified.

curl "https://api.sfox.com/v1/orders/<order_id>" \
  -u "<api_key>:" \
  -X DELETE
requests.delete(
    "https://api.sfox.com/v1/orders/<order_id>",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

The above command does not return anything. To determine the cancellation status of an order, you will need to poll the Order Status endpoint.

HTTP Request

DELETE /v1/orders/<order_id>

Amend an Order

Use this endpoint to make the following adjustments to the quantity or amount, price, and stop amount or stop percent parameters of an order without canceling the order.

curl "https://api.sfox.com/v1/orders/" \
  -u "<api_key>:" \
  -d "quantity=2" \
  -X  PATCH
requests.patch(
    "https://api.sfox.com/v1/orders/",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

The above command returns an array of Order Status JSON objects structured like this:

{
    "id": 123,
    "quantity": 2,
    "price": 10,
    "o_action": "Buy",
    "pair": "btcusd",
    "type": "Limit",
    "vwap": 0,
    "filled": 0,
    "status": "Started"
  
}

HTTP Request

PATCH v1/orders/<order_id>

Allowed Modifications

Parameter Allowable Modifications Example
quantity/amount Increase the quantity or amount of an order
Amount may only be increased for Stop and Trailing Stop buy orders
Buy $100 of BTC instead of $50
price Buy Orders: Increase limit price
Sell Orders: Decreaselimit pricePrice cannot be modified for Trailing Stop orders
Limit buy at $100 instead of $99

Smart sell at $99 instead of $100

stop_amount/stop_percent Any modification is allowed Trailing stop sell trail amount = $5 instead of $100

Response Body

Successfully amending an order will return the updated order details

Order Status

Get the status and details of an order.

curl "https://api.sfox.com/v1/orders/<order_id>" \
  -u "<api_key>:"
requests.post(
    "https://api.sfox.com/v1/orders/<order_id>",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

The above command returns a JSON object structured like this:

{
  "id": 666,
  "quantity": 1,
  "price": 10,
  "o_action": "Buy",
  "pair": "btcusd",
  "type": "Limit",
  "vwap": 0,
  "filled": 0,
  "status": "Started"
}

HTTP Request

GET /v1/orders/<order_id>

Possible “status” values

Value Description
Started The order is open on the marketplace waiting for fills
Cancel pending The order is in the process of being cancelled
Canceled The order was successfully canceled
Filled The order was filled
Done The order was completed successfully

Get Open Orders

Get a list of your current open orders.

curl "https://api.sfox.com/v1/orders" \
  -u "<api_key>:"
requests.get(
    "https://api.sfox.com/v1/orders",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

The above command returns an array of Order Status JSON objects structured like this:

[
  {
    "id": 666,
    "quantity": 1,
    "price": 10,
    "o_action": "Buy",
    "pair": "btcusd",
    "type": "Limit",
    "vwap": 0,
    "filled": 0,
    "status": "Started"
  },
  {
    "id": 667,
    "quantity": 1,
    "price": 10,
    "o_action": "Sell",
    "pair": "btcusd",
    "type": "Limit",
    "vwap": 0,
    "filled": 0,
    "status": "Started"
  }
]

HTTP Request

GET /v1/orders

Possible “status” values

Value Description
Started The order is open on the marketplace waiting for fills
Cancel pending The order is in the process of being cancelled
Canceled The order was successfully canceled
Filled The order was filled
Done The order was completed successfully

Get Done Trades

Get a list of your completed trades.

curl "https://api.sfox.com/v1/orders/done" \
  -u "<api_key>:"
requests.get(
    "https://api.sfox.com/v1/orders/done",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

The above command returns an array of Order Status JSON objects structured like this:

[
  {
    "id": 666,
    "quantity": 1,
    "price": 10,
    "o_action": "Buy",
    "pair": "btcusd",
    "type": "Limit",
    "vwap": 0,
    "filled": 0,
    "status": "Done"
  },
  {
    "id": 667,
    "quantity": 1,
    "price": 10,
    "o_action": "Sell",
    "pair": "btcusd",
    "type": "Limit",
    "vwap": 0,
    "filled": 0,
    "status": "Done"
  }
]

HTTP Request

GET /v1/orders/done

List Asset Pairs

Get a list of the asset pairs that are currently active for your account.

curl "https://api.sfox.com/v1/markets/currency-pairs" \
  -u "<api_key>:"
requests.get(
    "https://api.sfox.com/v1/markets/currency-pairs",
    auth=requests.auth.HTTPBasicAuth("<api_key>", "")
).json()

Response

{
    "bchbtc": {
        "formatted_symbol": "BCH/BTC",
        "symbol": "bchbtc"
    },
    "bchusd": {
        "formatted_symbol": "BCH/USD",
        "symbol": "bchusd"
    },
    "btcusd": {
        "formatted_symbol": "BTC/USD",
        "symbol": "btcusd"
    }
}

HTTP Request

GET /v1/markets/currency-pairs

Algorithms & Routing Types

Algorithms

SFOX offers a wide range of trading algorithms, as well as two routing types, to optimize your order’s execution. For more details, see SFOX Algorithms.

ID Name Description
100 Market Optimally-routed market order (taker-only)
150 Instant Instantly-settled market order
160 Simple Instantly-settled market order
200 Smart Routing Smart Order Routing–an order to buy or sell an asset at a specific price or better
201 Limit Smart-routed limit order–an order to buy or sell an asset at a specific price or better
301 Gorilla Hidden, smart-routed order, optimized for larger order sizes (maker-only)
302 Tortoise Optimizes order placement on the best-priced liquidity providers (maker-only)API only
303 Hare Smart-routed maker-only order, optimizing order placement at the top of the orderbook for better prices and zero slippage
304 Stop An order to buy or sell an asset once the price of the asset reaches a specified price. When the trigger price is reached, a stop order becomes a market order (taker-only)
305 Polar Bear Hidden, optimally-routed less-aggressive order (taker-only)
306 Sniper Hidden, optimally-routed agressive order (taker-only)
307 TWAP Optimally-routed order for executing portions of an order over a specified period of time and number of intervals at or better than the specified limit price (taker-only)
308 Trailing Stop Trailing stop sell sets the stop price at a fixed amount or percentage below the market price. As the market price rises, the stop price rises by the trail amount/percentage. If the price falls, the stop price doesn’t change, and a market order is submitted when the stop price is hit. “Buy” trailing stop orders are the mirror image of sell trailing stop orders)
309 Immediate-or-Cancel (IOC) An immediate-or-cancel order (IOC) is an order to buy or sell an asset that attempts to execute immediately at or better than the limit price and then cancels any unfilled portion of the order

Routing Types

The routing type defines how SFOX prioritizes different sources of liquidity when executing your order. SFOX always attempts to execute your order at the best available price.

Routing Type Description
NetPrice Routes orders to the best venues for execution by considering both the quoted prices and the fees charged by the trading venues. Orders can be routed to additional OTC trading venues and receive a 10bps discount on the SFOX fee. For more details, see here.

Market Data

Smart Routing Order Estimate

$ curl "https://api.sfox.com/v1/offer/buy?amount=1"
requests.get("https://api.sfox.com/v1/offer/buy", params={"amount": 1}).json()

The result of the calls is something like this:

{
  "quantity":1,
  "vwap":383.00,
  "price":383.21,
  "fees":0.95,
  "total":382.26
}

Get an estimated execution price for the specified quantity of a given asset using SFOX’s Smart Order Routing, as well as related information. Only use this as an estimate – execution is not guaranteed.

HTTP Request

Buy:

GET /v1/offer/buy?amount=1

Sell:

GET /v1/offer/sell?amount=1

Query Parameters

Parameter Required Default Description
amount Y The amount you will be trading (base currency).
pair N btcusd The pair you will be trading.

Response Body

Key Description
quantity Quantity to buy or sell
vwap “Volume Weighted Average Price”, the price the user can expect to receive if the order is executed. Even though the price is $383.21 in this example, you will most likely pay $383 for the entire order. These prices are not guaranteed as the market is always moving.
price Limit price the user must specify when placing the order to achieve the VWAP price at execution
fees Expected fee for executing this order
total Total cost of the order

Candlestick / OHLCV Historical Data

Use this endpoint to access historical, aggregated Open-High-Low-Close-Volume data from all supported liquidity providers and currency pairs

curl "https://chartdata.sfox.com/candlesticks?endTime=1592951280&pair=btcusd&period=60&startTime=1592939280"
requests.get("https://chartdata.sfox.com/candlesticks?endTime=1592951280&pair=btcusd&period=60&startTime=1592939280").json()

The result is an array of OHLCV datapoints:

[
  {
    "open_price":"9654",
    "high_price":"9662.37",
    "low_price":"9653.66",
    "close_price":"9655.73",
    "volume":"6.31945755",
    "start_time":1592939280,
    "pair":"btcusd",
    "candle_period":60,
    "vwap":"9655.70504211",
    "trades":53
  },
  {
    "open_price":"9655.72",
    "high_price":"9663.381",
    "low_price":"9653.8",
    "close_price":"9653.9",
    "volume":"19.78230049",
    "start_time":1592939340,
    "pair":"btcusd",
    "candle_period":60,
    "vwap":"9654.19237263",
    "trades":56
    },
  ...
]

HTTP Request

GET https://chartdata.sfox.com/candlesticks

Query Parameters

Parameter Required Default Description
pair N btcusd The pair you want data for
startTime N The unix timestamp of the first datapoint returned
endTime N The unix timestamp of the last datapoint you want returned
period N The duration of each datapoint or candle in seconds (i.e. period = 60 would return 1-minute candles)

Response Body

Key Description
open_price The price at the start of that period
high_price The highest price reached during that period
low_price The lowest price reached during that period
close_price The price at the end of that period
volume Total volume of the asset traded during that period
start_time The unix timestamp of the beginning of the period
end_time The unix timestamp of the end of the period
pair The trading pair of the data
candle_period The duration of each datapoint in seconds
vwap The volume-weighted average price of the period
trades The total number of trades executed across all liquidity providers during that period

Orderbook

Get the blended L2 orderbook data of our connected exchanges, including the top bids and asks and the location of those bids and asks.

curl "https://api.sfox.com/v1/markets/orderbook/<asset_pair>"
requests.get("https://api.sfox.com/v1/markets/orderbook/<asset_pair>").json()

The result of the calls is an array of bids and asks:

{
  "bids": [
    [
      9458.12,
      1e-08,
      "gemini"
    ],
    [
      9456,
      1,
      "itbit"
    ],
    [
      9453,
      0.73553115,
      "itbit"
    ],
    // truncated
  "asks": [
    [
      9455.55,
      2.03782954,
      "market1"
    ],
    [
      9455.56,
      0.9908,
      "market1"
    ],
    [
      9455.59,
      0.60321264,
      "market1"
    ],
    // truncated
  "market_making": {
    "bids": [
      [
        9447.34,
        2,
        "bitstamp"
      ],
      [
        9452.01,
        0.60321264,
        "market1"
      ],
      [
        9452.31,
        0.47488688,
        "bittrex"
      ],
      [
        9456,
        1,
        "itbit"
      ],
      [
        9458.12,
        1e-08,
        "gemini"
      ]
    ],
    "asks": [
      [
        9458.13,
        2.07196048,
        "gemini"
      ],
      [
        9457.75,
        0.14748797,
        "itbit"
      ],
      [
        9456,
        0.1686167,
        "bittrex"
      ],
      [
        9455.68,
        0.742406,
        "bitstamp"
      ],
      [
        9455.55,
        2.03782954,
        "market1"
      ]
    ]
  },
  "timestamps": {
    "gemini": [
      1572903458537,
      1572903458538
    ],
    "bitstamp": [
      1572903458199,
      1572903458199
    ],
    "itbit": [
      1572903458414,
      1572903458416
    ],
    "bittrex": [
      1572903458517,
      1572903458517
    ],
    "market1": [
      1572903458071,
      1572903458071
    ]
  },
  "lastupdated": 1572903458756,
  "pair": "btcusd",
  "currency": "usd",
  "lastpublished": 1572903458798
}

HTTP Request

The default pair is btcusd

GET /v1/markets/orderbook

However if you want to specify a pair:

GET /v1/markets/orderbook/ethusd

Response Body

Key Description
pair The trading pair
currency The quote currency
asks List of asks, size, and exchange
bids List of the bids, size, and exchange
market_making List of the best bid and ask on each exchange
timestamps A list of exchanges and the latest timestamps of the orderbook
lastupdated Last update of the blended orderbook
lastpublished Last time an orderbook update was published

Websocket Feeds

Connecting

import asyncio

import websockets


async def main(uri):
    async with websockets.connect(uri) as ws:
        # don't forget to subscribe (see below)
        async for msg in ws:
            print(msg)


asyncio.run(main("wss://ws.sfox.com/ws"))
const WebSocket = require('ws');

const ws = new WebSocket('wss://ws.sfox.com/ws');

// don't forget to subscribe (see below)
ws.on('message', function(data) {
    // Do something with data
    console.log(data);
});

Connecting to the SFOX websocket feed gives you access to real-time market data from all supported exchanges.

Endpoint Description
Production wss://ws.sfox.com/ws
Sandbox Contact support

Authentication

Authentication Message

var unsubscribe = {
      "type": "authenticate",
      "apiKey":"<your_api_key>",
  }
ws.send(JSON.stringify(unsubscribe));

Success Response

  {
    "type":"success",
    "sequence":1,
    "timestamp":1611363288098046336
  }

Private websocket feeds require authentication. These commands should be JSON with the following properties

Property Type Command
type string “authenticate”
apiKey string “<your_api_key>”

Subscribing & Unsubscribing

Subscribing

subscribe_msg = {
    "type": "subscribe",
    "feeds": ["ticker.sfox.btcusd"],
}

await ws.send(json.dumps(subscribe_msg))
var subscribeMsg = {
    type: "subscribe",
    feeds: ["ticker.sfox.btcusd"]
}
ws.send(JSON.stringify(subscribeMsg));

Response:

{
    "type":"success",
    "sequence":1,
    "timestamp":1534443719605160397
}

{
    "sequence": 2,
    "recipient": "ticker.sfox.btcusd",
    "timestamp": 1534443725944639261,
    "payload": {
        "amount": 0.0989,
        "exchange": "coinbase",
        "high": 6491.8,
        "last": 6399.99,
        "low": 6200,
        "open": 6269.01,
        "pair": "btcusd",
        "route": "Smart",
        "source": "ticker-info",
        "timestamp": "2018-08-16T18:22:05.909Z",
        "volume": 38541.16966647,
        "vwap": 6358.123642949931
    }
}

Unsubscribing

var unsubscribe = {
      "type": "unsubscribe",
      "feeds": ["ticker.sfox.btcusd"]
  }
ws.send(JSON.stringify(unsubscribe));

Response:

  {
    "type":"success",
    "sequence":30,
    "timestamp":1534440639383033506
  }

Once connected to the SFOX websocket you can subscribe to various public feeds without authenticating by using the subscribe or unsubscribe command. These commands should be JSON with the following properties.

Property Type Description
type string Command you are sending to the websocket (subscribe or unsubscribe)
feeds []string List of the feeds that should be subscribed/unsubscribed to

Message Format

Messages that are sent to the various feeds will be JSON objects with the following similar format.

Property Type Description
sequence int The sequence number that the message was sent in.
recipient string The feed that the message was sent to
timestamp int The timestamp (in microseconds)
payload json The payload parameter will be a JSON message that contains then data

Supported Channels

Public Websocket Channels

Public websocket channels do NOT require authentication. The following public channels offer real-time data from SFOX’s global liquidity network

Channels

Channel Example Description
Orderbooks Net Price
orderbook.net.ethbtcNormal
orderbook.sfox.btcusd
Orderbook channels are of the form orderbook.type.pair. Channels with type sfox will stream the normal, consolidated SFOX orderbook, while type net channels will stream the fee-adjusted orderbook used for the NetPrice routing type.
Trades trades.sfox. i.e. trades.sfox.btcusd Real-time tick data feed of all trades executed on SFOX’s supported exchanges
Ticker ticker.sfox. i.e. ticker.sfox.ltcbtc Receive aggregated 24-hour OHLCV data from all supported exchanges and the last price before each update every 10 seconds. Subscriptions to the ticker feed will receive realtime trades that occur on any of the exchanges that are active on the SFOX platform.

Private Websocket Channels

Private websocket channels require authentication. The following private channels offer real-time account updates.

Channels

Channel Example Description
Balances private.user.balances Real-time account balance updates
Open Orders private.user.open-orders Real-time updates to open orders including order status changes, fills, and more
Post-Trade Settlement private.user.post-trade-settlement Real-time post-trade settlement data updates

Channel Descriptions

Orderbooks

Orderbook channels are of the form orderbook.type.pair. Channels with type sfox will stream the normal, consolidated SFOX orderbook, while type net channels will stream the fee-adjusted orderbook used for the NetPrice routing type.

E.g. orderbook.sfox.btcusd or orderbook.net.ethbtc

Trades

Trade channels are of the form trades.sfox.pair.

E.g. trades.sfox.btcusd

Ticker

Ticker channels are of the form ticker.sfox.pair.

E.g. ticker.sfox.ltcbtc

Channel Descriptions

Ticker

Receive aggregated 24-hour OHLCV data from all supported exchanges and the last price before each update every 10 seconds. Subscriptions to the ticker feed will receive realtime trades that occur on any of the exchanges that are active on the SFOX platform.

Ticker Example

import asyncio
import json

import websockets


async def main(uri):
    async with websockets.connect(uri) as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "feeds": [
                "ticker.sfox.btcusd",
            ],
        }))
        async for msg in ws:
            print(msg)


asyncio.run(main("wss://ws.sfox.com/ws"))
const WebSocket = require("ws");
const ws = new WebSocket("wss://ws.sfox.com/ws");

ws.on("message", function(data) {
    console.log(data);
});

ws.on("open", function() {
    ws.send(JSON.stringify({
        type: "subscribe",
        feeds: [
            "ticker.sfox.btcusd"
        ],
    }));
});

Ticker example message

  {
    "sequence": 2,
    "recipient": "ticker.sfox.btcusd",
    "timestamp": 1534440861543042409,
    "payload": {
      "amount": 0.0092443,
      "exchange": "bitstamp",
      "high": 6491.8,
      "last": 6442.5,
      "low": 6200,
      "open": 6269.01,
      "pair": "btcusd",
      "route": "Smart",
      "source": "ticker-info",
      "timestamp": "2018-08-16T17:34:21.000Z",
      "volume": 36810.02514349,
      "vwap": 6355.319029430
    }
  }

Payload Description

Key Description
amount Last trade quantity
exchange Location of trade
last Last trade price (tick)
high 24 hour high price
low 24 hour low price
open 24 hour open price
pair Crypto asset traded
route disregard
source Data source
timestamp Time of trade
volume 24 hour volume
vwap 24 hour volume-weighted average price

Orderbook

Receive real-time L2 orderbook data

Orderbook Example

import asyncio
import json

import websockets


async def main(uri):
    async with websockets.connect(uri) as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "feeds": [
                "orderbook.sfox.ethbtc",
            ],
        }))
        async for msg in ws:
            print(msg)


asyncio.run(main("wss://ws.sfox.com/ws"))
const WebSocket = require("ws");
const ws = new WebSocket("wss://ws.sfox.com/ws");

ws.on("message", function(data) {
    console.log(data);
});

ws.on("open", function() {
    ws.send(JSON.stringify({
        type: "subscribe",
        feeds: [
            "orderbook.sfox.ethbtc"
        ],
    }));
});

Orderbook Response

  {
    "sequence": 2,
    "recipient": "orderbook.sfox.ethbtc",
    "timestamp": 1534440609281315077,
    "payload": {
        "bids": [
            [
                0.0454916,
                1.519,
                "market2"
            ],
            [
                0.04549109,
                1.182,
                "market2"
            ],
            [
                0.04549086,
                0.21094215,
                "market2"
            ]
            // truncated
        ],
        "asks": [
            [
                0.04564,
                34.1074,
                "gemini"
            ],
            [
                0.04559969,
                4.8245942,
                "bitstamp"
            ],
            [
                0.04556277,
                0.507,
                "market2"
            ]
            // truncated
        ],
        "timestamps": {
            "gemini": [
                1572882771172,
                1572882771176
            ],
            "bitstamp": [
                1572882771112,
                1572882771112
            ],
            "itbit": [
                1572882770106,
                1572882770422
            ],
            "bittrex": [
                1572882769065,
                1572882769115
            ],
            "market1": [
                1572882770515,
                1572882770515
            ]
        },
        "lastupdated": 1534440609168,
        "lastpublished": 1534440609168,
        "pair": "ethbtc",
        "currency": "btc"
    }
  }

Trades

Real-time tick data feed of all trades executed on SFOX’s supported exchanges

Trades Example

import asyncio
import json

import websockets


async def main(uri):
    async with websockets.connect(uri) as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "feeds": [
                "trades.sfox.btcusd",
            ],
        }))
        async for msg in ws:
            print(msg)


asyncio.run(main("wss://ws.sfox.com/ws"))
const WebSocket = require("ws");
const ws = new WebSocket("wss://ws.sfox.com/ws");

ws.on("message", function(data) {
    console.log(data);
});

ws.on("open", function() {
    ws.send(JSON.stringify({
        type: "subscribe",
        feeds: [
            "trades.sfox.btcusd"
        ],
    }));
});

Trades Response

{
  "sequence": 2,
  "recipient": "trades.sfox.btcusd",
  "timestamp": 1572883322244910600,
  "payload": {
    "buyOrderId": "4307737868",
    "exchange": "bitstamp",
    "exchange_id": 1,
    "id": "99960684",
    "pair": "btcusd",
    "price": "9300",
    "quantity": "390419",
    "sellOrderId": "4307754886",
    "side": "sell",
    "timestamp": "2019-11-04T16:02:02.000"
  }
}

Payload Description

Key Description
buyOrderId Order ID of the buy
exchange Location of the trade
exchange_id ID of the trade location
pair Crypto asset traded
price Price of the trade
quantity Quantity traded
sellOrderId Order ID of the sale
side Which side was the taker
timestamp Time of the trade

Balances Example:


{
    "sequence": 6,
    "recipient": "private.user.balances",
    "timestamp": 1611365208455005384,
    "payload": [{
      "currency": "btc",
      "balance": 0,
      "available": 0,
      "held": 0
     }, { 
      "currency": "usd",
      "balance": 3320.55527573,
      "available": 3320.55527573,
      "held": 0
     }, { 
      "currency": "ltc",
      "balance": 9.22257079,
      "available": 9.22257079,
      "held": 0
     }, { 
      "currency": "eth",
      "balance": 8.80064155,
      "available": 8.80064155,
      "held": 0
     }, { 
      "currency": "bch",
      "balance": 0,
      "available": 0,
      "held": 0
     }, { 
      "currency": "rvn",
      "balance": 0,
      "available": 0,
      "held": 0
     }, { 
      "currency": "bsv",
      "balance": 0.59201937,
      "available": 0.59201937,
      "held": 0
     }, { 
      "currency": "etc",
      "balance": 32.59913691,
      "available": 32.59913691,
      "held": 0
    }]
}

Balances

Real-time feed for all balances by currency belonging to the user authenticated API key. The initial snapshot will provide a list of all current balances by currency and then any updates to the balances list will be sent.

Payload Description

Key Description
currency Currency of which the following balances applies
balance Total balance of this currency
available Portion of the balance that is available for trading or withdrawals
held Potion of the balance that is currently on hold and unavailable for trading or withdrawals (i.e. an ACH deposit that has yet to settle)

Post-Trade Settlement Example:


{
    "sequence": 5,
    "recipient": "private.user.post-trade-settlement",
    "timestamp": 1603998101753588121,
    "payload": {
        "enabled": true,
        "equity": 999999999999.99999999,
        "equity_available": 999999999999.99999999,
        "exposure": 0,
        "exposure_available": 100000,
        "exposure_limit": 100000,
    }
}

Post-Trade Settlement

Real-time post-trade settlement data. Feed to show all of the account’s Post-Trade Settlement data belonging to the user authenticated API key. Initial snapshot will provide a list of all post trade settlement data and then any updates to the data list will be sent.

Payload Description

available_exposureUSD value of available creditexposure_limitMaximum USD value that may be borrowed

Key Description
enabled Boolean whether post-trade settlement is enabled on your account
equity Current USD value of your account equity (portion of the portfolio owned by you)
equity_for_withdawals Current USD value of the portion of equity that may be withdrawn from the platform
exposure Current USD value of the amount borrowed

Enterprise

Streaming Quotes

Authentication message:

{
    "type": "authenticate",
    "apiKey": "<your_api_key>",
}

Subscribe message:

{
    "type": "subscribe",
    "feeds": ["private.orderbook.compact.btcusd"],
}

Unsubscribe message:

{
    "type": "unsubscribe",
    "feeds": ["private.orderbook.compact.btcusd"],
}

For Enterprise clients, SFOX offers a customizable compact orderbook of real-time executable quotes. Execution is not guaranteed.

Connecting

Streaming Quotes are accessible from the SFOX websocket feed.

Endpoint Description
Production wss://ws.sfox.com/ws
Sandbox Contact Support

Authenticating and Subscribing

Once connected to the SFOX websocket, you must authenticate with your API key before subscribing to private feeds.

Authentication

Property type Command
type string “authenticate”
apiKey string “your-api-key”

Subscribing/Unsubscribing

Property type Command
type string “subscribe” or “unsubscribe”
feeds []string “your-api-key”

Errors

HTTP Status Codes

The SFOX API communicates error codes through HTTP status codes. The following are the error codes currently in use:

Error Code Meaning
400 Bad Request — Your request was malformed in some way
401 Unauthorized — Your API key is wrong
403 Forbidden — The API key is not authorized for this endpoint
404 Not Found — The specified endpoint could not be found
405 Method Not Allowed — You tried to access a endpoint with an invalid method
406 Not Acceptable — You requested a format that isn’t json
429 Too Many Requests — You have exceeded your request limit
500 Internal Server Error — We had a problem with our server. Try again later.
503 Service Unavailable — We’re temporarially offline for maintanance. Please try again later.

FIX

Fix API

For information on how to implement the FIX protocol please contact support@sfox.com.

Field Value Description
HeartBtInt <=30 Heart beat interval
BeginString FIX.4.4 Only FIX 4.4 is supported
SenderCompID Anything You can provide your own sender comp id and have any number of FIX sessions
TargetCompID SFOX
ResetOnLogon Y

Endpoints

Environment Value Description
Production fix.sfox.com:5001 SSL Required
Staging fix.staging.sfox.com:5001 SSL Required

Supported Tags

Logon – A

Tag Name Required Description
554 Password SSL Required Your API Key (generate one here)

NewOrderSingle – D

21HandlInst (semi-custom)N2 (NetPriceRoutingType: 1 = Rest API default (empty), 2 = NetPrice, 3 = Enterprise

Tag Name Required Default Description
11 ClOrdID Y Client provided order ID, must be unique per-account
55 Symbol Y Trading pair (see: List Asset Pairs)
54 Side Y 1 = Buy, 2 = Sell
40 OrdType Y 1 = Market, 2 = Limit, 3 = Stop, or one of our Algoritm IDs
44 Price Y (except market orders) Limit Price
38 OrderQty Y For limit orders, this is the quantity to trade in the base currency. For Market Sell orders, this is the amount in the base currency.
152 CashOrderQty Y (OrdType = 1 AND Side = 1 or OrdType = 3 (stop) AND Side = 1 (buy)) For market buy orders, this is the amount to spend in the quote currency
59 TimeInForce N 1 (GTC) The lifetime of the order, immediate or cancel (3) and good till cancel (1)
Tag Name Algorithm Required Default Description
20000 StopAmount Trailing Stop (308) N The fixed amount to trail the market price by
20001 StopPercent Trailing Stop (308) N The percentage to trail the market price by (given as a decimal: 10% = 0.1)
20010 Interval TWAP (307) Y The frequency at which TWAP trades are executed (in seconds)
20011 TotalTime TWAP (307) Y The maximimum time a TWAP order will stay active (in seconds). Must be >= 15 minutes (900 seconds) and the interval (tag 20010)
20020 RoutingOption Gorilla (301), Hare (303) Y How SFOX will trade your order, BestPrice or Fast

OrderStatusRequest – H

Tag Name Required Description
11 ClOrdID Y Original ClOrdID when creating the order
790 OrdStatusReqID N Optionally provided value that will be echoed in the response

OrderCancelRequest – F

Tag Name Required Description
11 ClOrdID Y Unique ID of the cancel request
41 OrigClOrdID Y Original ClOrdID provided when creating the order

ExecutionReport – 8

Tag Name Description
37 OrderID SFOX Assigned Order ID, when rejected this will be 0.
17 ExecID SFOX Assigned Trade ID, when rejected this will be 0.
11 ClOrdID Client provided order ID
31 LastPx Last fill price
32 LastQty Last fill quantity
60 TransactTime
55 Symbol Trading pair
54 Side 1 = Buy, 2 = Sell
40 OrdType 1 = Market, 2 = Limit
44 Price Client provided limit price, only if OrdType = 2
150 ExecType Execution type: 0 = New, 4 = Canceled, 8 = Rejected, F = Trade, I = Order Status Request
39 OrdStatus Current status of the order: 0 = New, 1 = Partially Filled, 2 = Filled, 3 = Done, 4 = Canceled, 8 = Rejected
151 LeavesQty Amount remaining of the order
14 CumQty Amount filled so far of the order
799 AvgPx VWAP

OrderCancelReject – 9

Tag Name Description
37 OrderID SFOX Order ID, unless the order is unknown (CxlRejReason = Unknown Order)
11 ClOrdID Client provided order ID of the cancel request
41 OrigClOrdID Client provided order ID of the original order (echoed back from the request)
39 OrdStatus CExisting status of the order that could not be canceled

Market Data Request – V

Tag Name Required Description
262 MDReqID Y Market data request id, this will be included in all Market Data Snapshot Full Refresh updates.
146 NoRelatedSym Y Number of symbols in this request
-> 55 Symbol Y Pair to subscribe to
264 MarketDepth Y Depth of the orderbook
20030 custom N Which marketdata feed: "" – default/standard, "net" – net price, "compact" – compact/enterprise

Market Data Snapshot Full Refresh – W

Tag Name Description
262 MDReqID Market data request id that this is refresh was created by
55 Symbol Pair
268 NoMDEntries Market data request id that this is refresh was created by
-> 269 MDEntryType 0 – Bid, 1 – Ask/Offer
-> 270 MDEntryPx Price
-> 271 MDEntrySize Size/Quantity
-> 275 MDMkt Market of the entry, not applicable to the compacted feed