NAV
python go java

Genesis Trading API: Introduction

Version: 1.3.9

Last Updated: July, 14, 2022

The REST API documentation for Genesis Trading explains the input, output, and endpoint URL for each API to help you use them effectively.

For more information and any queries, Genesis API team can be reached at Send an email to Genesis API Team for questions related to API onboarding, connectivity issues, API availability, trading support, and more.

If you wish to receive notifications regarding scheduled maintenance windows and new features, please provide an appropriate email distribution for those.

Revision History

Date Version Summary
03/19/2020 1.0.0 Initial release
04/15/2020 1.0.1 Added rate limits and improved documentation
05/29/2020 1.0.2 Changed /stream to asynchronous design
08/31/2020 1.1.0 Clarified language
1.1.1 Clarified language
1.1.2 Added “Account” to /orderStatus and /stream
01/07/2021 1.2.0 New /balanceStatus endpoint, updated maintenance window, and ergonomic field naming changes
01/13/2021 1.2.1 Updated /stream response field and accepted fields for ‘TimeInForce’ arguments
04/08/2021 1.3.0 Added market order submissions
04/28/2021 1.3.1 Clarified language on partially filled orders
05/14/2021 1.3.2 Added /metadata endpoint
07/13/2021 1.3.3 Added /settlementStatus and /tradeHistory endpoints
07/22/2021 1.3.4 Updated /securityDefinitionRequest with price / quantity precision. Added additional error messaging.
08/13/2021 1.3.5 Added /quote endpoint and order reject / cancel messaging.
09/23/2021 1.3.6 Added pagination for /settlementStatus and added support for multi-level streaming IOC orders.
10/14/2021 1.3.7 Added support for IOC market orders
02/03/2022 1.3.8 Added /sseStream endpoint. Removed information on the nonce order validation.
05/19/2022 1.3.9 Added workflow to initiate a request for new coins.

API Support & Availability

Support Escalation

The Genesis API Support team can be directly reached at api@genesistrading.com for questions related to API onboarding, connectivity issues, API availability, trading support, and more.

For general support questions, please contact support@genesistrading.com

New features and maintenance notifications

If you wish to receive notifications regarding scheduled maintenance windows and new features, please send your appropriate email distribution to api@genesistrading.com

Availability

The Genesis Trading REST API is intended to facilitate market data and order entry.

Env Description
Production 24/7/365 with a daily maintenance window where the system will be entirely offline. The maintenance window runs between 16:30 and 16:55 ET.
UAT 24/7/365 with a variable maintenance window. Changes will be communicated through the Support team.

Connectivity

Endpoints

IP whitelisting is required for all endpoints.

Environment Endpoint
Production https://api.genesistrading.com
UAT https://trading.uat.genesistrading.com

Protocols and Verbs

All REST requests are communicated over HTTPS. REST requests should be made with the POST verb. Server-sent events (SSE) streaming URL requests should be made with the GET verb.

Streaming

The streaming HTTPS request will "time-out" after 300 seconds if no other REST request is made within that time interval. We recommend sending a keep-alive ping call every 60 seconds to keep the stream connected. WebSocket connections are not supported.

Rate limiting

By default, all clients are configured with the following global rate limits across all API methods. Rate limits are implemented using a “token bucket” of size equal to the max burst rate and refill rate equal to the request rate. Rate limits are enforced per client IP address, not per API key.

Description Rate limit
Max burst per IP 1000 requests/second
Request rate per IP 100 requests/second

Error handling and Best Practices

Error codes

Error codes Value Description
OK 0 No Error
TooManyRequests 1 Requests for client IP have exceeded rate limit
Unauthorized 2 Invalid client API key or client account
Unsupported method 3 Invalid REST verb or URL
Invalid signature 4 Signature string is invalid
Missing argument 5 A required argument was missing for the specific endpoint
Invalid argument 6
Invalid nonce 7
New order error 1001 A specific error occurred when creating a new order
Unknown Error 9999 Generic error code

Retry Logic - Detection & Reconnection

