NAV Navbar
javascript python

Web API

Overview

# Please note that many of the Python examples presented use type
# annotations introduced in Python 3.6. They are easy to remove
# manually if you are using an older version of Python. You could
# also use the strip-hints library to remove the type hints from
# the code.

The information below should be used to help you consume our Web API. This Web API is used for trading on Seed Digital Commodities Market ("SCXM"), Seed SEF ("SCXS") and for trades submitted directly to Zero Hash ("ZERO") for settlement.

URLs

Production

Certification

Public Endpoints

Public endpoints do not require authentication. This information is fundamental to the exchange and publicly available.

Instruments

GET /instruments

const axios = require('axios')

axios.get('https://api.seedcx.com/instruments')
import requests

requests.get('https://api.seedcx.com/instruments')

Sample Response

{
   "message":[
      {
         "code":"COSP:BTC/USD",
         "name":"Bitcoin USD Physical Forward",
         "exchange_mic":"SCXS",
         "asset_class":"Commodity",
         "underlying":"BTC",
         "product_type":"Forward",
         "quoted_currency":"USD",
         "physical_delivery":true,
         "cleared":false,
         "collaterization":"Partially Collateralized",
         "contract_size":1,
         "tick_band":5,
         "minimum_block_size":1,
         "exchange_name":"Seed SEF",
         "exchange_lei":"549300KEYNHAIZ6OWT97",
         "sdr_name":"CME Group",
         "sdr_lei":"LCZ7XYGSLJUHFXXNXD88",
         "id":5,
         "price_decimals":0,
         "market_data":{
            "binary":{
               "incremental":[
                  {
                     "name":"A",
                     "ip":"239.0.0.1",
                     "port":1100
                  },
                  {
                     "name":"B",
                     "ip":"239.0.0.2",
                     "port":1100
                  }
               ],
               "snapshot":[
                  {
                     "name":"private",
                     "ip":"10.4.24.103",
                     "port":65000
                  },
                  {
                     "name":"public",
                     "ip":"10.60.10.15",
                     "port":65000
                  }
               ]
            }
         }
      }
   ]
}

Returns an array of SCXM and SCXS-supported instruments and their definitions. Response parameters listed below.

Parameter Description Type
code The instrument's unique code string
name The instrument's name string
exchange_mic scxm or scxs string
asset_class The asset class of all underlying products is currently Commodity string
underlying Underlying asset code string
product_type Type of product - Spot, Forward, Option string
quoted_currency The currency in which the asset is quoted string
physical_delivery A boolean statement to indicate if the instrument is physically delivered boolean
cleared A boolean statement to indicate if the instrument is centrally cleared, which is relevant for Seed SEF instruments only boolean
collateralization Partially Collateralized string
contract_size The number of units of the underlying product that are traded as per instrument number
tick_band The minimum tick increment number
minimum_block_size The minimum quantity needed to be executed for a block trade in an instrument number
exchange_name Name of the exchange on which the instrument is traded string
exchange_lei Exchange Legal Entity Identifier (LEI) string
sdr_name The name of the Swap Data Repository (SDR) to which trades are reported, which is relevant for Seed SEF instruments only string
sdr_lei The LEI of the SDR number
id Instrument ID number
price_decimals Number of decimals in instrument price number
market_data Array market data connectivity information market_data[]

Code

Refer to our FAQ page for instrument code permutations.

Exchange MIC

The Market Identification Code (MIC) as issued by ISO 10383 Codes for exchanges and market identification (MIC).

Underlying and Quoted Currency

Refer to our FAQ page for supported assets and their codes.

The underlying is the asset being priced. The quoted_currency is the asset in which the underlying is being denominated. For example, with a BTC/USD instrument, BTC would be the underlying and USD would be the quoted_currency as BTC is being priced in USD.

Physical Delivery

This boolean determines if a product is physically or financially-settled.

Currently all instruments on Seed CX are physically-settled.

Collateralization

This indicates the requirements from a margin perspective to open a position in the instrument. Partially Collateralized infers that the instrument is margined, and only a partial value is required.

Currently all instruments on SCXM and SCXS are margined.

Market Data

Within the market_data array, there is a variety of information that is primarily used to connect to Seed CX binary multicast market data feeds. Please refer to the binary market data page for information on how to use fields in the market_data array.

GET /instruments/initial_margin_requirements

const axios = require('axios')

axios.get('https://api.seedcx.com/instruments/initial_margin_requirements')
import requests

requests.get('https://api.seedcx.com/instruments/initial_margin_requirements')

Sample Response:

{
   "message":[
      {
         "instrument_code":"COSP:BTC/USD",
         "margin_price":900
      },
      {
         "instrument_code":"COSP:ETH/USD",
         "margin_price":400
      }
   ]
}

Returns an array of instruments and their initial margin requirements.

Parameter Description Type
instrument_code The instrument's unique code string
margin_price Initial margin requirement number

Initial Margin

Initial margin means the collateral, as calculated in accordance with our margin methodology, that must be collected or posted in connection with opening one contract. It is a US dollar amount, set per instrument, that must be on hand to open a position, and is then set aside during the life of a trade to cover the risk associated with that position.

The total initial margin obligation for a position is tracked in real-time and used to determine credit available for use in trading. Refer to our FAQ page on how our credit system works for more information.

GET /instruments/:instrumentCode/time_and_sales

const axios = require('axios')

axios.get('https://api.seedcx.com/instruments/COSP:BTC%2FUSD/time_and_sales')
import requests

requests.get('https://api.seedcx.com/instruments/COSP:BTC%2FUSD/time_and_sales')

Sample Response

{
   "message":[
      {
         "instrument_code":"COSP:BTC/USD",
         "quantity":2,
         "transact_time":1544038299787,
         "price":3735,
         "side":"buy"
      }
   ]
}

Returns an array of the last 50 trades for an instrument. Response parameters listed below.

Parameter Description Type
instrument_code The instrument's unique code string
quantity Order quantity number
transact_time Time of transaction number
price Order price number
side Side of order, buy or sell string

GET /instruments/:instrumentCode/ohlc

const axios = require('axios')

axios.get('https://api.seedcx.com/instruments/COSP:BTC%2FUSD/ohlc?start=1552953600&end=1554747242&resolution=1D')
import requests

requests.get('https://api.seedcx.com/instruments/COSP:BTC%2FUSD/ohlc?start=1552953600&end=1554747242&resolution=1D')

Returns an instrument's open, high, low, close and volume for the specified timeframe. All three query parameters are mandatory and are listed below.

Parameter Description
start Start time of ohlc in seconds
end End time of ohlc in seconds
resolution Time resolution of ohlc (1M, 5M, 15M, 1H, 6H, 1D)

An annotated response example is below:

[
  [
    1552953600000, // unix timestamp in ms
    3985, // close
    3985, // open
    4010, // high
    3980, // low
    36 // volume
  ],
  [
    1553040000000, // unix timestamp in ms
    null, // close
    null, // open
    null, // high
    null, // low
    null // volume
  ]
]

Time

GET /time

const axios = require('axios')

axios.get('https://api.seedcx.com/time')
import requests

requests.get('https://api.seedcx.com/time')

Sample Response

  {
    "epoch": 1550174574
  }

Return the current unix time of the server in seconds.

Authentication

const crypto = require('crypto')
const request = require('request-promise')


const makeRequest = (
    apiKey,
    apiSecret,
    passphrase,
    host,
    route,
    method,
    body
  ) => {
    // CREATE SIGNATURE
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + method + route + JSON.stringify(body)
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    // Don't forget to base 64 encode your digest
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': apiKey,
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': passphrase
    }

    const derivedMethod = {
      POST: 'post',
      PUT: 'put',
      GET: 'get'
    }[method]

    const options =  {
      headers,
      body,
      json: true
    }

    return request[derivedMethod](`https://${host}${route}`, options)
  }
import hashlib
import hmac
import json
from base64 import b64decode, b64encode
from datetime import datetime
from typing import Any, Dict, Optional
from urllib.parse import urljoin

import requests
from logging import getLogger

logger = getLogger(__name__)

# NB: THESE CREDENTIALS SHOULD NOT BE STORED IN PLAINTEXT
# Keys here are kept in plaintext for the purposes of demonstration
# We encourage you to encrypt your keys and decrypt them only when being used
URL_BASE = 'api.seedcx.com'
HTTP_BASE = 'https://' + URL_BASE
API_PUBLIC_KEY = 'usjHuLksaeBXWSsa8uU7ES'
API_PRIVATE_KEY = '2mC4ZvVd4goRkuJm+rjr9byUiaUW1b6tVN4xy9QXNSE='
PASSPHRASE = 'testingisgreat'


def sign(api_key: str, method: str, route: str, json_body: str, timestamp: str) -> bytes:
    """Given a key and data, create and sign a payload.

    :param api_key: Key to sign the message with
    :param method: HTTP method
    :param route: Relative route. EX. /fills
    :param json_body: JSON as a string. Usually created via json.dumps(dict)
    :param timestamp: Unix Epoch time as a string
    :return: Base64 encoded digest
    """
    msg = bytes(timestamp + method + route + json_body, encoding='utf-8')
    hm = hmac.new(key=b64decode(api_key), msg=msg, digestmod=hashlib.sha256)
    return b64encode(hm.digest())


def headers() -> Dict[str, Any]:
    """Create a header template for use in HTTP requests."""
    return {
        'X-SCX-API-KEY': API_PUBLIC_KEY,
        'X-SCX-SIGNED': '',  # Put here to make sure we alway send something
        # The datetime.timestamp function is available only in Python 3.3+
        'X-SCX-TIMESTAMP': str(int(datetime.now().timestamp())),  # Unix Epoch
        'X-SCX-PASSPHRASE': PASSPHRASE
    }


def make_seed_request(
    method: str, url: str, body: Optional[Dict[str, str]] = None
) -> requests.Response:
    """Create and send an HTTP request with a signature to the Seed API.

    :param method: HTTP method
    :param url: Relative route. EX. /fills
    :param body: Dictionary for serializing into the JSON body of the request. For GET requests,
                 this can be omitted or set to an empty dict. Nothing will be sent, but it is
                 required for the signature.
    :return: requests.Response object
    """
    if body is None:
        body = {}
    h = headers()
    json_body = json.dumps(body, separators=(',', ':'))
    h['X-SCX-SIGNED'] = sign(API_PRIVATE_KEY, method, url, json_body, h['X-SCX-TIMESTAMP'])
    args = {'method': method, 'url': urljoin(HTTP_BASE, url)}
    logger.info('Making {} request to {}'.format(method, urljoin(URL_BASE, url)))
    if body:
        args['data'] = json_body
        h['Content-Type'] = 'application/json'
        logger.debug(json_body)
    args['headers'] = h

    # Since we don't know if it's a GET or POST, use the generic request function and create an
    # args dict so that we can conditionally pass data/JSON
    return requests.request(**args)

Example Headers

{
  "X-SCX-API-KEY": "h2yFu1uijCDEqkbdop4GAF",
  "X-SCX-SIGNED": "PFMlg+bMFVjjAiGPLR/zJCStmiiOIeyz5NIOZEmpfH0=",
  "X-SCX-TIMESTAMP": 1550175822,
  "X-SCX-PASSPHRASE": "passphrase"
}

Seed CX Uses HMAC SHA-256 verification to ensure the authenticity of every API request.

To Authenticate with us, you will need to set the following headers:

Header Description
X-SCX-API-KEY Your public key
X-SCX-SIGNED Signature for your request
X-SCX-TIMESTAMP Unix timestamp
X-SCX-PASSPHRASE Your passphrase

To sign your request:

  1. Concatenate timestamp + method + route + request body

    Example: 1549468233POST/orders{"client_order_id":"abcdefg","instrument_code":"COSP:BTC/USD","market_code":"SCXM","order_type":"limit","price":"3780","quantity":"10","side":"buy"}

  2. Generate an HMAC digest using your private key (using HMAC SHA-256).

    Generating a digest for the above payload with a private key of foo should produce: 8c6186a8be544071dae4ac635dfe91382fcc1842f97fb390202a6836725fa433

  3. Encode the HMAC digest in Base64.

    The above digest should produce: jGGGqL5UQHHa5KxjXf6ROC/MGEL5f7OQICpoNnJfpDM==

Private Endpoints

# The below Python examples make use of the functions defined above.

Positions

GET /positions/desks

const crypto = require('crypto')
const request = require('request-promise')


const getDeskPositions = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/positions/desks' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/positions/desks`, options)
  }
desk_positions = make_seed_request('GET', '/positions/desks', {})

Sample Response

{
   "message":[
      {
         "desk_code":"20QK0COBD",
         "type":"desk",
         "desk_limit":50000,
         "available":48500,
         "initial_margin_obligation":2000,
         "realized_pnl":500,
         "unrealized_pnl":300
      }
   ]
}

Returns an array of your desk's current credit properties due to positions and trading across all instruments. Response parameters listed below.

Parameter Description Type
desk_code Unique desk code string
type Position type, which is always desk from this endpoint string
desk_limit The USD-denominated limit assigned to the desk by an admin number
available Total USD-denominated credit available to a desk for trading number
initial_margin_obligation Total USD-denominated initial margin requirement for all positions in all instruments under a desk number
realized_pnl Total USD-denominated realized P&L across all instruments under this desk number
unrealized_pnl Total USD-denominated unrealized P&L across all instruments under this desk number

Refer to our FAQ page on how our credit system works for more information.

GET /positions/instruments

const crypto = require('crypto')
const request = require('request-promise')