During scheduled maintenance windows or any unexpected outages, all requests will return an HTTP 5XX server error and the SSE connection will be closed. Upon detection, we recommend implementing retry logic to reopen the stream every 60 seconds until a stream connection is successfully secured. Please note that following scheduled maintenance windows or any unexpected outage, you will need to send a subscription request via the /marketDataRequest endpoint to receive market data or submit orders.

Nonces - Ordering & Tolerance

We require strict ordering and uniqueness of nonce values received over the API gateway to ensure sequenced processing of these messages. If your implementation involves parallel processes making API requests, all calls should be directed through an outbound service that tags the requests with the appropriate nonce and signature.

Authentication

Message Format Examples:

# ?APIKEY=apikey&PAYLOAD=payload&NONCE=nonce&SIGNATURE=signature
import hmac
import time
import requests

def generate_query_params(args):
    payload = json.dumps(args) #'null' if none
    nonce = str(int(time.time() * 1e9))  # nanosecond
    signature = hmac.new(api_secret.encode(), (api_key + payload + nonce).encode(),
                   hashlib.sha384).hexdigest()
    query_params = {
        "APIKEY": api_key,
        "PAYLOAD": payload,
        "NONCE": nonce,
        "SIGNATURE": signature,
    }
    return query_params

The following fields should be URL-encoded for all requests. Arguments for a specific method are passed as a standard JSON object in the PAYLOAD field.

Field Name Datatype Description
APIKEY string Client API key
PAYLOAD string URL encoded JSON object specifying request arguments. Must be 'null' if none.
NONCE number Unix timestamp with nanosecond precision (the number of nanoseconds elapsed since January 1, 1970 UTC). Requests older than 10 seconds will be considered stale and will not be processed as a safety mechanism.
SIGNATURE string Hex digest of SHA384 hash of the concatenation of APIKEY + PAYLOAD + NONCE, using the client API secret

List of API Endpoints

URL Description
POST /ping No operation. Used to keep stream alive or test connectivity
POST /securityDefinitionRequest Retrieve an array of tradable symbols with properties
POST /metadata Retrieve configuration information
POST /marketDataRequest Subscribe to market data
GET /sseStream Opens multiple market data streams with limit of 10
POST /quote Retrieve current L2 update
POST /newOrderSingle Send a new order
POST /orderStatus Retrieve execution reports for a given order
POST /tradeHistory Retrieve trade history for the specified date range
POST /balanceStatus Retrieve the outstanding quantity of unsettled trades by symbol
POST /settlementStatus Retrieve trade batch settlement amounts

Recommended API Workflows

API Endpoints

Ping

import requests

url = "https://<trading-api-url>/ping?APIKEY=API_KEY_VALUE&PAYLOAD=null&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"

payload = ""

response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1633963791265166639,
    "Result": "PONG",
    "Text": "Success"
}

A no-operation request to reset the stream timeout interval or test connectivity.

HTTP Request

POST https:<trading-api-url>/ping?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result string 'PONG'
Text string ‘Success’ or reason for error

Security Definition Request

import requests

url = "https://<trading-api-url>/securityDefinitionRequest?APIKEY=APIKEY_VALUE&PAYLOAD=null&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"

payload = ""

response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1632932207589991721,
    "Result": [
        {
            "Symbol": "ETH-USD",
            "MinQty": 0.00000001,
            "QtyPrecision": 8,
            "PricePrecision": 2
        },
        {
            "Symbol": "BTC-USD",
            "MinQty": 0.00000001,
            "QtyPrecision": 8,
            "PricePrecision": 2
        }
    ],
    "Text": "Success"
}

Retrieves the symbols allowed for trading and their properties. Precisions are defined as the maximum number of decimal places this field supports.

HTTP Request

POST https:<trading-api-url>/securityDefinitionRequest?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array(Object) [{ 'Symbol': string, 'MinQty': number, ‘QtyPrecision’: number, ‘PricePrecision’: number},...]
Text string ‘Success’ or reason for error

Market data Request

import requests

payload = {'Action': 'SUBSCRIBE', 'Symbols': ['BTC-USD', 'ETH-USD', 'LTC-USD']}

url = "https://<trading-api-url>/marketDataRequest?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635224837518606767,
    "Result": null,
    "Text": "Success: requested symbols: BTC-USD,ETC-USD,LTC-USD, subscribed/unsubscribed symbols: BTC-USD,ETC-USD,LTC-USD"
}

Add symbols to the streaming URL. L2 updates returned on /stream. Subscriptions remain active until unsubscribe or /logout.

HTTP Request

POST https:<trading-api-url>/marketDataRequest?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
Action string Accepted: 'SUBSCRIBE' or 'UNSUBSCRIBE'
Symbols array (string) An array of string symbols to subscribe/unsubscribe

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result null null
Text string ‘Success: requested symbols: {client requested symbols}, subscribed/unsubscribed symbols: {successfully subscribed/unsubscribed symbols}’ or reason for error

Quote

import requests

payload = {"Symbol":"BTC-USD"}

url = "https://<trading-api-url>/quote?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635306311921354653,
    "Result": {
        "QuoteTime": 1635306310561884347,
        "ValidUntil": 1635306315561182283,
        "Symbol": "BTC-USD",
        "Changes": [
            {
                "Entry": [
                    "BUY",
                    60302.28,
                    0
                ]
            },
            {
                "Entry": [
                    "SELL",
                    61104.79,
                    0
                ]
            },
            {
                "Entry": [
                    "BUY",
                    60277.82,
                    1000
                ]
            },
            {
                "Entry": [
                    "SELL",
                    61141.5,
                    1000
                ]
            }
        ],
        "Venue": "GENESIS"
    },
    "Text": "Success"
}

Retrieve the latest L2 update for a given symbol. Prior to sending a /quote request, please submit a successful subscription request for the given symbol via the /marketDataRequest endpoint.

HTTP Request

POST https:<trading-api-url>/quote?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
Symbol string Symbol to pull quote for (e.g. ‘BTC-USD’)

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result object L2 Update with multi-level quote
{
Venue: 'GENESIS',
QuoteTime: number (Unix timestamp w/ ns precision),
ValidUntil: number (Unix timestamp w/ ns precision),
Symbol: string,
Changes: [{‘Entry’: [string number number]},
{‘Entry’: [string number number]},...]
e.g.
[{‘Entry’: ['BUY' price qty]},
{‘Entry’: ['BUY' price qty]}
{‘Entry’: ['SELL' price qty]}
{‘Entry’: ['SELL' price qty]},...]
}
Text string Success

NewOrderSingle

import requests

payload = {"Symbol":"BTC-USD","ClOrdID":"299808394218321","OrdType":"MARKET","TimeInForce":"FILL_OR_KILL","Side":"BUY","OrderQty":0.01, "Price": 0}

url = "https://<trading-api-url>/newOrderSingle?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635225609292793427,
    "Result": null,
    "Text": "Success"
}

Submit a new order. Execution report returned on /stream.

HTTP Request

POST https:<trading-api-url>/newOrderSingle?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
Symbol string Symbol identifier
ClOrdID string (string) Client-specified unique order identifier. Must be <= 32 characters in length.
OrdType* string Accepted: 'LIMIT' or 'MARKET'
TimeInForce** string Accepted: 'FILL_OR_KILL' or 'IMMEDIATE_OR_CANCEL'
Side string Accepted: 'BUY' or 'SELL'
Price number Required for OrdType ‘LIMIT’
OrderQty number Order size in units of given symbol. See /securityDefinitionRequest for qty precision by symbol.

* For market orders, we currently support FOK. We will be releasing support for market IOC orders in the next update. ** For clients enabled for 2+ order book levels, only immediate-or-cancel orders will be accepted.

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result null null
Text string ‘Success’ or reason for error

Order Status

import requests

payload = {"ClOrdId":"576048115236807"}