const getInstrumentPositions = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/positions/instruments' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/positions/instruments`, options)
  }
instrument_positions = make_seed_request('GET', '/positions/instruments', {})

Sample Response

{
   "message":[
      {
         "desk_code":"20QK0COBD",
         "instrument_code":"COSP:BTC/USD",
         "type":"instrument",
         "available":48500,
         "initial_margin_obligation":2000,
         "realized_pnl":500,
         "unrealized_pnl":300,
         "average_price_paid":3800,
         "position":2,
         "position_allowance":48,
         "offset_allowance":50,
         "open_buy_order_quantity":15,
         "buy_order_allowance":33,
         "open_sell_order_quantity":0,
         "sell_order_allowance":50
      }
   ]
}

Returns an array of your desk's current credit properties for a specific instrument due to a position and previous activity in that instrument. It also includes information on your order and trading allowances. Response parameters listed below.

Parameter Description Type
desk_code Unique desk code string
instrument_code Unique instrument code string
type Position type, which is always instrument from this endpoint string
available The USD-denominated credit available to a trading desk to trade in a particular instrument number
initial_margin_obligation The USD-denominated margin obligation of a trading desk due to an open position in a particular instrument number
realized_pnl The USD-denominated profit or loss that a desk has realized in a particular instrument through actively closing an open position number
unrealized_pnl The USD-denominated profit or loss that a desk could potentially realize if they closed out their open position in a particular instrument number
average_price_paid The volume-weighted average price that a desk has realized to obtain its current position number
position The current net position a desk has in a particular instrument, with a positive value indicating long position and a negative value indicating a short position number
position_allowance The quantity that a desk can increase its current position by, in the same direction as the current position number
offset_allowance The quantity that a desk can decrease its current position by, in the opposite direction as the current position number
open_buy_order_quantity The sum of all order quantities placed in that instrument on the buy side number
buy_order_allowance The order buy quantity allowed to be submitted by any trader under a trading desk into the order book number
open_sell_order_quantity The sum of all order quantities placed in that instrument on the sell side number
sell_order_allowance The order sell quantity allowed to be submitted by any trader under a trading desk into the order book number

Refer to our FAQ page on how our credit system works for more information.

Orders

GET /orders

const crypto = require('crypto')
const request = require('request-promise')


const getOrders = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/orders' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/orders`, options)
  }
orders = make_seed_request('GET', '/orders', {})

Sample Response

{
   "message":[
      {
         "order_id":"327500000000000026",
         "market_code":"SCXM",
         "exec_id":"327500000000000042",
         "trading_account_code":"WS9U7YYTHGQU",
         "order_type":"limit",
         "exec_type":"new",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545336027435,
         "side":"buy",
         "original_quantity":"10.000000",
         "total_quantity":"10.000000",
         "liquidity_indicator":"added",
         "remaining_quantity":"10.000000",
         "total_filled_quantity":"0.000000",
         "last_filled_quantity":"0.000000",
         "price":"3780.000000",
         "status":"new",
         "reject_reason":""
      }
   ]
}

Returns your open orders on SCXM and SCXS. Response parameters listed below.

Parameter Description Type
order_id ID of open order string
market_code MIC where the order is resting, scxm or scxs string
exec_id ID of open execution report string
trading_account_code Unique trading account code string
order_type market, limit or post-limit string
exec_type new, canceled, rejected, replaced, or trade string
instrument_code Unique instrument code string
transact_time Transaction time number
side Side of fill, buy or sell string
original_quantity Original quantity of order (Deprecated) string
total_quantity Original quantity of order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
remaining_quantity Quantity remaining to be filled string
total_filled_quantity Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of fill string
status new, partially filled, filled, done, canceled, or rejected string
reject_reason A description of the reason for order rejection if status is rejected string

Order Type

To see a full list of supported order types, please refer to our FAQ page.

POST /orders

const crypto = require('crypto')
const request = require('request-promise')
const short = require('short-uuid')


const newOrder = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'POST' + '/orders' + JSON.stringify(body)
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    const body = {
      client_order_id: short.uuid(),
      instrument_code: 'COSP:BTC/USD',
      market_code: 'SCXM',
      order_type: 'post-limit',
      time_in_force: 'day',
      quantity: '1',
      side: 'buy',
      price: '5',
      time_in_force: 'day'
    }

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.post(`https://api.seedcx.com/orders`, options)
  }
from uuid import uuid4

new_order = make_seed_request(
    'POST', '/orders', {
        'client_order_id': uuid4(),
        'instrument_code': 'COSP:BTC/USD',
        'market_code': 'SCXM',
        'order_type': 'post-limit',
        'time_in_force': 'day',
        'quantity': '1',
        'side': 'buy',
        'price': '5'
    }
)

Sample Response

{
   "message":{
      "trading_account_code":"3E1KWLUYNPBQ",
      "client_order_id":"0.06906619",
      "order_id":"333500000000003712",
      "market_code":"SCXM",
      "exec_id":"333500000000021158",
      "order_type":"post-limit",
      "exec_type":"new",
      "instrument_code":"COSP:BTC/USD",
      "transact_time":1550501899018,
      "side":"buy",
      "original_quantity":"1.000000",
      "total_quantity:":"1.000000",
      "liquidity_indicator":"added",
      "remaining_quantity":"1.000000",
      "total_filled_quantity":"0.000000",
      "last_filled_quantity":"0.000000",
      "price":"5.000000",
      "status":"new",
      "reject_reason":""
   }
}

Creates an order. Request parameters listed below.

Parameter Description Type
client_order_id A unique order ID supplied by you string
instrument_code The code of the instrument for which you are submitting an order string
market_code MIC of target exchange, scxm or scxs string
order_type market, limit or post-limit string
price Price of order string
quantity Quantity of order string
time_in_force day, IOC or FOK string
side Side of order, buy or sell string

Once the request is posted, the response is made available. Response parameters listed below.

Parameter Description Type
trading_account_code Unique trading account code string
client_order_id client_order_id supplied by you at order creation string
order_id ID of open order string
market_code MIC of responding exchange, scxm or scxs string
exec_id ID of open execution report string
order_type Type of order string
exec_type Type of execution report string
instrument_code Instrument code string
transact_time Transaction_time number
side Side of order, buy or sell string
original_quantity Original quantity of order (Deprecated) string
total_quantity Original quantity of order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
remaining_quantity Quantity remaining to be filled string
total_quantity_filled Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of order string
time_in_force day, FOK, or IOC string
status Status of order string
reject_reason Reason for rejection string

GET /orders/:order_id

const crypto = require('crypto')
const request = require('request-promise')


const getOrder = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/orders/fd5c084c-ff7c-4651-9a52-37096242d81c' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/orders/fd5c084c-ff7c-4651-9a52-37096242d81c`, options)
  }
specific_order = make_seed_request('GET', '/orders/fd5c084c-ff7c-4651-9a52-37096242d81c', {})

Sample Response

{
   "message":[
      {
         "order_id":"327500000000000039",
         "market_code":"SCXM",
         "exec_id":"327500000000000064",
         "trading_account_code":"WS9U7YYTHGQU",
         "order_type":"limit",
         "exec_type":"new",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545338249442,
         "side":"buy",
         "original_quantity":"10.000000",
         "total_quantity":"10.000000",
         "liquidity_indicator":"added",
         "remaining_quantity":"10.000000",
         "last_filled_quantity":"0.000000",
         "price":"3780.000000",
         "status":"new",
         "reject_reason":""
      }
   ]
}

Gets information about a specific order. Response parameters listed below.

Parameter Description Type
trading_account_code Unique trading account code string
client_order_id client_order_id supplied by you at order creation string
order_id ID of open order string
market_code MIC of exchange, scxm or scxs string
exec_id ID of open execution report string
order_type Type of order string
exec_type Type of execution report string
instrument_code Instrument code string
transact_time Transaction time number
side Side of order, buy or sell string
original_quantity Original quantity of order (Deprecated) string
total_quantity Original quantity of order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
remaining_quantity Quantity remaining to be filled string
total_quantity_filled Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of order string
status Status of order string
reject_reason Reason for rejection string

PUT /orders/:order_id

const crypto = require('crypto')
const request = require('request-promise')


const cancelReplaceOrder = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'PUT' + '/orders/1133224432' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    const body = {
      client_order_id: '0x6906619',
      instrument_code: 'COSP:BTC/USD',
      market_code: 'SCXM',
      order_type: 'limit',
      price: '2780',
      quantity: '100',
      side: 'buy'
    }

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.put(`https://api.seedcx.com/orders/1133224432`, options)
  }
cancel_replace_order = make_seed_request(
    'PUT', '/orders/1133224432', {
        'client_order_id': '0x6906619',
        'instrument_code': 'COSP:BTC/USD',
        'market_code': 'SCXM',
        'order_type': 'limit',
        'price': '2780',
        'quantity': '100',
        'side': 'buy'
    }
)

Sample Response

{
   "message":[
      {
         "trading_account_code":"WS9U7YYTHGQU",
         "client_order_id":"3kdc932ld0s98",
         "order_id":"327500000000000034",
         "original_client_order_id":"f3dk2982l",
         "market_code":"SCXM",
         "exec_id":"327500000000000053",
         "order_type":"limit",
         "exec_type":"replaced",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545337404962,
         "side":"buy",
         "original_quantity":"100.000000",
         "total_quantity":"10.000000",
         "liquidity_indicator":"added",
         "remaining_quantity":"100.000000",
         "total_filled_quantity":"0.000000",
         "last_filled_quantity":"0.000000",
         "price":"2780.000000",
         "status":"new",
         "reject_reason":""
      }
   ]
}

Sends a cancel replace for a specific order to change something about it, e.g. price, quantity, order_type. Request parameters listed below.

Parameter Description Type
client_order_id A unique request id supplied by you
Note: this is not the client_order_id of the order being cancel/replaced
string
instrument_code The code of the instrument for which you are submitting an order string
market_code scxm or scxs - desired market code string
order_type market, limit, or post-limit - indicating type of order string
price Price of order string
quantity Quantity of order string
side buy or sell string

Once the cancel replace is submitted, our response is made available. Response parameters listed below.

Parameter Description Type
trading_account_code Unique trading account code string
client_order_id client_order_id supplied by you in the cancel/replace request string
original_client_order_id original client_order_id supplied in the order create request string
order_id ID of open order string
market_code Market code string
exec_id ID of open execution report string
order_type Type of order string
exec_type Type of execution report string
instrument_code Instrument code string
transact_time Transaction time number
side Side of order string
original_quantity Quantity of the new order that has replaced the previous, now canceled order (Deprecated) string
total_quantity Quantity of the new order that has replaced the previous, now canceled order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
remaining_quantity Quantity remaining to be filled string
total_quantity_filled Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of order string
status Status of order string
reject_reason Reason for rejection string

POST /orders/:order_id/cancel

const crypto = require('crypto')
const request = require('request-promise')


const cancelOrder = () => {
  const timestamp = Math.round(Date.now() / 1000)
  const payload = timestamp + 'PUT' + '/orders/73WakrfVbNJBaAmhQtEeDv/cancel' + '{}'
  const decodedSecret = Buffer.from(apiSecret, 'base64')
  const hmac = crypto.createHmac('sha256', decodedSecret)
  const signedPayload = hmac.update(payload).digest('base64')

  const body = {
    client_order_id: '73WakrfVbNJBaAmhQtEeDv',
    instrument_code: 'COSP:BTC/USD',
    market_code: 'SCXM',
    side: 'buy'
  }

  // SET HEADERS
  const headers = {
    'X-SCX-API-KEY': 'public_key',
    'X-SCX-SIGNED': signedPayload,
    'X-SCX-TIMESTAMP': timestamp,
    'X-SCX-PASSPHRASE': 'passphrase'
  }
  const options =  {
    headers,
    body,
    json: true
  }
  return request.post(`https://api.seedcx.com/orders/73WakrfVbNJBaAmhQtEeDv/cancel`, options)
}
cancel_order = make_seed_request(
    'POST', '/orders/73WakrfVbNJBaAmhQtEeDv/cancel', {
        'client_order_id': '73WakrfVbNJBaAmhQtEeDv',
        'instrument_code': 'COSP:BTC/USD',
        'market_code': 'SCXM',
        'side': 'buy'
    }
)

Sample Response

{
   "message":[
      {
         "trading_account_code":"WS9U7YYTHGQU",
         "client_order_id":"kdl39d0sj2sas",
         "order_id":"327500000000000031",
         "original_client_order_id":"fxlxsx38wo",
         "market_code":"SCXM",
         "exec_id":"327500000000000049",
         "exec_type":"canceled",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545336887676,
         "side":"buy",
         "original_quantity":"10.000000",
         "total_quantity":"10.000000",
         "liquidity_indicator":"added",
         "remaining_quantity":"0.000000",
         "total_filled_quantity":"0.000000",
         "last_filled_quantity":"0.000000",
         "price":"3780.000000",
         "status":"canceled",
         "reject_reason":""
      }
   ]
}

Cancels an existing order. Request parameters listed below.

Parameter Description Type
client_order_id A unique request id supplied by you
Note: this is not the client_order_id of the order being canceled
string
instrument_code The code of the instrument you are submitting an order for string
market_code scxm or scxs - desired market code string
side buy or sell string

Once the cancel is submitted, our response is made available. Response parameters listed below.