url = "https://<trading-api-url>/orderStatus?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635307485199219381,
    "Result": [
        {
            "OrdID": "8374283749237498273",
            "Account": "key",
            "ClOrdID": "128371827481827",
            "TransactTime": 1635307481965122901,
            "OrdType": "MARKET",
            "OrdStatus": "FILLED",
            "TimeInForce": "FILL_OR_KILL",
            "Symbol": "BTC-USD",
            "Side": "BUY",
            "OrderQty": 0.01,
            "Price": 0,
            "LastPx": 61006.46,
            "LastQty": 0.01,
            "LeavesQty": 0,
            "CumQty": 0.01,
            "AvgPx": 61006.46,
            "Text": "Filled"
        }
    ],
    "Text": "Success"
}

Obtain the chronologically ordered execution report history for one order.

Field Descriptions

The price and quantity fields of the execution report for a given order is in accordance with FIX specifications.

HTTP Request

POST https:<trading-api-url>/orderStatus?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
ClOrdID string The order’s client-set ClOrdID

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array(object) [{
OrdID: string,
Account: string,
ClOrdID: string,
TransactTime: number (Unix timestamp w/ ns precision),
OrdType: string ('LIMIT' or 'MARKET'),
OrdStatus: string ('FILLED', 'PARTIALLY_FILLED',
'CANCELLED', or 'ORDER_REJECTED'),
TimeInForce: string ('FILL_OR_KILL' or
'IMMEDIATE_OR_CANCEL'),
Symbol: string (e.g. 'BTC-USD'),
Side: string ('BUY' or 'SELL'),
OrderQty: number,
Price: number,
LastPx: number,
LastQty: number,
LeavesQty: number,
CumQty: number,
AvgPx: number,
Text: string ('Filled' or cancel reason)
},...]
Text string ‘Success’ or reason for error

Trade history

import requests

payload = {"StartTime":1635223770045000000, "EndTime":1635310170046000000, "OrderDesc": true}

url = "https://<trading-api-url>/tradeHistory?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635310170267334350,
    "Result": [
        {
            "OrdID": "123123123123123",
            "Account": "key",
            "ClOrdID": "207090116513944",
            "TransactTime": 1635307481965122901,
            "OrdType": "MARKET",
            "OrdStatus": "FILLED",
            "TimeInForce": "FILL_OR_KILL",
            "Symbol": "BTC-USD",
            "Side": "BUY",
            "OrderQty": 0.01,
            "Price": 0,
            "LastPx": 61006.46,
            "LastQty": 0.01,
            "LeavesQty": 0,
            "CumQty": 0.01,
            "AvgPx": 61006.46,
            "Text": "Filled"
        }
    ],
    "Text": "Success"
}

Obtain the chronologically ordered execution report history for orders that were filled or partially filled.
To paginate results, the ‘StartTime’ value of the subsequent /tradeHistory request should be populated with the ‘EndTime’ value of the previous response.

HTTP Request

POST https:<trading-api-url>/tradeHistory?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
StartTime number Unix timestamp with nanosecond precision. Exclusive of given range. Else 0 for beginning of time.
EndTime number Unix timestamp with nanosecond precision. Inclusive of given range.
Limit number Optional - Number of orders (Default set to 20, otherwise 1 <= Limit <= 100)
Side string Optional - Side to filter for (‘BUY’ or ‘SELL’)
Symbol string Optional - Symbol to filter for (e.g. ‘BTC-USD’)
OrderDesc boolean Optional - Sorting order (Default set to ascending order (False))

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array(object) [{
OrdID: string,
Account: string,
ClOrdID: string,
TransactTime: number (Unix timestamp w/ ns precision),
OrdType: string ('LIMIT' or 'MARKET'),
OrdStatus: string ('FILLED', 'PARTIALLY_FILLED',
'CANCELLED', or 'ORDER_REJECTED'),
TimeInForce: string ('FILL_OR_KILL' or
'IMMEDIATE_OR_CANCEL'),
Symbol: string (e.g. 'BTC-USD'),
Side: string ('BUY' or 'SELL'),
OrderQty: number,
Price: number,
LastPx: number,
LastQty: number,
LeavesQty: number,
CumQty: number,
AvgPx: number,
Text: string ('Filled' or cancel reason)
},...]
Text string ‘Success’ or reason for error