Parameter Description Type
trading_account_code Unique trading account code string
client_order_id client_order_id supplied by you in the cancel request string
original_client_order_id original client_order_id supplied in the order create request string
order_id ID of open order string
market_code Market code string
exec_id ID of open execution report string
order_type Type of order string
exec_type Type of execution report string
instrument_code Instrument code string
transact_time Transaction time number
side Side of order string
original_quantity Original quantity of the order (Deprecated) string
total_quantity Original quantity of order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
remaining_quantity Quantity remaining to be filled string
total_quantity_filled Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of order string
status Status of order string
reject_reason Reason for rejection string

Sample Response

{
   "message":[
      {
         "order_id":"327500000000000042",
         "market_code":"SCXM",
         "exec_id":"327500000000000073",
         "trading_account_code":"WS9U7YYTHGQU",
         "order_type":"limit",
         "exec_type":"trade",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545339380053,
         "side":"buy",
         "original_quantity":"7.000000",
         "total_quantity":"7.000000",
         "liquidity_indicator":"added",
         "total_filled_quantity":"7.000000",
         "last_filled_quantity":"7.000000",
         "price":"6400.000000",
         "status":"filled",
         "reject_reason":""
      }
   ]
}

Fills

GET /fills

const crypto = require('crypto')
const request = require('request-promise')


const getFills = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/fills' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/fills`, options)
  }
fills = make_seed_request('GET', '/fills', {})

Sample Response

{
   "message":[
      {
         "order_id":"327500000000000042",
         "market_code":"SCXM",
         "exec_id":"327500000000000073",
         "trading_account_code":"WS9U7YYTHGQU",
         "order_type":"limit",
         "exec_type":"trade",
         "instrument_code":"COSP:BTC/USD",
         "transact_time":1545339380053,
         "side":"buy",
         "original_quantity":"7.000000",
         "total_quantity":"7.000000",
         "liquidity_indicator":"added",
         "total_filled_quantity":"7.000000",
         "last_filled_quantity":"7.000000",
         "price":"6400.000000",
         "status":"filled",
         "reject_reason":""
      }
   ]
}

Returns an array of your recent fills from orders submitted to SCXM and SCXS. Response parameters listed below.

Parameter Description Type
order_id of filling order string
market_code MIC where fill occurred, scxm or scxs string
exec_id ID of filling execution report string
trading_account_code Unique trading account code string
order_type Type of order string
exec_type Type of execution report string
instrument_code Unique instrument code string
transact_time Transaction time number
side Side of fill string
original_quantity Original quantity of order (Deprecated) string
total_quantity Original quantity of order string
liquidity_indicator Indicates whether order was executed as a maker (added) or taker (removed) string
total_filled_quantity Total quantity filled string
last_filled_quantity Quantity of last fill string
price Price of fill string

Trades

GET /trades

Sample Response

{
   "message":[
      {...}, // see trade by ID response below
      {...}  // see trade by ID response below
   ]
}

This returns an array of all trades received by Zero Hash for settlement from trading on SCXM, SCXS or any another platform supported by Zero Hash. Your intraday fills from trading on SCXM and SCXS may not be included until Zero Hash receives the trades for settlement.

Optional query paramters include:

GET /trades/:trade_id

A particular trade that has been submitted by to Zero Hash for settlement. Note: the trade_id field is the Zero Hash-provided identifier returned as a response to the trade submission endpoints.

Sample Response

{
   "message":{
       "trade_id":"asdf-asdf-asdf-asdf",
       "client_trade_id":"asdf-adsf-asdf-asdf",
       "status":"accepted",
       "market_identifier_code":"zero",
       "trade_reporter_code":"SDF123",
       "symbol":"BTC/USD",
       "trade_price":"4000",
       "trade_type":"spot",
       "physical_delivery":true,
       "comment":"some comments about the trade for Zero Hash to store",
       "transaction_timestamp":123123123,
       "accepted_timestamp":123123123,
       "settled_timestamp":null,
       "parties_anonymous":true,
       "parties":[
          {
             "side":"buy",
             "participant_code":"ABC123",
             "asset":"USD",
             "amount":"40000"
          },
          {
             "side":"sell",
             "participant_code":"DEFXYZ",
             "asset":"BTC",
             "amount":"10"
          }
       ]
   }
}

POST /trades

Sample Response

{
   "message":{
       "trade_id":"asdf-asdf-asdf-asdf",
       "client_trade_id":"asdf-adsf-asdf-asdf",
       "status":"accepted",
       "market_identifier_code":"zero",
       "trade_reporter_code":"SDF123",
       "symbol":"BTC/USD",
       "trade_price":"4000",
       "trade_type":"spot",
       "physical_delivery":true,
       "comment":"some comments about the trade for Zero Hash to store",
       "transaction_timestamp":123123123,
       "accepted_timestamp":123123123,
       "settled_timestamp":null,
       "parties_anonymous":true,
       "parties":[
          {
             "side":"buy",
             "participant_code":"ABC123",
             "asset":"BTC",
             "amount":"10"
          },
          {
             "side":"sell",
             "participant_code":"DEFXYZ",
             "asset":"USD",
             "amount":"40000"
          }
       ]
    }
}

Allows a Trade Reporter to post executed spot trades to Zero Hash for settlement. The following fields are part of the submission.

Parameter Description Type
client_trade_id A unique ID provided by the Trade Reporter
Note: Zero Hash cannot guarantee the uniqueness of this field
string
market_identifier_code The market identifier code, which must be zero for this post request string
trade_reporter_code The participant code of the Trade Reporter, as provided by Seed CX string
symbol The pair being traded string
trade_price The price the trade was executed
If asset and amount are included, this must equal to the buyer's amount divided by the seller's amount
string
trade_type The type of trade to be settled
Currently Zero Hash only supports spot
string
physical_delivery A boolean statement to indicate if the trade is physically delivered
Currently Zero Hash only supports physically-settled trades, i.e. a value of true
boolean
comment An option field to use if there is any additional information needed string
transaction_timestamp The unix timestamp the trade was executed on the external platform in milliseconds timestamp
parties_anonymous A boolean flag to determine if the counterparties are known to each other
Must be false if the trade reporter is a counterparty to the trade
boolean
parties The counter-parties of the trade
Currently Zero Hash only supports 2 parties per trade
parties[]

Parameters for a specific party to a trade.

Parameter Description Type
side The side of the party, buy or sell string
participant_code The participant code as assigned by Seed CX
Note: this will be Anonymous for counterparties to the trade if the parties_anonymous boolean was flagged as true by the Trade Reporter
string
asset The asset that is being delivered by the party string
amount The amount of the asset that is to be delivered by the party string

As a response, all information provided in the trade submission will be returned, plus the following additional fields:

Parameter Description Type
trade_id A unique ID from Zero Hash string
status accepted, rolled, settled or defaulted string
accepted_timestamp The time that Zero Hash accepted the request timestamp
settled_timestamp The timestamp that the trade fully settled, and will be null unless the status field is settled timestamp

Trade Status

Parties Anonymous

The parties_anonymous field is used to protect counterparty information. In the event that a Trade Reporter wishes to keep the counterparty details anonymous, this flag can be set to true. This is relevant for brokers and other types of agency execution providers.

Accounts

GET /accounts

const getAccounts = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/accounts' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/accounts`, options)
  }
accounts = make_seed_request('GET', '/accounts', {})

Sample Response

{
   "message":[
      {
         "asset":"USD",
         "account_owner": "ABCDEF",
         "account_type":"collateral_deficiency",
         "account_group":"seed",
         "balance":"0.00",
         "usd_adjusted":"0.00",
         "account_id":"ce819fe8-b1d7-43bb-961c-e09ede0988d3",
         "last_update":1554395972174
      }
   ]
}

Returns an array of all accounts maintained at Zero Hash and their balances as of the most recent settlement run. See this page to predict trade and settlement obligations that will affect those account balances. Response parameters listed below.

Parameter Description Type
asset The asset code for the specific account, e.g. USD string
account_owner The code of the participant that owns the account string
account_type available, collateral, payable, receivable or collateral_deficiency string
account_group The group that the account is a part of string
balance The balance in the account string
usd_adjusted The adjusted, USD-value of holdings in this account string
account_id Unique ID of the specific account string
last_update Timestamp of last settlement run timestamp

Assets

Refer to our FAQ page to see which assets we support and their corresponding asset codes.

Account Type

Account types refer to their utilization. Zero Hash maintains 5 account types:

Account Group

Account groups are utilized as part of the Zero Hash settlement infrastructure, to determine for which purpose the funds in the account have been allocated. All participants of Seed CX are provided a single, default account group: seed, which is used to determine the funds allocated for trading on Seed Digital Commodities Market or Seed SEF. A participant may also be provided additional account groups into which they can allocate funds for settling trades executed on other, third-party platforms.

USD Adjusted

Please refer to our FAQ page for more information on the usd_adjusted field. In short, the usd_adjusted value of an account is the value of the account's holdings, converted to USD and haircut according to Seed CX's haircut levels.

The sum of a participant's usd_adjusted and available accounts assigned to the seed group indicate the total credit available for trading on Seed CX.

GET /accounts/:account_id

const getAccount = () => {
    const timestamp = Math.round(Date.now() / 1000)
    const payload = timestamp + 'GET' + '/accounts/e5e18303-a352-4c28-8dab-3779e66a659b' + '{}'
    const decodedSecret = Buffer.from(apiSecret, 'base64')
    const hmac = crypto.createHmac('sha256', decodedSecret)
    const signedPayload = hmac.update(payload).digest('base64')

    // SET HEADERS
    const headers = {
      'X-SCX-API-KEY': 'public_key',
      'X-SCX-SIGNED': signedPayload,
      'X-SCX-TIMESTAMP': timestamp,
      'X-SCX-PASSPHRASE': 'passphrase'
    }
    const options =  {
      headers,
      body,
      json: true
    }
    return request.get(`https://api.seedcx.com/accounts/e5e18303-a352-4c28-8dab-3779e66a659b`, options)
  }
account = make_seed_request('GET', '/accounts/e5e18303-a352-4c28-8dab-3779e66a659b', {})

Sample Response

{
   "message":[
      {
         "asset":"USD",
         "account_type":"collateral_deficiency",
         "account_group":"seed",
         "balance":"0.00",
         "usd_adjusted":"0.00",
         "account_id":"ce819fe8-b1d7-43bb-961c-e09ede0988d3",
         "last_update":1554395972174
      }
   ]
}

Information about a specific account. Response parameters listed below.

Parameter Description Type
asset The asset code for the specific account, e.g. USD string
account_type available, collateral, payable, receivable or collateral_deficiency string
account_group The sub account determination used for allocating towards settlements string
balance The balance in the account string
usd_adjusted The adjusted, USD-value of holdings in this account string
account_id Unique ID of the specific account string
last_update Timestamp of last settlement run timestamp

GET /accounts/:account_id/run_history

Sample Response

{
   "message":[
      {
         "run_timestamp":1549577062214,
         "run_type":"settlement",
         "run_id":"500",
         "change":"2000",
         "new_balance":"146645"
      },
      {
         "run_timestamp":1520134020000,
         "run_type":"deposit",
         "run_id":"480",
         "change":"100000",
         "new_balance":"144645"
      },
      {
         "run_timestamp":1510101010000,
         "run_type":"withdrawal",
         "run_id":"375",
         "change":"-20000",
         "new_balance":"44645"
      }
   ],
   "page":1,
   "total_pages":32
}

The /run_history endpoint was deployed to the certification environment as part of March 8th release.

Returns the history of grouped settlements, deposits, withdrawals and other changes that have been applied to an account to lead up to its current balance.

Parameter Description Type
run_timestamp The time that the particular run was executed timestamp
run_type The type of run string
run_id A unique ID for the particular run string
change The net change to the account due to all movements within the particular run string
new_balance The new account balance post-run string

Run Type

A run is a group of movements that pertain to the same type of change to an account. They are split into the following buckets:

GET /accounts/:account_id/movements

Sample Response