Balance Status

import requests

payload = ""

url = "https://<trading-api-url>/balanceStatus?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1634648211947571440,
    "Result": [
        {
            "Symbol": "ADA-USD",
            "Qty": 67.473386
        },
        {
            "Symbol": "BTC-USD",
            "Qty": 103.01804763
        },
        {
            "Symbol": "ETH-USD",
            "Qty": 2884.51758661
        },
        {
            "Symbol": "SOL-USD",
            "Qty": 0.4601
        },
        {
            "Symbol": "XLM-USD",
            "Qty": 6.04
        },
        {
            "Symbol": "USD",
            "Qty": -14920863.19
        }
    ],
    "Text": "Success"
}

Obtain the outstanding quantity of unsettled trades summed by symbol. Negative balances are owed to Genesis, positive balances are owed to Client.

HTTP Request

POST https:<trading-api-url>/balanceStatus?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array(object) [{'Symbol': string, 'Qty': number},...]
e.g.
[{'Symbol': 'BTC-USD', 'Qty': 3.23}]
Text string ‘Success’ or reason for error

Settlement Status

import requests

payload = ""

url = "https://<trading-api-url>/settlementStatus?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1634648211947571440,
    "Result": [
        {
            "Symbol": "ADA-USD",
            "Qty": 67.473386
        },
        {
            "Symbol": "BTC-USD",
            "Qty": 103.01804763
        },
        {
            "Symbol": "ETH-USD",
            "Qty": 2884.51758661
        },
        {
            "Symbol": "SOL-USD",
            "Qty": 0.4601
        },
        {
            "Symbol": "XLM-USD",
            "Qty": 6.04
        },
        {
            "Symbol": "USD",
            "Qty": -14920863.19
        }
    ],
    "Text": "Success"
}

Obtain the outstanding set of settlement batches with creation times. Negative balances are owed to Genesis, positive balances are owed to Client.
In the example below, Client would settle by sending 1.45 BTC to Genesis and would receive 16032 USD from Genesis.

HTTP Request

POST https:<trading-api-url>/settlementStatus?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

Argument Datatype Description
StartTime number Optional - Unix timestamp with nanosecond precision, else 0 for beginning of time
EndTime number Optional - Unix timestamp with nanosecond precision (must be > StartTime)
Limit number Optional - Number of orders (Default set to 20, otherwise 1 <= Limit <= 100)
OrderDesc boolean Optional - Sorting order (Default set to ascending order (False))

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array(object) [{
BatchID: number,
CreateTime: number (Unix timestamp w/ ns precision),
Status: string ('PENDING' or 'SETTLED'}
Balances: [{'Symbol': string, 'Qty': number},...]},...]
e.g.
[{
BatchID: 601,
CreateTime: 1610390686000000000,
Status: 'SETTLED',
Balances: [{'Symbol': 'BTC-USD', 'Qty': -1.45}, {'Symbol': 'USD', 'Qty': 50032.21}]
}]
Text string ‘Success’ or reason for error

Stream

import requests

payload = {"ClOrdId":"576048115236807"}

url = "https://<trading-api-url>/orderStatus?APIKEY=11213&PAYLOAD="+ payload +"&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"



response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1635307485199219381,
    "Result": [
        {
            "OrdID": "8374283749237498273",
            "Account": "key",
            "ClOrdID": "128371827481827",
            "TransactTime": 1635307481965122901,
            "OrdType": "MARKET",
            "OrdStatus": "FILLED",
            "TimeInForce": "FILL_OR_KILL",
            "Symbol": "BTC-USD",
            "Side": "BUY",
            "OrderQty": 0.01,
            "Price": 0,
            "LastPx": 61006.46,
            "LastQty": 0.01,
            "LeavesQty": 0,
            "CumQty": 0.01,
            "AvgPx": 61006.46,
            "Text": "Filled"
        }
    ],
    "Text": "Success"
}