{
   "message":[
      {
         "run_id":"500",
         "movement_timestamp":1554395972174,
         "movement_id":"ab938734-0aa6-4378-baa1-2cc56aeee757",
         "movement_type":"final_settlement",
         "trade_id":"332300000000228562",
         "change":"100"
      },
      {
         "run_id":"500",
         "movement_timestamp":1554395972174,
         "movement_id":"d8f902be-f8c3-4f9c-ac66-67000510900d",
         "movement_type":"final_settlement",
         "trade_id":"332300000000228563",
         "change":"-200"
      }
   ],
   "page":1,
   "total_pages":40

The /movements endpoint was deployed to the certification environment as part of March 8th release.

Returns the history of each itemized movement that has been applied to an account to lead up to its current balance.

Parameter Description Type
run_id A unique ID for the particular run string
movement_timestamp The timestamp of the specific movement timestamp
movement_id A unique ID for the specific movement string
movement_type The type of movement string
trade_id The ID of the trade that resulted in the movement string
change The change due to the specific movement string

Movement Type

Movement Description
deposit New capital added to the account
withdrawal Existing capital removed from an account
final_settlement A movement due to the full delivery and settlement of a trade executed in the current session, i.e. settling on T+0
final_settlement_previous A movement due to the full delivery and settlement of a trade executed in the previous session, i.e. settling on T+1
final_settlement_default_partial A partial delivery in the event of a default by one counterparty to the trade
final_settlement_default_fallback In the event of a partial delivery of a physically-settled trade, the remaining portion will be financially-settled using this movement type
initial_margin Collateral held for an open position
variation_margin A payment made or collected due to changes in the market value of the position since the trade was executed or since the previous time the position was marked to market, settled on T+0
variation_margin_previous A variation margin payed on T+1
network_fee Any and all blockchain network fees applied to an account
transfer A transfer from one account to another

Participants

GET /participants

Returns a list of all participants to which you are associated.

Sample Response

{
   "message": [
      {
         "participant_code":"123XYZ",
         "participant_name":"Trading Firm LLC",
         "relationship_types":[
            "customer_of_platform"
         ]
      },
      {
         "participant_code":"ABC456",
         "participant_name":"Lots of Capital LLC",
         "relationship_types":[
            "customer_of_platform"
         ]
      }
   ]
}

Response parameters listed below

Parameter Description Type
participant_code Unique participant code string
participant_name Name of participant string
relationship_types An array of the types of relationships you have with the participant string[]

Query parameters include:

Public Socket Feed

Connecting

const WebSocket = require('ws')

let ws = new WebSocket(`wss://api.seedcx.com`)

ws.on('open', () => {
  ws.send(JSON.stringify({ "messageType": "marketDataRequest", "payload": "COSP:BTC/USD" }))
})

ws.on('message', (message) => {
  console.log(message)
})
import asyncio
import json
from logging import getLogger

import websockets

logger = getLogger(__name__)
URL_BASE = 'api.seedcx.com'
WS_URL = 'wss://' + URL_BASE


async def mkt_data(instrument: str):
    """Subscribe to a market data feed over websocket."""
    async with websockets.connect(WS_URL) as conn:
        await conn.send(json.dumps({'messageType': 'marketDataRequest', 'payload': instrument}))
        while True:
            message_handler(await conn.recv())


def message_handler(msg: str):
    """Print the parts of the message. Simple example of message handling.

    :param msg: Message string to process
    """
    try:
        msg = json.loads(msg)
    except json.JSONDecodeError:
        logger.error('Error loading JSON message from server: {}'.format(msg))
        return
    if 'message' in msg:
        logger.info(msg['message'])
        return
    logger.info('Received {} message'.format(msg['messageType']))
    logger.info('Payload: {}'.format(msg['payload']))


# Run the event loop
loop = asyncio.get_event_loop()
loop.run_until_complete(mkt_data(instrument='COSP:BTC/USD'))

Our public websocket feed URL is wss://api.seedcx.com

Once connected, sending a JSON message with a messageType of marketDataRequest and a payload of a seed instrument code will subscribe you to market data updates of that instrument.

{ "messageType":"marketDataRequest","payload":"COSP:BTC/USD" }

A connection will be automatically severed if no information is received from the server for an extended period of time. To avoid this, ensure that you ping the Seed CX server on an interval of 10 seconds or less, to which you will receive a corresponding pong message response back as an ack.

Responses

Upon subscribing you will immediately receive an exchangeState and marketDataSnapshot message followed by a recentTimeAndSales message. These messages can be distinguished from each other by their messageType property.

the exchangeState describes the current state of the exchange. Trading is only allowed when the exchange is OPEN.

The marketDataSnapshot represents the current state of the orderbook. The orders field will contain all of the orders currently on the book. After subscribing, any change to the orderbook will come through as a conflatedMarketDataUpdate. These updates can be used to construct your own live representation of the applied to the initial marketDataSnapshot.

exchangeState

{
   "messageType":"exchangeState",
   "payload":{
      "currentPeriod":"OPEN",
      "marketCode":"SCXM",
      "nextPeriod":"PRE_CLOSE",
      "nextPeriodTimeStamp":"2019-03-01T22:00:00+00:00"
   }
}

The current state of the exchange.

Parameter Description Type
currentPeriod Current state of exchange string
marketCode MIC of the exchange being referenced, SCXM or SCXS string
nextPeriod Next state of exchange string
nextPeriodTimeStamp Time of next period start string

Market Periods

marketDataSnapshot

Sample Response

{
   "messageType":"marketDataSnapshot",
   "payload":{
      "close": "5100.000000",
      "lastTradedPrice": "4000.000000",
      "open": "5000.000000",
      "instrumentCode": "COSP:BTC/USD",
      "requestID": "5UmzsksUoB3SUS72NdKojR",
      "sequence": "3",
      "orders":[
         {
            "side": "buy",
            "orderID": "329700000000000000",
            "price": "5.000000",
            "quantity": "1"
         }
      ]
   }
}

A snapshot of the orderbook.

Parameter Description Type
close Price at which market previously closed string
lastTradedPrice Price of last trade string
open Price at which market opened string
instrumentCode Unique instrument code string
requestID Unique identifier for this marketDataSnapshot string
sequence Sequence number string
orders Array of orders order[]

Parameters for a specific public order.

Parameter Description Type
side buy or sell string
orderID ID of order string
price Price of order string
quantity Quantity of order string

recentTimeAndSales

Sample Response

{
   "messageType":"recentTimeAndSales",
   "payload":{
      "instrumentCode":"COSP:BTC/USD",
      "timeAndSales":[
         {
            "instrumentCode":"COSP:BTC/USD",
            "quantity":1,
            "transactTime":1547213413254,
            "price":1000,
            "side":"buy"
         }
      ]
   }
}

Recent time and sales.

Parameter Description Type
instrumentCode Instrument code of market string
timeAndSales Array of time and sales timeAndSale[]

Specific time and sales response parameters.

Parameter Description Type
instrumentCode Unique instrument code string
quantity Order quantity number
transactTime Time of transaction number
price Order price number
side buy or sell string

conflatedMarketDataUpdate

Update(s) to the orderbook

The payload will be an array of market data updates.

Sample Response

{
   "messageType":"conflatedMarketDataUpdate",
   "payload":[
      {
         "instrumentCode":"COSP:BTC/USD",
         "orderID":"329700000000000003",
         "quantity":"10",
         "price":"5.000000",
         "side":"buy",
         "type":"new",
         "transactTime":1547219109026,
         "sequence":"6"
      }
   ]
}
Parameter Description Type
instrumentCode Instrument code of market string
orderID ID of order string
quantity Quantity of order string
price Price of order string
side buy or sell string
type Type of update, new, delete, trade or change string
transactTime Time of transaction number
sequence Sequence number string

Private Socket Feed

Connecting

const WebSocket = require('ws')
const crypto = require('crypto')

const KEY = process.env.API_KEY
const apiSecretBase64 = process.env.API_SECRET
const PASSPHRASE = process.env.PASSPHRASE
const TIMESTAMP = String(Math.round(Date.now() / 1000))

const ws = new WebSocket(`wss://api.seedcx.com/private`)

const payload = TIMESTAMP + 'POST' + '/private' + JSON.stringify({})
const decodedSecret = Buffer.from(apiSecretBase64, 'base64')
const hmac = crypto.createHmac('sha256', decodedSecret)
const signedPayload = hmac.update(payload).digest('base64')

ws.on('open', () => {
  ws.send(JSON.stringify({
    body: {},
    KEY,
    PASSPHRASE,
    TIMESTAMP,
    SIGNED: signedPayload
  }))
})

ws.on('message', (data) => {
  console.log(data)
})

ws.on('error', (data) => {
  console.error(data)
})
# Even after removing type annotations, the below code works with Python 3.4+ only.
# For ease of use, Python 3.6+ is recommended if using websockets.

import asyncio
import hashlib
import hmac
import json
from base64 import b64decode, b64encode
from datetime import datetime
from logging import getLogger

import websockets

logger = getLogger(__name__)

# NB: THESE CREDENTIALS SHOULD NOT BE STORED IN PLAINTEXT
# Keys here are kept in plaintext for the purposes of demonstration
# We encourage you to encrypt your keys and decrypt them only when being used
URL_BASE = 'api.seedcx.com'
WS_URL = 'wss://' + URL_BASE
API_PUBLIC_KEY = 'usjHuLksaeBXWSsa8uU7ES'
API_PRIVATE_KEY = '2mC4ZvVd4goRkuJm+rjr9byUiaUW1b6tVN4xy9QXNSE='
PASSPHRASE = 'testingisgreat'


def sign(api_key: str, method: str, route: str, json_body: str, timestamp: str) -> bytes:
    """Given a key and data, create and sign a payload.

    :param api_key: Key to sign the message with
    :param method: HTTP method
    :param route: Relative route. EX. /fills
    :param json_body: JSON as a string. Usually created via json.dumps(dict)
    :param timestamp: Unix Epoch time as a string
    :return: Base64 encoded digest
    """
    msg = bytes(timestamp + method + route + json_body, encoding='utf-8')
    hm = hmac.new(key=b64decode(api_key), msg=msg, digestmod=hashlib.sha256)
    return b64encode(hm.digest())


async def connect_private():
    """Connect to the private websocket endpoint that requires authentication."""
    async with websockets.connect(WS_URL + '/private') as conn:
        t = str(int(datetime.now().timestamp()))
        sig = sign(API_PRIVATE_KEY, 'POST', '/private', json.dumps({}), t)
        # NB: there is no messageType and payload for an auth message
        await conn.send(
            json.dumps({
                'body': {},
                'KEY': API_PUBLIC_KEY,
                'PASSPHRASE': PASSPHRASE,
                'TIMESTAMP': t,
                'SIGNED': sig.decode('utf-8')
            })
        )
        while True:
            message_handler(await conn.recv())


def message_handler(msg: str):
    """Print the parts of the message. Simple example of message handling.

    :param msg: Message string to process
    """
    try:
        msg = json.loads(msg)
    except json.JSONDecodeError:
        logger.error('Error loading JSON message from server: {}'.format(msg))
        return
    if 'message' in msg:
        logger.info(msg['message'])
        return
    logger.info('Received {} message'.format(msg['messageType']))
    logger.info('Payload: {}'.format(msg['payload']))


# Run the event loop
loop = asyncio.get_event_loop()
loop.run_until_complete(connect_private())

Sample Response

{
  "message":"successfully subscribed to executions for desk 0XPVJR65S"
}

Our private websocket feed URL is wss://api.seedcx.com/private

Once connected, you will need to authenticate to subscribe to your execution reports.

Parameter Description Type
body An empty object - {} JSON
key Your public key string
passphrase Your passphrase string
timestamp Time in seconds since Unix Epoch string
signed your hmac signature string

For details on how to sign your payload, refer to the Authentication section above.

Some websocket client libraries may automatically sever the connection if no information is sent from your client or received from the server for an extended period of time. If you experience this, sending a ping through your websocket connection every 30 seconds will remedy this problem.

Responses

Upon successfully subscribing you will receive a subscription confirmation message.

{
  "message":"successfully subscribed to executions for desk 0XPVJR65S"
}

These are the types of messages you may receive through your private socket feed.

Order Execution Report

A private execution report for an order.

Sample Response

{
   "messageType":"executionReport",
   "tradingAccountCode":"0XPVJR65S2AT",
   "payload":{
      "tradingAccountCode":"0XPVJR65S2AT",
      "clientOrderID":"0.49566202",
      "orderID":"333500000000004014",
      "marketCode":"SCXM",
      "execID":"333500000000022419",
      "orderType":"post-limit",
      "execType":"new",
      "instrumentCode":"COSP:BTC/USD",
      "transactTime":1550507010097,
      "side":"buy",
      "originalQuantity":"1.000000",
      "remainingQuantity":"1.000000",
      "totalFilledQuantity":"0.000000",
      "totalQuantity":"0.000000",
      "liquidityIndicator":"added",
      "lastFilledQuantity":"0.000000",
      "price":"5.000000",
      "status":"new",
      "rejectReason":""
   }
}
Parameter Description Type
tradingAccountCode Unique trading account code string
clientOrderID client_order_id supplied at order creation string
orderID ID of open order string
originalOrderID Order ID of order being canceled and replaced string
marketCode scxm or scxs string
execID ID of open execution report string
orderType market, limit or post-limit string
execType Type of execution report string
instrumentCode Unique instrument code string
transactTime Transaction time number
side buy or sell string
originalQuantity Original quantity of order (Deprecated) string
totalQuantity Original quantity of order string
remainingQuantity Quantity remaining to be filled string
totalFilledQuantity Total quantity filled string
lastFilledQuantity Quantity of last fill string
price Price of order string
status Status of order string
rejectReason Reason for rejection string

Business Message Reject

A rejection due to a business reason such as insufficient funds

Sample Response

{
  "messageType": "businessMessageReject",
  "payload": {
    "tradingAccountCode": "0XPVJR65S2AT",
    "businessRejectReason": 0,
    "refMsgType": "D",
    "clientOrderID": "8537839",
    "text": "Order quantity is above upper threshold. 1001 was entered, but maximum order quantity is 1000.0"
  }
}
Parameter Description Type
tradingAccountCode Unique trading account code string
businessRejectReason Business reject reason code number
refMsgType Type code for message string
clientOrderID client_order_id supplied at order creation string
text Additional information about business reject string

Order Cancel Reject

An Order Cancel was rejected.

Sample Response

{
  "messageType": "orderCancelReject",
  "payload": {
    "tradingAccountCode": "0XPVJR65S2AT",
    "clientOrderID": "449dd29",
    "originalClientOrderID": "22dd3sk3",
    "orderStatus": "rejected",
    "rejResponseTo": "OrderCancelRequest",
    "rejReason": "OrderCancelRequest - Unknown order",
    "text": "",
  }
}
Parameter Description Type
tradingAccountCode Your trading account code string
clientOrderID client_order_id of cancel reject order string
originalClientOrderID client_order_id of order being cancelled string
orderStatus Status of order, new string
rejResponseTo The type of request that the cancel reject is in response to string
rejReason Reason for the rejection string
text More information about the rejection string