Receive live Level II market data updates and trade events as carriage-return new line “\r\n”
delimited JSON. Decode an object by looking at the “Type” key.

Market Data Subscription

To see L2 quotes for a given symbol, please submit a successful subscription request via the /marketDataRequest endpoint.

Number of Connections

Only one streaming connection is allowed per client API key. Additional connection attempts will be closed by the host and return with REST error: “Stream active”.

Number of Levels

The number of levels streamed to the client will be determined by the Genesis Trading Desk prior to trading in production.

Field Descriptions

The price and quantity fields of the execution report for a given order is in accordance with FIX specifications.

HTTP Request

GET https:<trading-api-url>/stream?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Streaming JSON. EOF denotes finalization of request and pending closure of socket connection.

Field Datatype Description
SequenceNumber number Session-dependent monotonically increasing sequence number. Resets upon disconnect/logout.
Result object [{'Type': string, 'Data': object},...]
Type: 'ExecutionReport' (fill, partial fill, cancel, or reject)
{
OrdID: string,
Account: string,
ClOrdID: string,
TransactTime: number (Unix timestamp w/ ns precision),
OrdType: string ('LIMIT' or 'MARKET'),
OrdStatus: string ('FILLED', 'PARTIALLY_FILLED', 'CANCELLED', or 'ORDER_REJECTED'),
TimeInForce: string ('FILL_OR_KILL' or 'IMMEDIATE_OR_CANCEL'),
Symbol: string (e.g. 'BTC-USD'),
Side: string ('BUY' or 'SELL'),
OrderQty: number,
Price: number,
LastPx: number,
LastQty: number,
LeavesQty: number,
CumQty: number,
AvgPx: number,
Text: string ('Filled' or cancel reason)
}
Type: 'L2Update' (order book change)
{
Venue: 'GENESIS',
QuoteTime: number (Unix timestamp w/ ns precision),
ValidUntil: number (Unix timestamp w/ ns precision),
Symbol: string,
Changes
2: [{‘Entry’: [string number number]},
{‘Entry’: [string number number]},...]
e.g.
[{‘Entry’: ['BUY' price qty]},
{‘Entry’: ['BUY' price qty]}
{‘Entry’: ['SELL' price qty]}
{‘Entry’: ['SELL' price qty]},...]
}
Text string ‘Success’ or reason for error

MetaData

import requests

url = "https://<trading-api-url>/metadata?APIKEY=11213&PAYLOAD=null&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"

payload = ""

response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1632932203993892508,
    "Result": {
        "Instruments": {
            "BSV-USD": {
                "Qtys": [
                    0.5,
                    5,
                    35
                ],
                "Enabled": true
            },
            "BTC-USD": {
                "Qtys": [
                    0.5,
                    5,
                    35
                ],
                "Enabled": true
            },
            "ZEC-USD": {
                "Qtys": [
                    0.1,
                    0.2,
                    1
                ],
                "Enabled": false
            }
        },
        "Enabled": true,
        "MaxNotionalDayDollars": 1000000000,
        "MaxNotionalOrderDollars": 1000000000,
        "RefreshIntervalDurationSecs": 10
    },
    "Text": "Success"
}

Configuration information including notional risk limits (in USD) and quoting parameters.

HTTP Request

POST https:<trading-api-url>/metadata?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result array (object) [{
QuoteFrequencyMs: number,
MaxDayNotionalDollars: number,
MaxDayNotionalOrderDollars: number,
Instruments: {{Symbol: {Enabled: bool,
Qty: [number]}},
{Symbol: {Enabled: bool,
Qty: [number]}}
e.g.
{{BTC-USD: {Enabled: True,
Qty: [10]}},
{ETH-USD: {Enabled: False,
Qty: [50]}}
}]
Text string ‘Success’ or reason for error

Logout

import requests

url = "https://<trading-api-url>/logout?APIKEY=11213&PAYLOAD=null&NONCE=1634241864011000000&SIGNATURE=91f0bb5c89b01235ded238b82f9613cdeeb76bf8d1f15470890927a684b2bea0e4fa08b4bc628a67434b4c8cb37e355a"

payload = ""

response = requests.request("POST", url, headers=headers, data=payload)

The above command returns JSON structured like this:

{
    "ErrorStatus": 0,
    "SendingTime": 1634662115368273207,
    "Result": null,
    "Text": "Success"
}

Cleanly teardown the streaming URL, unsubscribing from any active market data requests. The streaming URL should send a logout message as the final message before finalizing the HTTP request (sending EOF) and closing the socket.

HTTP Request

POST https:<trading-api-url>/logout?APIKEY=KEY&PAYLOAD=PL&NONCE=NC&SIGNATURE=SIGNATURE

Arguments

None

Response

Field Datatype Description
ErrorStatus number 0 if OK, error code otherwise.
SendingTime number Unix timestamp with nanosecond precision.
Result null null
Text string ‘Success’ or reason for error

Appendix

Error Text

Endpoint(s) Error Text
All Client exceeds rate limits Rate limit exceeded, please try again later
Missing arguments in request Missing required arguments:{comma separated list of missing arguments}
Unsupported argument in request Unsupported argument provided in {client requested arguments}
Invalid API Key length Invalid API key length, expected 50 max length but got {client api key length} instead
Invalid payload length Invalid payload length, expected 100000 max length but got {client payload length} instead
Invalid nonce length Invalid nonce length, expected 19 max length but got {client nonce length} instead
Expired nonce Expired nonce: nonce: {client requested nonce} expired {time since requested nonce expiry} ago
All endpoints with no required arguments Non-null payload Non-null payload sent
/marketDataRequest Invalid action Invalid action sent, please send SUBSCRIBE
No valid symbols sent Invalid symbols sent, please call /securityDefinitionRequest for list of valid symbols and /metadata for enabled symbols
/quote Not subscribed to market data Quote not found, please subscribe to market data
/newOrderSingle Invalid symbol Invalid symbol sent, please call /securityDefinitionRequest for list of valid symbols
Invalid ClOrdID Invalid ClOrdID sent, please check length and characters in ClOrdID
Invalid OrdType Invalid OrdType sent, please send either LIMIT or MARKET
Invalid TIF Invalid TimeInForce sent, please send either FILL_OR_KILL or IMMEDIATE_OR_CANCEL
Invalid side Invalid side sent, please send either BUY or SELL
Invalid limit price Invalid price sent, please ensure price is positive and within precision limits
Invalid order qty Invalid order qty sent, please ensure order qty is positive and within precision limits
IOC market order Invalid order, MARKET order must be FILL_OR_KILL
Duplicate ClOrdID Duplicate ClOrdID sent, please ensure ClOrdIDs are unique
Client not enabled for symbol Invalid symbol sent, please call /metadata for list of enabled symbols
/tradeHistory Invalid time range Invalid time range sent, please ensure start time and end time are positive and start time < end time
Invalid pagination limit Invalid pagination limit sent, please ensure 0 <= Limit <= 100
Invalid side Invalid side sent, please send BUY, SELL or an empty string
Invalid symbol Invalid symbol sent, please either populate symbol as an empty string or call /securityDefinitionRequest for list of valid symbols to populate
/orderStatus Invalid ClOrdID Invalid ClOrdID sent, please check length and characters in ClOrdID

Order Rejects & Cancels

Endpoint(s) Error Text
Reject Client not enabled for trading Not enabled for trading
Client not enabled to trade instrument Not enabled for trading this instrument
Internal Server Error Internal Server Error
Client order notional limit exceeded Order notional limit exceeded
Client daily notional limit exceeded Daily notional limit exceeded
Client not subscribed to market data Must subscribe to market data before placing order
Cancel Pricing failure Insufficient liquidity
Limit condition failure Out-of-limit price.
FOK Matching failure - no matches No fills
Unable to fill entire quantity FOK - order quantity greater than available inventory
IOC Matching failure - no matches No fills