NAV
cURL JavaScript Python Go

Paradigm API v1

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Introduction

Paradigm has two major products, Multi-Dealer RFQ (DRFQ) and Global RFQ (GRFQ).

These two products are separate and require separate authenticated interaction via their specific version & product connections URLs.

Paradigm uses RESToverHTTP and JSON-RPCoverWebSockets as our API interfaces to be consistent with the broader crypto space.

Feel free to reach out for any technical support as we would love to help!

DRFQ - Brief Overview

Multi Dealer RFQ (DRFQ) is to be used when you wish to request a quote for a specific size and from a specific group of counterparties. DRFQs are short lived and designed to be executed within a small time window.

To be part of a DRFQ, you must either be the Initiator (Taker) or a requested counterparty (Maker). DRFQs can be created on a disclosed or anonymous basis, but Makers' desk names are always & only disclosed to the DRFQ Taker.

Makers are unable to see competing Quotes or information relating to the Taker's intended execution side.

If you would like to be recognized as a "Liquidity Provider" or a Maker, please reach out to our Sales team.

Deribit, Bit.com, and the CME are available as venues.

GRFQ - Brief Overview

Global RFQ (GRFQ) is to be used when you wish to contribute to a public auction for a specific RFQ. GRFQ RFQs are long lived and are only canceled after the expiry of the underlying instruments or the inactivity of the RFQ.

Anyone is able to participate in a GRFQ RFQ and act as a Taker or a Maker. All GRFQ RFQ Quotes, Orders, Trades, and interactions are anonymous to everyone but the users who are directly apart of each interaction.

Deribit, Bit.com, and Bybit are available as venues.

API Connection URLs

The API is available on Paradigm's Live and Test environments.

Base URL | Live Environment

Base URL | Test Environment

Product & Version

You must concatenate the Base URL with the Version & Product URLs to access specific endpoints.

Examples:

Rate Limits

RESToverHTTP requests are rate limited to 30 requests per second per desk across all API Keys.

RESToverHTTP requests share a static rate limit across both our DRFQ and GRFQ Products. You cannot horizontally scale your rate limit per desk by using multiple API Keys.

Onboarding

We can create as many Paradigm test environment accounts as you like. We would love to create a Taker and a Maker account, functionally no different to each other, so you can test the workflows end-to-end.

For test environment accounts, all you need to do is:

As a note, you will need to enter different Venue API Credentials on your Taker and Maker Paradigm accounts as you cannot trade against yourself.

Exchange Testnet URLs

Helpful Reminders

High Level Implementation Notes

These notes relate to DRFQ, and GRFQ Products.

You should use your connection to Paradigm through the JSON-RPCoverWebSockets interface to receive updates relating to RFQs, Quotes, Orders (GRFQ), and Trades.

You should use our RESToverHTTP endpoints to interact with Paradigm for all actions such as, but not limited to, Creating RFQs, Creating Quotes, Canceling Quotes, Creating Orders, and Canceling Orders.

Your solution should:

Your solution should not:

Errors

All RESToverHTTP error responses follow the same basic format. An Error object is returned in response to an erroneous RESToverHTTP request, accompanied by a HTTP status code of 400.

Specific error codes are listed with each RESToverHTTP endpoint.

Error Object

An example of an erroneous Response message

{
    "code": 1002,
    "message": "Invalid enumeration set value",
    "data": {
        "member": "side",
        "value": "CROSS"
    }
}

The Error object is expressed as a single JSON Object, with the following members:

Member Type Req Description
code number Y The type of error that occured.
message string Y A short description of the error.
data object N Additional structured information about the error. The value is determined by the specific member invoked and may not be present if the error does not require it.

Error Codes

The following general error codes are supported by Paradigm:

Code Message Meaning
-32700 Parse error Invalid JSON received by the server.
-32600 Invalid Request The JSON sent is not a valid Request object.
-32601 Method not found The method does not exist / is not available.
-32602 Invalid params Invalid method parameter(s).
-32603 Internal error Internal JSON-RPC error.
429 Desk's ratelimit reached. Expected available in 1 second. Refer to Rate Limit section above.
1001 Insufficient permissions The user does not have sufficient permissions to execute the method.
1002 Invalid enumeration set value The enumeration set value is invalid for the specified field.

Authentication

All Paradigm API endpoints are considered private and require authentication.

Paradigm uses token-based authentication for API access to both the RESToverHTTP and JSON-RPCoverWebSocket API endpoints.

As an additional protection measure against replay attacks in environments where SSL trust is not properly configured, Paradigm requires all RESToverHTTP requests to be signed using your Paradigm API Key's <secret-key>.

Important Notes:

There are a number of Authentication methods available across both the RESToverHTTP and JSON-RPCoverWebSocket interfaces, these include:

Error Codes

The following error codes relate to Authentication Errors:

Code Message Meaning
401 API Key is not enabled or has been revoked. Paradigm API Key is Inactive or has been Deleted.
401 Invalid API Access Key. Paradigm API Access Key is invalid or incorrect.
403 Request signature verification failed. Paradigm API Secret Key is invalid, incorrect or you have not properly created the signature.

Generating a Paradigm API Key

Before accessing any RESToverHTTP or JSON-RPCoverWebSocket API endpoints, you must generate the necessary Paradigm API credentials. This can be accomplished via the Paradigm Admin Dashboard.

You use the same Paradigm API <access-key> & <secret-key> to authenticate requests for all Paradigm products.

Live Environment

Paradigm Admin Dashboard URL: https://admin.chat.paradigm.co/

Test Environment

Paradigm Admin Dashboard URL: https://admin.test.paradigm.co/

Once Created:

When you have generated Paradigm API credentials, you will be presented with two keys:

  1. Access Key: used to authenticate the API.
  2. Secret Key: used to sign requests against the API.

Be sure to save these two keys somewhere secure as both the Access Key and the Secret Key will only be visible once during creation.

If you lose either the <access-key> or the <secret-key>, you will need to generate a new Paradigm API Key via the Admin Dashboard.

Token-based Authentication

Only the <access-key> is needed for authenticating requests. The different methods are presented below in order of our preference.

HTTP Header

Authorization example with a HTTP Header

{
    "Authorization": "Bearer SXDlhLKYX6GH6InhBxcCzoW4"
}

When possible, authentication should be performed using the Authorization HTTP header. The header should supply the Paradigm API <access-key> in plain text, preceded by the text "Bearer ".

Authorization: Bearer <access-key>

In some cases, providing custom HTTP headers may not be possible. This is particularly true when connecting to JSON-RPCoverWebSockets via browser APIs.

In these cases, the Paradigm API Key Access Key may be provided by a special HTTP cookie. The cookie should be defined as follows:

Paradigm-API-Key = <access-key>

Query String Parameter (for JSON-RPCoverWebSocket connections only)

In the unlikely scenario that you are unable to use HTTP headers or Cookies for authentication against the JSON-RPCoverWebSocket API, Paradigm supports a special HTTP query parameter.

The query parameter can be provided as part of the WebSocket connection URL.

Live Environment | URL Examples

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.chat.paradigm.co/v1/drfq/?api-key=<access-key>

GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.chat.paradigm.co/v1/grfq/?api-key=<access-key>

Test Environment | URL Examples

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.test.paradigm.co/v1/drfq/?api-key=<access-key>

GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.test.paradigm.co/v1/grfq/?api-key=<access-key>

Signing Requests

Paradigm requires all RESToverHTTP requests to be signed.

GET RESToverHTTP example demonstrating signing of requests

# A GET RESToverHTTP sample demonstrating the generation of signatures and signing of requests.

import base64
import hmac
import json
import time
from urllib.parse import urljoin

import requests


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)

    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)

    return timestamp, signature


access_key = '<access-key>'
secret_key = '<secret-key>' 
host = 'https://api.test.paradigm.co'

# GET example
method = b'GET'
path = b'/v1/drfq/instruments/'
body = b''

timestamp, signature = sign_request(secret_key, method, path, body)
headers = {
    'Authorization': 'Bearer {}'.format(access_key),
    'Paradigm-API-Timestamp': timestamp,
    'Paradigm-API-Signature': signature,
}
url = urljoin(host, path.decode())
response = requests.get(url, headers=headers)
print(response.status_code)
print(response.text)

POST RESToverHTTP example demonstrating signing of requests

# A POST RESToverHTTP sample demonstrating the generation of signatures and signing of requests.

import base64
import hmac
import json
import time
from urllib.parse import urljoin

import requests


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)

    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)

    return timestamp, signature


access_key = '<access-key>'
secret_key = '<secret-key>' 
host = 'https://api.test.paradigm.co'

# POST example
method = b'POST'
path = b'/v1/echo/'
data = {'message': 'hello'}
body = json.dumps(data).encode('utf-8')

timestamp, signature = sign_request(secret_key, method, path, body)
headers = {
    'Authorization': 'Bearer {}'.format(access_key),
    'Paradigm-API-Signature': signature,
    'Paradigm-API-Timestamp': timestamp,
    'Accept': 'application/json',
}
url = urljoin(host, path.decode())
response = requests.post(url, headers=headers, json=data)
print(response.status_code)
print(response.text)

Important Note: Signing is not currently supported for JSON-RPCoverWebSocket API endpoints.

Request signatures are generated by applying the HMAC-SHA256 function to your Paradigm API <secret-key> and a concatenated message consisting of the request timestamp, request method, request path, query parameters, and body. The key provided to the HMAC function must be the base64-decoded version of the <secret-key>. The signature must then be base64-encoded and passed via a special header value.

Some important considerations are:

Once the signature is generated, the timestamp and signature should be provided as HTTP headers:

Header Name Header Value
Paradigm-API-Signature The generated signature
Paradigm-API-Timestamp The timestamp used when generating the signature

Note: Signed requests are only valid for 30 seconds from when the timestamp is captured. Requests received after the 30 second window are rejected.

JSON-RPC over WebSocket

JSON-RPC

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. It uses JSON (RFC 4627) as the data format.

All member names exchanged between the Client and the Server that are considered for matching of any kind should be considered to be case-sensitive. The Client is defined as the origin of Request objects and the handler of Response objects. The Server is defined as the origin of Response objects and the handler of Request objects. A trader using the API can fill the role of both the Client and the Server depending on the Request.

Error Codes

The following error codes relate to establishing a JSON-RPCoverWebSocket connection:

Code Meaning
HTTP 403 An invalid or incorrect Paradigm API Access Key was used to authenticate the JSON-RPCoverWebSocket connection.
HTTP 403 Incorrect connection query string used.

Cancel on Disconnect

Cancel on Disconnect mode is enabled on all JSON-RPCoverWebSocket connections by default. Cancel on Disconnect mode will cancel all outstanding RFQs (solely for DRFQ) and Quotes (DRFQ+GRFQ) that have been sent with the Paradigm API Key used to authenticate the WebSocket session when all associated WebSocket connections disconnect.

If multiple WebSocket connections are authenticated with the same API Key at the same time, then RFQs (solely for DRFQ) and Quotes (DRFQ+GRFQ) will only be canceled when the last connection with Cancel on Disconnect mode enabled disconnects.

To disable Cancel on Disconnect mode, specify cancel_on_disconnect=false as a query string parameter when connecting to the JSON-RPCoverWebSocket interface.

Cancel on Disconnect mode is shared across all JSON-RPCoverWebSocket interface connections on Paradigm irrespective of the product specific URL being used. This meaning, unless you expliticly specify cancel_on_disconnect=false, all of your JSON-RPCoverWebSocket connections dropping will cancel all actively created RFQs and Quotes in DRFQ and in all Quotes in GRFQ.

Live Environment | Cancel on Disconnect Examples

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.chat.paradigm.co/v1/drfq/?api-key=<access-key>&cancel_on_disconnect=false

GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.chat.paradigm.co/v1/grfq/?api-key=<access-key>&cancel_on_disconnect=false

Test Environment | Cancel on Disconnect Examples

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.test.paradigm.co/v1/drfq/?api-key=<access-key>&cancel_on_disconnect=false

GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.test.paradigm.co/v1/grfq/?api-key=<access-key>&cancel_on_disconnect=false

Request Objects

An example of a JSON-RPCoverWebSocket Request message

{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "subscribe",
    "params": {
        "channel": "rfq"
    }
}

A RPC call is represented by sending a Request object to a Server.

The Request object has the following members:

Member Type Req Description
id string or number N An identifier established by the Client. The id is omitted if the method is a Notification.
jsonrpc string Y The version of the JSON-RPC protocol. Always "2.0".
method string Y The name of the method to be invoked.
params object N The parameter values to be used during the invocation of the method. This field may be omitted if the method has no parameters.

Response Objects

An example of a Successful Response message

{
    "id": "1",
    "jsonrpc": "2.0",
    "result": [
        "rfq",
        "trade"
    ]
}

An example of an Erroneous Response message

{
    "id": "1",
    "jsonrpc": "2.0",
    "error": {
        "code": -32601,
        "message": "method not found",
        "data": {
           "method": "unsubscribe-all",
           "timestamp": 1597326842.415
        }
    }
}

When a RPC call is made, the Server replies with a Response, except for in the case of Notifications. The Response is expressed as a single JSON Object, with the following members:

Member Type Req Description
id string or number N The same value of the id field specified on the Request object. The value is null if there is an error parsing the Request object. The value is omitted in a Notification.
jsonrpc string Y The version of the JSON-RPC protocol. Always "2.0".
result object N The result of a successful request. The value is determined by the specific method invoked. Not present if there is an erroneous result.
error Error object N The result of an erroneous request. Not present if there is a successful result.
> code number N Error code.
> message string N Error message.
> data object N Array of information relating to error.
>> method string N Erroneous request method.
>> timestamp decimal N The time the error occurred as the number of unix milliseconds since epoch (January 1, 1970).

Session Methods

heartbeat

An example of a JSON-RPCoverWebSocket heartbeat Request Object

{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "heartbeat"
}

An example of a JSON-RPCoverWebSocket heartbeat Response Object

{
    "id": 1,
    "jsonrpc": "2.0"
}

The client is required to regularly send heartbeat Requests to the user over a WebSocket connection at least once every 10 seconds.

If the user does not send a heartbeat in a given 10 second window, the WebSocket connection will be closed by Paradigm.

Paradigm will respond to a heartbeat Request with a heartbeat Response.

Note: The Request does not have a params object and the Response does not have a results object.

Error Codes

The following error code relates to maintaining a heartbeat:

Code Meaning
4005 Paradigm did not receive a heartbeat from the WebSocket connection within the past 10 seconds.

Subscription Methods

Subscriptions work as Notifications, so users will automatically (after subscribing) receive messages from the server.

They are the primary means through which you should intend to receive updates with regards to RFQs, Quotes, Orders (GRFQ) and Trades.

Subscriptions are only available through WebSockets as these are sent asynchronously from Paradigm to the user as they happen.

Subscription Notification objects have the following members:

Member Type Req Description
jsonrpc string Y Always "2.0".
method string Y Always subscription.
params object Y Array of returned data.
> channel string Y The name of the channel.
> data object Y Data specific to the channel.

subscribe

An example of a subscribe Request Object

{
   "id": 123,
   "jsonrpc": "2.0",
   "method": "subscribe",
   "params": {
            "channel": "rfq"
   }
}

An example of a subscribe Response Object

{
    "id": 123,
    "jsonrpc": "2.0",
    "result": [
               "rfq",
               "trade"
    ]
}

For DRFQ, there are four subscription channels you can subscribe to: rfq, quote, trade, and trade_confirmation.

For GRFQ, there are six subscription channels you can subscribe to: rfq, quote_book, order, quote, trade, and trade_tape.

To subscribe to multiple channels, send a separate subscribe request for each channel.

Note: The Response result is a JSON array of all channels currently subscribed to (DRFQ+GRFQ).

The Request params object has the following members:

Member Type Req Description
channel string Y The channel to subscribe to.
data object N An channel-specific object that specifies parameters for the channel.

unsubscribe

An example of an unsubscribe Request Object

{
   "id": 123,
   "jsonrpc": "2.0",
   "method": "unsubscribe",
   "params": {
      "channel": "rfq"
   }
}

An example of an unsubscribe Response Object

{
   "id": 123,
   "jsonrpc": "2.0",
   "result": [
            "trade"     
   ]
}

To unsubscribe from multiple channels, send a separate unsubscribe request for each channel.

Note: The Response result is a JSON array of all channels currently subscribed to.

The Request params object has the following members:

Member Type Req Description
channel string Y The channel to unsubscribe from.

Notification Channels

A Notification is a Request object without an id member. A Request object that is a Notification signifies the Client's lack of interest in the corresponding Response object, and as such no Response object needs to be returned to the client. The Server must not reply to a Notification, including those that are within a batch request.

Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such, the Client would not be aware of any errors (like e.g. "Invalid params", "Internal error").

The Notification Channels are the primary means by which your solution should be expected to be updated with regards to RFQs, Quotes, Orders(GRFQ) and Trades.

Key Note: DRFQ, and GRFQ are separate products with separate JSON-RPCoverWebSocket subscriptions required. You must subscribe to the specific channels of each product you would like to receive notifications from.

DRFQ WebSocket Notification Channels

There are four DRFQ JSON-RPCoverWebSocket notification channels:

GRFQ WebSocket Notification Channels

There are six GRFQ JSON-RPCoverWebSocket notification channels:

Shared - REST Endpoints

The following REST Endpoints have no Product Identifier in the Connection URL as they are shared across the Paradigm API.

[POST] /echo/

/echo/ Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/echo/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

const inputBody = '{
  "message": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Authorization':'Bearer <access-key>'
};

fetch('https://api.test.paradigm.co/v1/echo/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json

# installed
import requests


access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /echo/
method = 'POST'
path = '/v1/echo/'

body = b''

payload = {
            "message": "this is a test echo message"
            }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Authorization": []string{"Bearer <acces-key>"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/echo/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

/echo/ Response example

{
  "message": "this is a test echo message"
}

A [POST] /echo/ request returns the message specified in the request.

It is designed to allow users to test their authentication as well as connection to Paradigm's API.

Parameters

Name In Type Required Description
body body object true none
message body string false none

Response Schema

Status Code 200

Name Type Required Description
message string true Returns the string from the request.

DRFQ - API Workflows

We have Auto-Market Makers running on our Test environment. You are able to request any RFQ from them and they will respond with a number of quotes promptly.

Their desk names are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2". They are apart of the 'LP' counterparty list returned from [GET] /counterparties/.

High Level

DRFQ is centred around the concepts of "RFQs", "Quotes" and "Trades":

At a high level, the DRFQ workflow is:

  1. Taker creates an RFQ and chooses which counterparties to send it too.
  2. Maker(s) quotes the RFQ.
  3. Taker receives the quote(s).
  4. Taker chooses to execute upon the best quote and the trade is sent to the underlying venue for clearing & settlement.
  5. Taker & Maker receive confirmation that the trade's execution has successfully cleared & settled or been rejected by the underlying venue.

Key DRFQ Concepts

In DRFQ,

Taker's Perspective

Important Note: Both the Taker and the Maker will receive all updates through the JSON-RPCoverWebSockets Notification channels for events relating to RFQs, Quotes, and Trades.

  1. Taker creates an RFQ using [POST] /rfq/create/. You can pull available instruments from [GET] /instruments/ and counterparties from [GET] /counterparties/.
  2. Taker is able to cancel an RFQ if they wish to do so with [POST] /rfq/cancel/.
  3. Maker, who is a requested counterparty to the RFQ, and is notified over the rfq JSON-RPCoverWebSockets Notification channel, is then able to provide a quote to the RFQ.
  4. Taker, who will be notified of quotes on the quote JSON-RPCoverWebSockets Notification channel, is able to execute upon the best quote with [POST] /quote/execute/.
  5. Taker will receive confirmation of the trade's successful/rejected clearing & settlement on the trade_confirmation JSON-RPCoverWebSockets Notification channel.
  6. Taker will also receive confirmation of the trade being completed on the trade JSON-RPCoverWebSockets Notification channel as well as all other DRFQ trades on Paradigm.

Maker's Perspective

Important Note: Both the Taker and the Maker will receive all updates through the JSON-RPCoverWebSockets Notification channels for events relating to RFQs, Quotes,and Trades.

  1. Taker will create an RFQ and the Maker will be notified on the rfq JSON-RPCoverWebSockets Notification channel.
  2. Maker is able to create a one way quote using [POST] /quote/create/.
  3. Maker is able to cancel an existing quote with [POST] /quote/cancel/. A Maker must cancel any existing quote on an RFQ before they are able to update their quote.
  4. Taker chooses to execute upon an available quote.
  5. Maker will receive an update of their Quote being executed upon from the quote JSON-RPCoverWebSockets Notification channel with the status pending_fill.
  6. Maker will receive finality around successful/rejected clearing & settlement from the trade_confirmation JSON-RPCoverWebSockets Notification channel.
  7. Maker will receive confirmation of the trade being completed on the trade JSON-RPCoverWebSockets Notification channel as well as all other DRFQ trades on Paradigm.

DRFQ - Code Examples

Reach out if you ever need any help! We are more than happy to help.

You will need to update the provided Code Examples with your own Paradigm Access Key and Secret Key.

You can find all existing examples on our github: https://github.com/tradeparadigm/code-samples

Note: All examples in this section are in Python3.

JSON-RPCoverWebSockets

Authentication + Subscribe & Unsubscribe to Notification Channels

  1. Authenticate, establish a heartbeat and Subscribe to the rfq, quote, trade, and trade_confirmation JSON-RPCoverWebSockets Notification Channels.

RESToverHTTP

All Interactions

Takers and Makers should both be subscribed to the rfq, quote, trade, and trade_confirmation JSON-RPCoverWebsockets Notification channels to receive the required information to use the RESToverHTTP endpoints.

Both Makers and Takers

  1. [GET] - /instruments/ - A simple code example demonstrating how to pull the instruments available on Paradigm.
  2. [GET] - /counterparties/ - A simple code example demonstrating how to pull your available counterparties' information.
  3. [GET] - /rfq/ - A simple code example demonstrating how to pull information relating to RFQs you were aparty to.
  4. [GET] - /rfq/ - A more comprehensive example demonstrating pagination and the use of parameters.

Taker Specific

  1. [POST] - /rfq/create/ - A simple code example demonstrating how to create an RFQ.
  2. [POST] - /rfq/cancel/ - A simple code example demonstrating how to cancel an RFQ.
  3. [POST] - /quote/execute/ - A simple code example demonstrating how to execute a provided Quote.

Maker Specific

  1. [POST] - /quote/create/ - A simple code example demonstrating how to create a Quote.
  2. [POST] - /quote/cancel/ - A simple code example demonstrating how to cancel an already created Quote.

Auto-Market Makers

We encourage you to RFQ all counterparties marked as an "LP" from the [GET] /counterparties/ as this includes all of Paradigm's Auto-Market Makers.

The desk names of some of the Auto-Marker Makers are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2" on the Test environment.

If you would like to run your own Auto-Market Maker, here is a link to the code and dockerfile: https://github.com/tradeparadigm/code-samples/tree/main/python/api/market_maker

Auto-Takers

We also have Auto-Taker code examples to help Maker's test their solutions.

  1. Auto-Taker-Creator - Creates RFQs every 5 seconds: https://github.com/tradeparadigm/code-samples/tree/main/python/api/auto_taker
  2. Auto-Taker-Executor - Executes the best received quote every 5 seconds: https://github.com/tradeparadigm/code-samples/tree/main/python/api/market_taker

DRFQ - WebSocket Notification Channels

rfq

An example, as the Taker, of the rfq notification received when an RFQ is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611022135830.395,
         "desk":"DSK2",
         "rfq_id":22523,
         "account":{
            "name":"ParadigmTestTwo"
         },
         "client_order_id":"",
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "instrument":"BTC-20JAN21-36000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"ACTIVE",
         "valid_until":1611108535827.299,
         "counterparties":[
            "DSK1",
            "DSK3",
            "DSK4",
            "DSK5"
         ]
      }
   }
}

An example, as the Taker, of the rfq notification received when an RFQ is canceled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611022135830.395,
         "desk":"DSK2",
         "rfq_id":22523,
         "account":{
            "name":"ParadigmTestTwo"
         },
         "client_order_id":"",
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "instrument":"BTC-20JAN21-36000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"CANCELED",
         "valid_until":1611108535827.299,
         "counterparties":[
            "DSK1",
            "DSK3",
            "DSK4",
            "DSK5"
         ]
      }
   }
}

An example, as the Taker, of the rfq notification received when an RFQ is filled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611023461827.417,
         "desk":"DSK2",
         "rfq_id":22527,
         "account":{
            "name":"ParadigmTestTwo"
         },
         "client_order_id":"",
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"FILLED",
         "valid_until":1611023489464.3481,
         "counterparties":[
            "DSK1",
            "DSK3",
            "DSK4",
            "DSK5"
         ]
      }
   }
}

An example, as the Maker, of the rfq notification received when an RFQ is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611022135830.395,
         "desk":"DSK2",
         "rfq_id":22523,
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "instrument":"BTC-20JAN21-36000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"ACTIVE",
         "valid_until":1611108535827.299
      }
   }
}

An example, as the Maker, of the rfq notification received when an RFQ is canceled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611022135830.395,
         "desk":"DSK2",
         "rfq_id":22523,
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "instrument":"BTC-20JAN21-36000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"CANCELED",
         "valid_until":1611108535827.299
      }
   }
}

An example, as the Maker, of the rfq notification received when an RFQ is filled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "created":1611023461827.417,
         "desk":"DSK2",
         "rfq_id":22527,
         "legs":[
            {
               "instrument":"BTC-19JAN21-32000-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "status":"FILLED",
         "valid_until":1611023489464.3481
      }
   }
}

An update to an RFQ sent as an RFQ object with members the user is permissioned for. Users are sent RFQs in which they are a counterparty to.

Each RFQ has a globally unique identifier with the rfq_id member.

The most recently received Notification with the same rfq_id is the current state of the RFQ.

Important Note: Quotes in response to the RFQs are not sent through the rfq notifications channel, but through the quote notifications channel.

The response "params" data object has the following members:

Member Type Req Description
channel string Y The notification channel the message was delivered upon.
data array Y An arrary of information relating to the specific RFQ.
> created decimal Y The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
> desk string N The Desk Name of Taker.
> rfq_id number Y The unique identifier of the RFQ. Paradigm creates this value.
> account object N An array present as the Taker detailing the Paradigm API Key Name or "CME" related information.
>> name string N Name of the Paradigm API Key used.
>> clearing_account_name string N Clearing Account Name related to trades executed upon the "CME".
>> trader_id string N Trader ID related to trades executed upon the "CME".
> client_order_id string Y User determined unique identifier. Empty if the RFQ is created using the GUI.
> legs array of objects Y An array of instruments that comprise the RFQ.
>> instrument string Y None
>> price decimal N The price of the leg if specified.
>> quantity decimal Y The number of contracts of the leg.
>> venue string Y The venue the RFQ will be executed on.
> status string Y The status of the RFQ. Values can include: ACTIVE, CANCELED, FILLED.
> counterparties [strings] N As the Taker, the other counterparties involved in the RFQ.
> valid_until decimal N The time the RFQ expires in the number of milliseconds since epoch (January 1, 1970).

quote

An example, as the Taker, of the quote notification received when a Quote is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "desk":"DSK1",
         "valid_until":1611024209158.0242,
         "created":1611024112328.771,
         "legs":[
            {
               "price":0.1294,
               "quantity":25.0,
               "instrument":"BTC-19JAN21-32000-C",
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "price":0.0302,
               "quantity":25.0,
               "instrument":"BTC-20JAN21-36000-C",
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quote_id":84032,
         "rfq_id":22530,
         "side":"SELL",
         "status":"ACTIVE"
      }
   }
}

An example, as the Taker, of the quote notification received when a Quote is canceled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "desk":"DSK1",
         "valid_until":"None",
         "created":1611024112328.771,
         "legs":[
            {
               "price":"None",
               "quantity":25.0,
               "instrument":"BTC-19JAN21-32000-C",
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "price":"None",
               "quantity":25.0,
               "instrument":"BTC-20JAN21-36000-C",
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quote_id":84032,
         "rfq_id":22530,
         "side":"SELL",
         "status":"CANCELED"
      }
   }
}

An example, as the Taker, of the quote notification received when a Quote is executed

{
   "desk":"DSK2",
   "valid_until":1616995320247.1162,
   "created":1616995218247.1162,
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "price":55084.4,
         "quantity":20000.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "quote_id":1541710,
   "rfq_id":244484,
   "side":"SELL",
   "status":"PENDING_FILL"
}

An example, as the Maker, of the quote notification received when a Quote is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "desk":"DSK1",
         "valid_until":1611024209158.0242,
         "account":{
            "name":"ParadigmTestOne"
         },
         "client_order_id":"DSK1738007604",
         "created":1611024112328.771,
         "legs":[
            {
               "price":0.1294,
               "quantity":25.0,
               "instrument":"BTC-19JAN21-32000-C",
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "price":0.0302,
               "quantity":25.0,
               "instrument":"BTC-20JAN21-36000-C",
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quote_id":84032,
         "rfq_id":22530,
         "side":"SELL",
         "status":"ACTIVE"
      }
   }
}

An example, as the Maker, of the quote notification received when a Quote is canceled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "desk":"DSK1",
         "valid_until":"None",
         "account":{
            "name":"ParadigmTestOne"
         },
         "client_order_id":"DSK1738007604",
         "created":1611024112328.771,
         "legs":[
            {
               "price":"None",
               "quantity":25.0,
               "instrument":"BTC-19JAN21-32000-C",
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "price":"None",
               "quantity":25.0,
               "instrument":"BTC-20JAN21-36000-C",
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quote_id":84032,
         "rfq_id":22530,
         "side":"SELL",
         "status":"CANCELED"
      }
   }
}

An example, as the Maker, of the quote notification received when a Quote is filled

{
   "desk":"DSK2",
   "valid_until":1616995442399.624,
   "account":{
      "name":"ParadigmTestTwo"
   },
   "client_order_id":"DSK2572194009",
   "created":1616995359399.624,
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "price":55063.79,
         "quantity":20000.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "quote_id":1541712,
   "rfq_id":244485,
   "side":"SELL",
   "status":"PENDING_FILL"
}

An update to a Quote sent in response to an RFQ sent as a Quote object with members the user is permissioned for. Users are sent quotes in which they are a counterparty to.

Each Quote has a globally unique identifier with the quote_id member.

The most recently received Notification with the same quote_id is the current state of the RFQ & Quote.

As Takers, you are able to see all Quotes provided to you and the desk name of the counterparty.

As Makers, you are only able to see your Quote and the desk name of the Taker if the RFQ is on a disclosed basis.

The response params data object has the following members:

Member Type Req Description
channel string Y The channel name the message was received upon.
data array Y An array containing information relating to the Quote(s) of a specific RFQ.
> desk string N The Paradigm desk name of the Taker.
> valid_until decimal Y The time at which the Quote expires in the number of milliseconds since epoch (January 1, 1970).
> created decimal Y The time the Quote was executed in the number of milliseconds since epoch (January 1, 1970).
> legs array of objects Y An array of legs that comprise the RFQ.
>> price decimal Y The price of the leg if one is quoted
>> quantity decimal Y The quantity of the leg if one is quoted.
>> side string Y The direction of the leg. Values can be BUY and SELL.
>> venue string Y The venue which the RFQ will be executed upon.
> price decimal N The calculated spread price, if applicable.
> quote_id string Y The unique identifier of the Quote. Paradigm creates this value.
> rfq_id string Y The unique identifier of the RFQ. Paradigm creates this value.
> side string Y None

trade

An example, as the Taker or the Maker, of the trade notification received when a trade is completed

{
   "created":1616995466611.969,
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "price":54608.22,
         "quantity":20000.0,
         "venue":"DBT",
         "trade_id":44290
      }
   ],
   "price":54608.22,
   "quote_id":1541713,
   "rfq_id":244486
}

Trades are sent for all executions on the Paradigm platform after the trade is confirmed by the Exchange.

The response params data object has the following members:

Member Type Req Description
channel string Y The channel upon which the notification was delivered.
data array Y An array of information relating to the completed Trade of the RFQ.
> created decimal Y The time the Trade was executed in the number of milliseconds since epoch (January 1, 1970).
> legs array of objects Y An array of legs that comprise the RFQ.
>> instrument string Y None
>> price decimal Y The price of the leg.
>> quantity decimal Y The number of contracts of the leg.
>> venue string Y The venue the RFQ was executed on.
>> trade_id decimal Y The unique identifier of the trade. Paradigm determines this.
> price decimal N The calculated spread price, if applicable.
> quote_id string Y The unique identifier of the Quote executed. Paradigm determines this.
> rfq_id string Y The unique identifier of the RFQ executed. Paradigm determines this.

trade_confirmation

An example, as the Taker or the Maker, of the trade_confirmation notification received when a trade is completed

{
   "account":{
      "name":"ParadigmTestTwo"
   },
   "created":1616995466611.969,
   "desk":"DSK2",
   "exec_id":"68454170",
   "instrument":"BTC-PERPETUAL",
   "venue":"DBT",
   "price":54608.22,
   "quantity":20000.0,
   "side":"BUY",
   "quote_id":1541713,
   "rfq_id":244486,
   "trade_id":44290
}

Trade Confirmations are sent for executions the user is involved in when the Exchange confirms the Trade.

Trade Confirmations are published for each individual leg executed.

The Request params data object has the following members:

Member Type Req Description
channel string Y The notification channel the message was received upon.
data array Y An array of trade confirmation information relating to a specific RFQ.
> account object N An array present as the Taker detailing the Paradigm API Key Name or "CME" related information.
>> name string N Name of the Paradigm API Key used.
>> clearing_account_name string N Clearing Account Name related to trades executed upon the "CME".
>> trader_id string N Trader ID related to trades executed upon the "CME".
> created decimal Y The time the instrument was executed at the exchange in the number of milliseconds since epoch (January 1, 1970).
> desk string Y The Paradigm Desk Name involved in the trade (your API Key's desk).
> exec_id string N Venue-specific field. The venue's unique identifier for the trade. The venue determines this value.
> instrument string Y The instrument name executed.
> venue string Y The venue the trade was executed on.
> price number Y The execution price of the instrument name.
> quantity number Y The number of contracts executed.
> side string Y The direction of the trade. Valid values can include "BUY" and "SELL".
> quote_id string Y The unique identifier for the quote that corresponds to the trade. Paradigm determines this value.
> rfq_id string Y The unique identifier for the RFQ that corresponds to the trade. Paradigm determines this value.
> trade_id string Y The unique identifier for the trade that corresponds to the trade. Paradigm determines this value.

DRFQ - REST Endpoints

[GET] /instruments/

/instruments/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/drfq/instruments/ \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/instruments/',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});


# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json

# installed
import requests


access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# GET /instruments/
method = 'GET'
path = '/v1/drfq/instruments/?venue=DBT'

body = b''

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.get(urljoin(host, path),
                        headers=headers)

print(response.status_code)
print(response.text)

package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("GET", "http://api.test.paradigm.co/v1/drfq/instruments/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [GET] /instruments/ request returns the instruments that are supported for trading on Paradigm. They follow the same naming conventions as the venue they are traded upon.

If the resulting returned list of instruments is too large, it is divided into pages. Each request returns a single page.

Parameters

Name In Type Required Description
asset query string false Type of currency. Valid values include "BCH", "BTC" or "ETH".
cursor query string false The next or previous cursor from the paginated result set.
type query string false Type of instrument. Valid values include "FUTURE" or "OPTION".
venue query string false Venue to return instruments for. Value values include "BIT", "CME", or "DBT"

/instruments/ Response example

200 Response

{
   "count":895,
   "next":"c12dEx=",
   "results":[
      {
         "name":"BTC-19JAN21-32000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-32000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-34000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-34000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-35000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-35000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-36000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-36000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-36500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-36500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-37000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-37000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-38000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-38000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-40000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-19JAN21-40000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-36000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-36000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-37000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-37000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-38000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-38000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-40000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-20JAN21-40000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-25000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-25000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-25500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-25500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-26000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-26000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-26500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-26500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-27000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-27000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-27500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-27500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-28000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-28000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-28500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-28500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-29000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-29000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-29500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-29500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-30000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-30000-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-30500-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-30500-C",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-31000-P",
         "type":"OPTION",
         "venue":"DBT"
      },
      {
         "name":"BTC-22JAN21-31000-C",
         "type":"OPTION",
         "venue":"DBT"
      }
   ]
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
count number Y None Number of available instruments.
next string Y None Cursor to use to retrieve the next page of results. Equal to "null" if there are no more pages.
results array of objects Y None Array of objects of instruments and their details.
> name string Y None Name of the instrument.
> type string Y None Type of instrument.
> venue string Y None Venue the instrument is available upon.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 101 Unknown type An invalid Type key value was provided.
400 102 Unknown venue An invalid Venue key value was provided.
404 Invalid cursor An invalid cursor value was provided.

[GET] /counterparties/

/counterparties/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/drfq/counterparties/ \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/counterparties/',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json

# installed
import requests


access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# GET /counterparties/
method = 'GET'
path = '/v1/drfq/counterparties/'

body = b''

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.get(urljoin(host, path),
                        headers=headers)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("GET", "http://api.chat.paradigm.co/counterparties/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [GET] /counterparties/ request returns the counterparties that the user is permissioned to trade with on Paradigm.

If the resulting returned list of counterparties is too large, it is divided into pages. Each request returns a single page.

Parameters

Name In Type Required Description
cursor query string false The next or previous cursor from the paginated result set.
type query string false Use 'LP' to filter only Liquidity Providers.

/counterparties/ Response example

200 Response

{
   "count":176,
   "next":"c12dEx=",
   "results":[
      {
         "firm_name":"0420",
         "ticker":"APR",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"0420",
         "ticker":"MAY",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"0420",
         "ticker":"MAY01",
         "venues":[
            "CME"
         ]
      },
      {
         "firm_name":"062020",
         "ticker":"JUN11",
         "venues":[
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"062020",
         "ticker":"05J2",
         "venues":[
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"062020",
         "ticker":"05J3",
         "venues":[
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"17bits",
         "ticker":"17B",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"Alpha5",
         "ticker":"ALP5",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"SHIVA",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"SAMBO",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"RUDRA",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"HARA",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"NATA",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"BHOLE",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"KEDAR",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"APEX(Stage)",
         "ticker":"BADRI",
         "venues":[
            "BIT"
         ]
      },
      {
         "firm_name":"Bloomberg",
         "ticker":"CRYPT",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Bloomberg",
         "ticker":"GBLOP",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"Champagne Trust",
         "ticker":"DOM",
         "venues":[
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"DARKO",
         "ticker":"DARKO",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"DARKO1",
         "ticker":"DARK1",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"Dragonfly Capital",
         "ticker":"DFLY",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP10",
         "ticker":"DSK10",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP2",
         "ticker":"DSK2",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP3",
         "ticker":"DSK3",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP4",
         "ticker":"DSK4",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP5",
         "ticker":"DSK5",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP6",
         "ticker":"DSK6",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP7",
         "ticker":"DSK7",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP8",
         "ticker":"DSK8",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP9",
         "ticker":"DSK9",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"EP99",
         "ticker":"DSK99",
         "venues":[
            "BIT",
            "CME",
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK4",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK5",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK6",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK7",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK8",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK9",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK10",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK11",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK12",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK13",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK14",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK18",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK19",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK20",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK21",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK22",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK23",
         "venues":[
            "DBT"
         ]
      },
      {
         "firm_name":"Epam_Maker",
         "ticker":"MAK24",
         "venues":[
            "DBT"
         ]
      }
   ]
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
count number Y None Number of available counterparties.
next string Y None Cursor to use to retrieve the next page of results. Equal to "null" if there are no more pages.
results array of objects Y None Array of objects of counterparties.
> firm_name string Y None Name of counterparty on Paradigm.
> ticker string Y None Desk Name on Paradigm.
> venues [string] Y None List of strings of venue counterparty is available upon.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
404 Invalid cursor An invalid cursor value was provided.

[POST]/rfq/create/

/rfq/create/ Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/drfq/rfq/create/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = '{
  "account": {
    "name": "string",
    "clearing_account_name": "string",
    "trader_id": "string"
  },
  "client_order_id": "string",
  "anonymous": true,
  "counterparties": [
    "strin"
  ],
  "expires_in": 1800,
  "legs": [
    {
      "price": "string",
      "quantity": "string",
      "side": "BUY",
      "instrument": "string",
      "venue": "BIT"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/rfq/create/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json
from random import randint

# installed
import requests

access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /rfq/create/
method = 'POST'
path = '/v1/drfq/rfq/create/'

body = b''

client_order_id_random = randint(1, 1000000000)
# print('Client_Order_Id: {}'.format(client_order_id_random))

payload = {
            "account": {
                        "name": "ParadigmTestTwo"
                        },
            "client_order_id": client_order_id_random,
            "anonymous": "false",
            "counterparties": [
                                "DSK4", "DSK5"
                                ],
            "expires_in": 120,
            "legs": [
                    {
                    "quantity": "25",
                    "side": "BUY",
                    "instrument": "BTC-31DEC21-36000-C",
                    "venue": "DBT"
                    }
                    ]
            }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)

package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/drfq/rfq/create/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [POST] /rfq/create/ request creates an RFQ.

An /rfq/create/ request has the following workflow:

  1. The Taker sends an /rfq/create/ request to Paradigm.
  2. Paradigm sends an /rfq/create/ response to the Taker.
    1. If the /rfq/create/ request is valid, the RFQ object is returned to the Taker.
    2. If the /rfq/create/ request is invalid, an Error object is returned to the Taker.
  3. If the /rfq/create/ request is valid, Paradigm sends a Notification on the rfq notification channel to the Taker & the counterparties listed in the RFQ specifying the details of the new RFQ.

Note: You are able to find the instrument names from the [GET] /instruments/ request or the name returned from the exchanges. You are able to pull counterparties desk tickers from [GET] /counterparties/. Takers are only able to RFQ up to 60 counterparties at the present moment.

The Auto-Market Makers on the Test Environment have the desk names are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2".

/rfq/create/ Body parameter example

{
  "account": {
              "name": "ParadigmTestTwo"
              },
  "client_order_id": 123,
  "anonymous": "false",
  "counterparties": [
                      "DSK4", "DSK5"
                      ],
  "expires_in": 120,
  "legs": [
          {
          "quantity": "25",
          "side": "BUY",
          "instrument": "BTC-31DEC21-36000-C",
          "venue": "DBT"
          }
          ]
  }

Parameters

Name In Type Required Description
account body object Y Object of Paradigm Account information
> name body string Y Paradigm API Key name.
> clearing_account_name body string N Required value if using "CME" as a venue.
> trader_id body string N Required value if using "CME" as a venue.
client_order_id body string Y Unique identifier created by the user.
anonymous body boolean N Submit RFQ on a disclosed or anonymous basis.
counterparties body [string] Y List of strings of the Desk Names of the other counterparties to the RFQ.
expires_in body integer N Length in seconds the RFQ is available for. Valid values are between 60-120.
legs body array of objects Y An array of objects containing each leg of the RFQ.
> price body decimal N Requested price of leg for hedge RFQs.
> quantity body decimal Y Number of contracts of the leg.
> side body string Y Direction of the RFQ leg. Valid values include "BUY" and "SELL".
> instrument body string Y Instrument name, for example: "BTC-PERPETUAL".
> venue body string Y Exchange to send the RFQ. Valid values include "DBT", "BIT", and "CME".

/rfq/create/ Response example

201 Response

{
   "created":1611033737572.134,
   "desk":"DSK2",
   "rfq_id":22534,
   "account":{
      "name":"ParadigmTestTwo"
   },
   "client_order_id":"769195219",
   "legs":[
      {
         "instrument":"BTC-31DEC21-36000-C",
         "quantity":25.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "status":"ACTIVE",
   "valid_until":1611033857557.6538,
   "counterparties":[
      "DSK4",
      "DSK5"
   ]
}

Response Schema

Status Code 201

Name Type Required Restrictions Description
created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
desk string Y None The desk name which created the RFQ.
rfq_id number Y None The unique identifier of the RFQ. This value is determined by Paradigm.
account object Y None An object of the account information relating to the creation of the RFQ.
> name string Y None The Paradigm API Key name.
> clearing_account_name string N None Only present if using "CME" as the venue.
> trader_id string N None Only present if using "CME" as the venue.
client_order_id string Y none Unique identifier created by user.
legs array of objects Y None Array of objects of the legs apart of the RFQ.
> instrument string Y None The leg's instrument name.
> price decimal N none Price of leg if a hedge has been added.
> quantity decimal Y None The number of contracts of the leg.
> side string Y None The Direction of leg. Valid values include "BUY" and "SELL".
> venue string Y None The Exchange the RFQ was created upon.
status string Y None The Status of the RFQ. Valid values include "ACTIVE", "CANCELED", "FILLED"
valid_until decimal Y None The time the RFQ will expire in the number of milliseconds since epoch (January 1, 1970).
counterparties [string] Y None List of strings of the other Counterparties apart of the RFQ.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 'Anonymous' key Must be a valid boolean. Anonymous key must be a valid boolean.
400 Future leg price is outside exchange price bands. The hedge leg's price is outside the exchange's accepted price bands.
400 1301 Duplicate client_order_id Non-Unique client_order_id value provided.
400 1302 Invalid account information Invalid account information provided.
400 1303 No counterparties specified No counterparties specified in request.
400 1304 Invalid counterparty Invalid or duplicate counterparty(ies) requested.
400 1305 Invalid expires_in Invalid expires_in value provided. Too small (<60) or too large.
400 1306 Invalid instrument Invalid instrument provided as apart of request.
400 1308 Invalid Price Invalid price provided as apart of request.
400 1309 Negative quantity Negative quantity value was provided as apart of request.
400 13010 Invalid quantity Invalid quantity specified in leg array.
400 1311 Unknown Venue Invalid venue provided as apart of request.
400 1312 Invalid price for instrument You are unable to request a price for single-leg instrument RFQ.
400 1313 Quantity below minimum block size Request RFQ below Exchange's set minimum block size.
400 1314 Maximum 60 counterparties allowed More than 60 counterparties requested to be apart of the RFQ.

[POST]/rfq/cancel/

/rfq/cancel/ Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/drfq/rfq/cancel/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = '{
  "rfq_id": 0
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/rfq/cancel/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json
from random import randint

# installed
import requests

access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /rfq/cancel/
method = 'POST'
path = '/v1/drfq/rfq/cancel/'

body = b''

client_order_id_random = randint(1, 1000000000)
# print('Client_Order_Id: {}'.format(client_order_id_random))

payload = {
            "rfq_id": 22535
            }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/drfq/rfq/cancel/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [POST] /rfq/cancel/ request cancels an exisitng RFQ you created.

An /rfq/cancel/ request has the following workflow:

  1. The creator of an RFQ sends a /rfq/cancel/ request to Paradigm.
  2. Paradigm sends an /rfq/cancel/ response to the creator.
    1. If the /rfq/cancel/ request is valid, the RFQ object is returned to the creator.
    2. If the /rfq/cancel/ request is invalid, an Error object is returned to the creator.
  3. If the /rfq/cancel/ request is valid, Paradigm sends a Notification on the quote notification channel to the counterparties with active Quotes specifying that the Quotes are now canceled.
  4. If the /rfq/cancel/ request is valid, Paradigm sends a Notification on the rfq notification channel to the counterparties aparty to the RFQ and other members of the user's desk specifying that the RFQ is now canceled.

/rfq/cancel/ Body parameter example

{
  "rfq_id": 22535
}

Parameters

Name In Type Required Description
body body object Y none
rfq_id body number Y The rfq_id value created by Paradigm.

/rfq/cancel/ Response example

200 Response

{
   "created":1611034695052.4731,
   "desk":"DSK2",
   "rfq_id":22535,
   "account":{
      "name":"ParadigmTestTwo"
   },
   "client_order_id":"641457979",
   "legs":[
      {
         "instrument":"BTC-31DEC21-36000-C",
         "quantity":25.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "status":"CANCELED",
   "counterparties":[
      "DSK4",
      "DSK5"
   ],
   "updated":1611034702624.0151
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
desk string Y None The Paradigm Desk Name of the creator of the RFQ.
rfq_id number Y None The RFQ unique identifier. This value is created by Paradigm.
account array Y None An array of attributes related to the account which created the RFQ.
> name string Y None The creator's Paradigm API Key name.
> clearing_account_name string N None Only present if using "CME" as a venue.
> trader_id string N Nnone Only present if using "CME" as a venue.
client_order_id string Y None Unique identifier created by user.
legs array of objects Y None Array of objects containing the leg information of the RFQ.
> instrument string Y None The leg's instrument name.
> price decimal N None Price of leg if a hedge has been added.
> quantity decimal Y None The number of contracts of the leg.
> side string Y None The Direction of leg. Valid values include "BUY" and "SELL".
> venue string Y None The Exchange the RFQ would have been executed on.
status string Y None The status of the RFQ. Valid values include "ACTIVE", "CANCELED", and "FILLED".
counterparties [string] Y None List of strings of the other counterparties involved in the RFQ.
updated decimal Y None The time the RFQ was last updated in the number of milliseconds since epoch (January 1, 1970).

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 1401 Unknown rfq_id Invalid rfq_id provided as apart of request.
400 1402 Too late to cancel. RFQ has already expired or been filled.

[GET] /rfq/

/rfq/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/drfq/rfq/ \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/rfq/',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json

# installed
import requests


access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# GET /rfq/
method = 'GET'
path = '/v1/drfq/rfq/?venue=DBT&asset=BTC'

body = b''

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.get(urljoin(host, path),
                        headers=headers)

print(response.status_code)
print(response.text)

package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("GET", "http://api.test.paradigm.co/v1/drfq/rfq/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [GET] /rfq/ request returns the current state of RFQs that the user is a counterparty to (either as the creator or the receiver).

If the resulting returned list of RFQs is too large, it is divided into pages. Each request can return a single page.

Parameters

Name In Type Required Description
client_order_id query string N The client's unique identifier for the RFQ.
cursor query string N The next or previous cursor from the paginated result set.
rfq_id query string N Paradigm's unique identifier for the RFQ.
status query string N The status of the RFQ. Values can include "ACTIVE", "CANCELED", and "FILLED".

/rfq/ Example response

200 Response

{
   "count":2441,
   "next":"c12dEx=",
   "results":[
      {
         "account":{
            "name":"ParadigmTestOne"
         },
         "client_order_id":"",
         "counterparties":[
            "MSTL1",
            "DSK2",
            "DSK3",
            "DSK4",
            "DSK5"
         ],
         "created":1608267227834.84,
         "desk":"DSK1",
         "fills":[

         ],
         "legs":[
            {
               "instrument":"BTC-18DEC20-13250-C",
               "quantity":25.0,
               "side":"SELL",
               "venue":"DBT"
            },
            {
               "instrument":"BTC-19DEC20-21125-C",
               "quantity":25.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quotes":[
            {
               "desk":"DSK5",
               "valid_until":null,
               "created":1608267227854.909,
               "legs":[
                  {
                     "price":null,
                     "quantity":25.0,
                     "instrument":"BTC-18DEC20-13250-C",
                     "side":"SELL",
                     "venue":"DBT"
                  },
                  {
                     "price":null,
                     "quantity":25.0,
                     "instrument":"BTC-19DEC20-21125-C",
                     "side":"BUY",
                     "venue":"DBT"
                  }
               ],
               "quote_id":25092,
               "rfq_id":18753,
               "side":"SELL",
               "status":"CANCELED"
            },
            {
               "desk":"DSK4",
               "valid_until":null,
               "created":1608267227869.377,
               "legs":[
                  {
                     "price":null,
                     "quantity":25.0,
                     "instrument":"BTC-18DEC20-13250-C",
                     "side":"SELL",
                     "venue":"DBT"
                  },
                  {
                     "price":null,
                     "quantity":25.0,
                     "instrument":"BTC-19DEC20-21125-C",
                     "side":"BUY",
                     "venue":"DBT"
                  }
               ],
               "quote_id":25093,
               "rfq_id":18753,
               "side":"SELL",
               "status":"CANCELED"
            }
         ]
      }

Response Schema

Status Code 200

Name Type Required Restrictions Description
count number Y None Number of available RFQs.
next string Y None Cursor to use to retrieve the next page of results. Equal to "null" if there are no more pages.
results array of objects Y None An array of objects of RFQs.
> account array Y None Array of information about the creator of the RFQ.
>> name string N None The Paradigm API Key name aparty to the RFQ.
>> clearing_account_name string N None "CME" venue clearing account name.
>> trader_id string N None "CME" venue trader_id value.
> client_order_id string Y None Client created unique identifier.
> counterparties [string] Y None Counterparties involved with the RFQ.
> created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
> desk string N None Paradigm Desk name of the RFQ creator.
> fills array of objects N None Array of objects of the fills.
> legs array of objects Y None Array of objects containing the legs of the RFQ.
>> instrument string Y None The leg's instrument name.
>> quantity decimal Y None The size in contracts of the leg.
>> side string Y None The Direction of the leg. Valid values include "BUY" and "SELL".
>> venue string Y None Venue of RFQ.
> quotes array of objects N None Array of objects containing the quotes provided for the RFQ.
>> desk string N None Paradigm Desk name of the Quote creator.
>> valid_until decimal Y None The time until the Quote expires in the number of milliseconds since epoch (January 1, 1970).
>> created decimal Y None The time the Quote was created in the number of milliseconds since epoch (January 1, 1970).
>> legs array of objects Y None An array of objects containing the Quotes of the individual legs.
>>> instrument string Y None The leg's instrument name.
>>> price decimal N None The price of the leg.
>>> quantity decimal N None The size in contracts of the leg.
>>> side string Y None The direction of the leg. Valid values include "BUY" and "SELL".
>>> venue string Y None The venue the RFQ would be executed on. Valid values include "DBT", "CME", and "BIT".
>> quote_id integer Y None The unique identifier of the quote. Paradigm determines this value.
>> rfq_id integer Y None Unqiue of the RFQ determined by Paradigm.
>> side string Y None Side being quoted. Valid values include "BUY" and "SELL".
>> status string Y None The status of the Quote. Valid values include "ACTIVE", "EXPIRED".

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 2103 Unavailable RFQ. Unavailable RFQ.
404 Invalid cursor. Invalid cursor value requested.

[POST]/quote/create/

/quote/create/ Request examples

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/drfq/quote/create/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = '{
  "account": {
    "name": "string",
    "clearing_account_name": "string",
    "trader_id": "string"
  },
  "client_order_id": "string",
  "expires_in": 10,
  "legs": [
    {
      "side": "BUY",
      "instrument": "string",
      "venue": "BIT",
      "price": "string",
      "quantity": "string"
    }
  ],
  "rfq_id": 0,
  "side":"SELL"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/quote/create/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json
from random import randint

# installed
import requests

access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /quote/create/
method = 'POST'
path = '/v1/drfq/quote/create/'

body = b''

client_order_id_random = randint(1, 1000000000)
# print('Client_Order_Id: {}'.format(client_order_id_random))

payload = {
            "account": {
                "name": "ParadigmTestOne"
            },
            "client_order_id": client_order_id_random,
            "expires_in": 60,
            "legs": [
                {
                    "price": 39450,
                    "quantity": 20000,
                    "instrument": "BTC-PERPETUAL",
                    "side": "BUY",
                    "venue": "DBT"
                },
                {
                    "price": 47000,
                    "quantity": 20000,
                    "instrument": "BTC-25JUN21",
                    "side": "SELL",
                    "venue": "DBT"
                }
            ],
            "rfq_id": 22539,
            "side":"SELL"
        }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/drfq/quote/create/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [POST] /quote/create/ request allows you to Quote an RFQ you are a counterparty to.

A Quote represents a single side of the trade, either the "BUY" or "SELL", specified by the top-level "side" field.

To quote both sides of an RFQ, two quotes would need to be created, each with it's own unique "client_order_id".

A /quote/create/ request has the following workflow:

  1. The receiver of an RFQ sends a /quote/create/ request to Paradigm.
  2. Paradigm sends a /quote/create/ response to the RFQ receiver.
    1. If the /quote/create/ request is valid, the Quote object is returned to the RFQ receiver.
    2. If the /quote/create/ request is invalid, an Error object is returned to the RFQ receiver.
  3. If the /quote/create/ request is valid, Paradigm sends a Notification on the quote JSON-RPCoverWebSockets Notification channel to the creator of the RFQ and other members of the user's desk specifying a new response to the RFQ.

Important Note: You must quote the entire RFQ and not part of the legs or only part of the quantity.

/quote/create/ Body parameter example

  {
    "account": {
        "name": "ParadigmTestOne"
    },
    "client_order_id": "123",
    "expires_in": "60",
    "legs": [
        {
          "price": 39450,
          "quantity": 20000,
          "instrument": "BTC-PERPETUAL",
          "side": "BUY",
          "venue": "DBT"
        }
    ],
    "rfq_id": 22539,
    "side": "SELL"
  }

Parameters

Name In Type Required Description
account body object Y Paradigm Account information of Quote creator.
> name body string Y The Name of Paradigm API Key.
> clearing_account_name body string N Required if venue is "CME".
> trader_id body string N Required if venue is "CME".
client_order_id body string Y Client determined unique identifier.
expires_in body integer Y Number of seconds quote is available for. Valid values between 10-120.
legs body array of objects Y An array of objects of each leg of the RFQ.
> price body decimal Y The price of the leg.
> quantity body decimal Y The size of the leg in contracts.
> instrument body string Y The leg's instrument name.
> side body string Y Direction of the leg. Valid values include "BUY" and "SELL".
> venue body string Y Venue of the RFQ. Valid values include "DBT", "BIT", "CME".
rfq_id body integer Y Unqiue identifier of RFQ. Paradigm determines this value.
side body string Y Side being quoted. Valid values include "BUY" and "SELL".

/quote/create/ Example response

200 Response

{
   "desk":"DSK1",
   "valid_until":1611038442838.6272,
   "account":{
      "name":"ParadigmTestOne"
   },
   "client_order_id":"49826055",
   "created":1611038342698.2578,
   "legs":[
      {
         "price":39450.0,
         "quantity":20000.0,
         "instrument":"BTC-PERPETUAL",
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "quote_id":84069,
   "rfq_id":22537,
   "side": "SELL",
   "status":"ACTIVE"
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
desk string Y None The Paradigm Desk name of the Quote creator.
valid_until decimal Y None The time the Quote is valid until in the number of milliseconds since epoch (January 1, 1970).
account object Y None An object of account information about the creator of the Quote.
> name string Y None The Name of the Paradigm API Key.
> clearing_account_name string N None Account identifier if venue is "CME".
> trader_id string N None Account identifier if venue is "CME".
client_order_id string Y None Client determined unique identifier.
created decimal Y None The time the Quote was created in the number of milliseconds since epoch (January 1, 1970).
expires_in integer N None Maximum number of seconds the Quote is available for.
legs array of objects Y None An array of objects of the legs of the Quote.
> instrument string Y None The leg's instrument name.
> price decimal N None The price of the leg.
> quantity decimal N None The number of contracts of the leg.
> side string Y None Direction of the quoted leg.
> venue string Y None Venue of the RFQ.
rfq_id integer Y None Unqiue identifier of the RFQ. Paradigm determines this value.
quote_id integer Y None Unique identifier of the Quote. Paradigm determines this value.
side string Y None Side being quoted. Valid values include "BUY" and "SELL".

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 1 Invalid desk product configuration Likely expires_in band outside of values set in your admin dashboard or missing key from payload in request. Leg Prices can also not be negative. Bid can also not be greater than offer.
400 1302 Invalid account information Invalid account information provided in request.
400 2101 Duplicate client_order_id Duplicate client_order_id provided in request.
400 2102 Unknown rfq_id Incorrect or missing rfq_id key from request.
400 2103 Unavailable RFQ RFQ is unavailable to be quoted upon. The RFQ is likely expired, filled or traded away.
400 2104 Invalid leg parameters Invalid payload provided in request. Likely wrong key value.
400 2105 Cannot change fixed leg price Hedge leg price must be the same as in the RFQ.
400 2106 Must specify bid or offer Please provide a price in the request.
400 2107 Invalid quote parameters Invalid /quote/create request.
400 2109 This RFQ already has an active quote for that side. Please cancel it before requoting. There is an ACTIVE existing quote for this side of the RFQ.

[POST]/quote/cancel/

/quote/cancel/ Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/drfq/quote/cancel/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = '{
  "quote_id": 0
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/quote/cancel/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json

# installed
import requests

access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /quote/cancel/
method = 'POST'
path = '/v1/drfq/quote/cancel/'

body = b''

payload = {
            "quote_id": 84063
          }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/drfq/quote/cancel/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [POST] /quote/cancel/ request cancels an existing Quote you have created upon an RFQ.

A /quote/cancel/ request has the following workflow:

  1. The creator of the quote sends a /quote/cancel/ request to Paradigm.
  2. Paradigm sends a /quote/cancel/ response to the creator.
    1. If the /quote/cancel/ request is valid, the Quote object is returned to the creator.
    2. If the /quote/cancel/ request is invalid, an Error object is returned to the creator.
  3. If the /quote/cancel/ request is valid, Paradigm sends a Notification on the quote JSON-RPCoverWebSockets Notifications channel to the creator of the RFQ and other members of the creator's desk specifying the quote is no longer available.

/quote/cancel/ Body parameter

{
  "quote_id": 2156
}

Parameters

Name In Type Required Description
body body object true none
quote_id body integer Y none

/quote/cancel/ Response Example

200 Response

{
   "desk":"DSK1",
   "valid_until":null,
   "account":{
      "name":"ParadigmTestOne"
   },
   "client_order_id":"613310893",
   "created":1611038225971.4749,
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "price":null,
         "quantity":20000.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "quote_id":84063,
   "rfq_id":22537,
   "side": "SELL",
   "status":"CANCELED",
   "updated":1611038331810.966
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
desk string Y None The desk name of the Quote creator.
valid_until decimal or null Y None null if the quote has been successfully canceled.
account object Y None An object of the Quote creator's account information.
> name string Y None The Paradigm API Key name.
> clearing_account_name string N None Account information if venue is "CME".
> trader_id string N None Account information if venue is "CME".
client_order_id string Y None User determined unique identifier.
created decimal Y None The time the Quote was created in the number of milliseconds since epoch (January 1, 1970).
legs array of objects Y None An array of objects of the legs of the Quote.
> instrument string Y None The leg's instrument name.
> price decimal N None The price of the leg.
> quantity decimal N None The contract size of the leg.
> side string Y None The Direction of the leg.
> venue string Y None The Venue of the RFQ.
quote_id integer Y None Unique identifier of the Quote. Paradigm determines this value.
rfq_id integer Y None Unique identifier of RFQ. Paradigm determines this value.
side string Y None Side being quoted. Valid values include "BUY" and "SELL".
status string Y None Status of the Quote.
updated decimal Y None The time the Quote is was last updated in the number of milliseconds since epoch (January 1, 1970).

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 2201 Unknown quote_id Unknown quote_id.
400 2202 Too late to cancel Quote is expired, filled, or does not exist.

[POST]/quote/execute/

/quote/execute/ Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/drfq/quote/execute/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = '{
  "rfq_id": 0,
  "legs": [
    {
      "price": "string",
      "quantity": "string",
    }
  ],
  "quote_id": 0
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer ACCESS_KEY'
};

fetch('https://api.test.paradigm.co/v1/drfq/quote/execute/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json
from random import randint

# installed
import requests

access_key = '<access-key>'
secret_key = '<secret-key>'

signing_key = base64.b64decode(secret_key)

print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))

# Request Body

host = 'https://api.test.paradigm.co'

# POST /quote/execute/
method = 'POST'
path = '/v1/drfq/quote/execute/'

body = b''

payload = {
            "rfq_id": 22540,
            "legs": [
                {
                "price": "38226.8",
                "quantity": "20000",
                }
            ],
            "quote_id": 84073
            }

json_payload = json.dumps(payload).encode('utf-8')

message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload

timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)


headers = {
            'Paradigm-API-Timestamp': timestamp,
            'Paradigm-API-Signature': signature,
            'Authorization': f'Bearer {access_key}'
            }

# Send request
response = requests.post(urljoin(host, path),
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)
package main

import (
       "bytes"
       "net/https"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer ACCESS_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := https.NewRequest("POST", "http://api.test.paradigm.co/v1/drfq/quote/execute/", data)
    req.Header = headers

    client := &https.Client{}
    resp, err := client.Do(req)
    // ...
}

A [POST] /quote/execute/ request executes a Quote. It is only used by the creator of the RFQ, the Taker.

A /quote/execute/ request has the following workflow:

  1. The creator of the RFQ sends a /quote/execute/ request to Paradigm.
  2. Paradigm sends a /quote/execute/ response to the creator.
    1. If the /quote/execute/ request is valid, the RFQ object is returned to the creator.
    2. If the /quote/execute/ response is invalid, an Error object is returned to the creator. A /quote/execute/ request is invalid if the RFQ or Quote has already expired or been canceled.
  3. If the /quote/execute/ request is valid, Paradigm sends a Notification on the quote JSON-RPCoverWebSocket Notification channel to the creator of the RFQ and the creator of the Quote specifying that a fill is pending.
    1. If the exchange confirms the trade, another Notification on the quote channel is sent to all parties listed above that the Trade has been completed and the Quote is filled.
    2. If the exchange rejects the trade, another Notification on the quote channel is sent to all parties listed above that the Trade could not be executed and the Quote is rejected. A Trade is all or nothing and a rejection of one leg of the trade will cause the rejection of all legs.
  4. If the Trade has been confirmed, Paradigm sends a Notification on the quote JSON-RPCoverWebSocket Notification channel to other desks that responded to the quote specifying that the quote has been canceled.
  5. If the Trade has been confirmed, Paradigm sends a Notification on the rfq JSON-RPCoverWebSocket Notification channel to all counterparties aparty in the RFQ specifying that the rfq has been filled.

Important Notes:

/quote/execute/ Body parameter example

{
  "rfq_id": 22540,
  "legs": [
      {
      "price": "38226.8",
      "quantity": "20000",
      }
  ],
  "quote_id": 84073
}

Parameters

Name In Type Required Description
rfq_id body integer Y Unique Identifier of the RFQ. Paradigm determines this value.
legs body array of objects Y An array of objects of the legs.
> price body decimal Y The Price of the leg.
> quantity body decimal Y The Size of the leg.
quote_id body integer Y Unqiue Identifier of Quote. Paradigm determines this value.

/quote/execute/ Response example

200 Response

{
   "account":{
      "name":"ParadigmTestTwo"
   },
   "client_order_id":"838781960",
   "counterparties":[
      "DSK1",
      "DSK4",
      "DSK5"
   ],
   "created":1611038577702.458,
   "desk":"DSK2",
   "fills":[
      {
         "created":1611038629260.88,
         "legs":[
            {
               "price":38226.8,
               "quantity":20000.0,
               "side":"BUY"
            }
         ],
         "quote_id":84073,
         "rfq_id":22540,
         "desk":"DSK1"
      }
   ],
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "quantity":20000.0,
         "side":"BUY",
         "venue":"DBT"
      }
   ],
   "quotes":[
      {
         "desk":"DSK1",
         "valid_until":1611038679969.7102,
         "created":1611038577707.4758,
         "legs":[
            {
               "instrument":"BTC-PERPETUAL",
               "price":37469.84,
               "quantity":20000.0,
               "side":"BUY",
               "venue":"DBT"
            }
         ],
         "quote_id":84073,
         "rfq_id":22540,
         "side":"SELL",
         "status":"PENDING_FILL"
      }
   ],
   "rfq_id":22540,
   "status":"PENDING_FILL",
   "valid_until":1611038697689.463
}

Response Schema

Status Code 200

Name Type Required Restrictions Description
account object Y None
> name string Y None The Name of Paradigm API Key.
> clearing_account_name string N None Required if venue is "CME".
> trader_id string N None Required if venue is "CME".
client_order_id string Y None Client determined unique identifier.
counterparties [string] Y None List of strings of counterparties involved in the RFQ.
created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
desk string Y None The desk name of the creator of the RFQ.
fills array of objects Y None An array of the fills of the RFQ.
>created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
>legs array of objects Y None An array of objects of the RFQ that were filled.
>> price decimal Y None The price of the filled leg.
>> quantity decimal Y None The size of the filled leg.
>> side string Y None The direction of the leg.
>quote_id integer Y None The unique identifier of the Quote of the Filled leg.
>rfq_id integer Y None The unique identifier of the RFQ.
>desk string Y None The desk name of the creator of the RFQ.
legs array of objects Y None An array of objects the legs of the RFQ.
>instrument string Y None The leg's instrument name.
>quantity decimal Y None The size in contracts of the leg.
>side string Y None The direction of the leg.
>venue string Y None The venue the RFQ is executed on.
quotes array of objects Y None An array of the Quotes of the RFQ.
>desk string Y None The desk name of the creator of the RFQ.
>valid_until decimal Y None The time the RFQ is valid until in the number of milliseconds since epoch (January 1, 1970).
>created decimal Y None The time the RFQ was created in the number of milliseconds since epoch (January 1, 1970).
>legs array of objects Y None An array of objects of the legs of the Quote.
>>instrument string Y None The leg's instrument name.
>>price decimal Y None The price of the leg.
>>quantity decimal Y None The size of the leg.
>>side string Y None The direction of the leg.
>>venue string Y None The venue the RFQ is executed on.
>quote_id integer Y None The unique identifier of the Quote.
>rfq_id integer Y None The unique identifier of the RFQ.
>status string Y None The status of the Quote.
rfq_id integer Y None Unique Identifier of the RFQ.
side string Y None Side being quoted. Valid values include "BUY" and "SELL".
status string Y None The status of the RFQ.
valid_until decimal Y None The time the RFQ is valid until in the number of milliseconds since epoch (January 1, 1970).

Error Codes

HTTP Status Code Paradigm Code Message Meaning
400 RFQ doesn't have a quote for this side of the trade. Or RFQ has been canceled, expired.
400 2104 Invalid leg parameters Provided payload is missing or contains incorrect values.
400 2201 Unknown quote_id Unknown quote_id value.
400 2205 Unable to execute an expired quote Quote has expired.
400 2302 Invalid leg price Leg price in payload must match quote provided.

GRFQ - API Workflows

Paradigm operates Auto-Market Makers running on our Test environment. All available and created RFQs will have markets made upon them.

High Level

GRFQ is centred around the concepts of "RFQs", "Quotes", "Orders" and "Trades":

At a high level, the GRFQ workflow is:

  1. Taker creates an RFQ with the desired Instruments and quantity ratios.
  2. Makers Quote the RFQ.
  3. Takers can execute an Order upon an RFQ and consume Quotes which suit the set Limit Price & venue enforced "Block Size Minimums".
  4. Once a Quote and an Order are matched, the executions are sent to the underyling venue for clearing & settlement.
  5. Taker and Maker aparty to the trade receive confirmation if clearing & settlement was successful or rejected.
  6. All Paradigm users are able to see cleared & settled Trades, but NOT the counterparties or the traded RFQ/Order/Quote side.

Key GRFQ Concepts

In GRFQ,

Common Workflows

Important Note: Both the Taker and the Maker will receive all updates through the JSON-RPCoverWebSockets Notification channels for events relating to RFQs, Quotes, Orders and Trades.

A user is only a Maker where their Quote is executed upon by an Order. A user is only a Taker if they submit an Order which crosses an existing Quote.

Create/Check for RFQ

If you would like to create an RFQ or check if one exists, you should request the RESToverHTTP [POST] /rfqs/ endpoint.

Pull available Quotes on an RFQ

Each RFQ is comprised of Quotes. Quotes are NOT aggregated by Price levels as is usual in centralized Quote Book.

Makers submit Quotes on RFQs and Paradigm returns them individually to all users as children of the RFQ primarily because of workflow complications relating to some venues' "Block Size Minimum" rules.

You should request the RESToverHTTP [GET] /quotes/ endpoint.

Submit a non-crossing Quote on an RFQ

Users are NOT able to submit Quotes which cross an existing resting Quote on an RFQ.

You should request the RESToverHTTP [POST] /rfqs/{rfq_id}/quotes/ endpoint.

Submit a crossing Quote/execute upon a Quote with an Order

Users are able to submit a Quote which crosses an existing Quote on an RFQ as well as they are able to submit an Order to cross an existing Quote.

You should request the RESToverHTTP [POST] /rfqs/{rfq_id}/quotes/ or [POST] /rfqs/{rfq_id}/orders/ endpoint.

Replace an existing Quote on an RFQ

In the present release there is NO atomic replace endpoint.

Users should first request RESToverHTTP [DELETE] /quotes/{quote_id}/ their existing Quote and wait for a response. Upon a successful response, users should then RESToverHTTP request [POST] /{rfq_id}/quotes/ to submit a new Quote.

Cancel a requested Order on an RFQ

Takers are not able to cancel a requested Order. You will receive a successful/erroneous response from the RESToverHTTP [POST] /rfqs/{rfq_id}/orders/ request with information regarding the outcome.

Executable Quote Book

RFQs are comprised of individual Quotes which are not aggregated by price level as is usual with standard centralized Quote Books. This was principally done to accomodate venue created & enforced "Block Size Minimums".

Not all venues have "Block Size Minimums", most notably Bybit, but the workflows for ranking+aggregating what is actually executable is the same for all venues with GRFQ.

So as the user, you are likely to have the following questions:

Workflow to create+manage your Quote Book

  1. Subscribe to the quote_book JSON-RPCoverWebSockets Notification Channel to receive updates relating to Quotes upon RFQs.
  2. Request the RESToverHTTP [GET] /quotes/ endpoint to return all existing Quotes on RFQs.
  3. ADD/REMOVE/UPDATE your locally stored Quotes as updates are received through the quote_book WS Channel.

Workflow to create+manage your Executable Quote Book:

  1. Subscribe to the quote_book JSON-RPCoverWebSockets Notification Channel to receive updates relating to Quotes upon RFQs.
  2. Request the RESToverHTTP [GET] /quotes/ endpoint to return all existing Quotes on RFQs.
  3. ADD/REMOVE/UPDATE your locally stored Quotes as updates are received through the quote_book WS Channel.
  4. Determine the Block Size Minimum requirement for the RFQ you are trading upon. This will be the minimum executable quantity.
    • For Deribit, this is 25BTC for BTC Options RFQs and $200kUSD for Futures RFQs.
    • For Bybit, this is $1USD for Futures RFQs.
  5. Create levels in your Executable Quote Book by the Block Size minimum quantity size to ascertain the size & price levels.

Helpful perspectives:

Comprehensive API Workflow Paths

RFQ Created

Taker's & Maker's Perspective:

  1. Subscribed to rfq WS Channel.
  2. Receives WS message with kind == ADDED, status == ACTIVE.

RFQ Expires

Taker's & Maker's Perspective:

  1. Subscribed to rfq WS Channel.
  2. Receives WS message with kind == REMOVED, status == EXPIRED.

Quote Created

Taker's & Maker's Perspective:

  1. Subscribed to the quote and quote_book WS Channels.
  2. Asynchronously:
    • Receives WS message on quote_book WS Channel with kind == ADDED and status == OPEN.
    • Maker only, receives WS message on quote WS Channel with kind == NEW and status == OPEN.

Quote Canceled

Taker's & Maker's Perspective:

  1. Subscribed to the quote and quote_book WS Channels.
  2. Asynchronously:
    • Receives WS message on quote_book WS Channel with kind == REMOVED and status == CLOSED.
    • Maker only, receives WS message on quote WS Channel with kind == CANCELED and status == CLOSED.

Matched Quote and Order

Taker's Perspective:

  1. Subscribed to quote_book, order, trade and trade_tape WS Channels.
  2. Asynchronously:
    • Receives a single WS message on order WS Channel with kind == PENDING_FILL and status == OPEN.
    • Receives a WS message on the quote_book WS Channel:
      • If Quote is completely consumed kind == REMOVED.
      • If Quote is partially consumed kind == UPDATED.
  3. Asynchronously:
    • If Trade execution is successful at clearing & settlement:
      • Receives WS messages on trade WS channel with kind == CONFIRMATION for each successful trade execution as apart of the Order.
      • Receives WS messages on trade_tape WS channel with kind == COMPLETED for each successful trade execution through Paradigm.
    • If Trade execution is rejected at clearing & settlement:
      • Receives WS messages on trade WS channel with kind == REJECTION for each rejected trade execution as apart of the Order.
    • In the event of Successful/Rejected executions at clearing & settlement:
      • Receives WS message on order on WS channel with kind == SUMMARY and status == CLOSED.

Maker's Perspective:

  1. Subscribed to quote_book, quote, trade and trade_tape WS Channels.
  2. Asynchronously:
    • Receives a single WS message on quote WS Channel:
      • If Quote is completely consumed kind == PENDING_FILL and status == CLOSED.
        • Also occurs if the Remaining Quantity is below the venue's enforced "Block Size Minimum".
      • If Quote is partially consumed kind == PENDING_FILL and status == OPEN.
    • Receives a WS message on the quote_book WS Channel:
      • If Quote is completely consumed kind == REMOVED.
      • If Quote is partially consumed kind == UPDATED.
  3. Asynchronously:
    • If Trade execution is successful at clearing & settlement:
      • Receives WS messages on trade WS channel with kind == CONFIRMATION for each successful trade execution as apart of the Order.
      • Receives WS messages on trade_tape WS channel with kind == COMPLETED for each successful trade execution through Paradigm.
      • If a Quote is only partially consumed at execution, meaning there is remaining available quantity:
        • Receives a WS message on the quote WS Channel with kind == PARTIALLY_FILLED and status == OPEN.
      • If a Quote is only completely consumed at execution, meaning there is NO remaining available quantity:
        • Receives a WS message on the quote WS Channel with kind == FILLED and status == OPEN.
    • If Trade execution is rejected at clearing & settlement:
      • Receives WS messages on trade WS channel with kind == REJECTION for each rejected trade execution as apart of the Order.
      • Receives a WS message on the quote WS Channel with kind == CANCELED and status == CLOSED.

GRFQ - Code Examples

Reach out if you ever need any help! We are more than happy to help.

You will need to update the provided Code Examples with your own Paradigm Access Key and Secret Key.

You can find all existing examples on our github: https://github.com/tradeparadigm/code-samples

Note: All examples in this section are in Python3.

JSON-RPCoverWebSockets

Authentication + Subscribe & Unsubscribe to Notification Channels

  1. Authenticate, establish a heartbeat and Subscribe to the rfq, quote_book, quote, order, trade, and trade_tape JSON-RPCoverWebSockets Notification Channels.

GRFQ - WebSocket Notifications Channels

rfq

An example of the rfq notification received when an RFQ is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "kind":"ADDED",
         "rfq":{
            "id":1232,
            "created":1628038165427.771,
            "description":"Call  4 Aug 21  39000",
            "last_trade":"None",
            "latest_activity":1628038165427.839,
            "product_codes":[
               "DO"
            ],
            "status":"ACTIVE",
            "venue":"DBT",
            "legs":[
               {
                  "instrument":"BTC-4AUG21-39000-C",
                  "product_code":"DO",
                  "ratio":"1",
                  "venue_instrument":"BTC-4AUG21-39000-C",
                  "side":"BUY"
               }
            ]
         }
      }
   }
}

An example of the rfq notification received when an RFQ expires

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq",
      "data":{
         "kind":"REMOVED",
         "rfq":{
            "id":589,
            "venue":"DBT",
            "created":1625191497588.2312,
            "description":"FSpd  2 Jul 21 / 25 Mar 22",
            "last_trade":"None",
            "latest_activity":1625191497588.316,
            "legs":[
               {
                  "instrument":"BTC-2JUL21",
                  "venue_instrument":"BTC-2JUL21",
                  "product_code":"CF",
                  "ratio":"1",
                  "side":"SELL"
               },
               {
                  "instrument":"BTC-25MAR22",
                  "venue_instrument":"BTC-25MAR22",
                  "product_code":"CF",
                  "ratio":"1",
                  "side":"BUY"
               }
            ],
            "product_codes":[
               "CF"
            ],
            "status":"EXPIRED"
         }
      }
   }
}

All updates relating to RFQs are sent through the rfq WebSocket Notifications channel.

This is a public channel and consumable by all.

Updates received through the rfq WebSocket Notification channel can include RFQ creations and expirations.

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon. Valid value is rfq.
data object true
> kind string true WS Action. Valid values include ADDED, REMOVED.
> rfq object true
>> id int true The Paradigm created unique identifier of the RFQ.
>> venue string true The underlying venue the RFQ is cleared & settled upon. Valid values include DBT, BIT, and BYB.
>> created number true Time in unix milliseconds since the epoch when the RFQ was created.
>> description string true Paradigm created description of the RFQ.
>> last_trade object true "None" if RFQ has not been traded.
>>> traded number false Time in unix milliseconds since the epoch when the the Trade occurred.
>>> quantity string false The size of the trade in the contract units of the RFQ.
>>> price string false The price the RFQ was Traded at.
>> latest_activity number true Time in unix milliseconds since the epoch when the RFQ was last acted upon.
>> legs array of objects true
>>> instrument string true The Paradigm standardized name of the Instrument.
>>> venue_instrument string true The name of the Instrument per the unerlying venue's naming convention.
>>> product_code string true The Paradigm created product code of the Instrument.
>>> ratio string true The quantity multiple relative to other legs.
>>> price string false The price of the Instrument in the Quote Currency of the RFQ.
>>> side string true The direction of the leg. Valid values include BUY and SELL.
>> product_codes array of strings true Paradigm created product codes apart of the RFQ.
>> status string true Status of the RFQ. Valid values include ACTIVE and EXPIRED.

quote_book

An example of the quote_book notification received when a Quote is newly added to the Quote Book

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote_book",
      "data":{
         "kind":"ADDED",
         "quote":{
            "remaining_quantity":"20000",
            "side":"BUY",
            "rfq_id":816,
            "id":482396,
            "price":"-9",
            "status":"OPEN",
            "created":1626155549137.585
         }
      }
   }
}

An example of the quote_book notification received when a Quote is removed from the Quote Book

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote_book",
      "data":{
         "kind":"REMOVED",
         "quote":{
            "id":482395,
            "side":"SELL",
            "created":1626155407461.441,
            "rfq_id":816,
            "status":"CLOSED",
            "price":"-13",
            "remaining_quantity":"20000"
         }
      }
   }
}

An example of the quote_book notification received when a Quote is updated in the Quote Book

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote_book",
      "data":{
         "kind":"UPDATED",
         "quote":{
            "remaining_quantity":"1990000",
            "side":"SELL",
            "rfq_id":816,
            "id":482399,
            "price":"9",
            "status":"OPEN",
            "created":1626155762785.2932
         }
      }
   }
}

Updates relating to Quotes upon RFQs are sent through the quote_book WebSocket Notifications channel.

This is a public channel and is consumable by all. This is the channel you should use to create your own Quote Book & Executable Quote Book.

Updates received through the quote_book WebSocket Notification channel can include newly created quotes, removed quotes as well as updates to existing Quotes.

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon.
data object true
> kind string true The action of the message. Valid values include ADDED, REMOVED, UPDATED.
> quote object true
> side string true The side of the Quote from the Maker's perspective. Valid values include BUY and SELL.
> rfq_id int true The Paradigm created unique identifer of the RFQ.
> id int true The Paradigm created unique identifier of the Quote.
> price string true The price in the Quote Currency of the RFQ.
> status string true The status of the Quote. Valid values include OPEN, CLOSED.
> created number true The time in unix milliseconds since the epoch when the Quote was created.
> remaining_quantity string true The remaining Quantity upon the Quote in contract units of the RFQ.

quote

An example of the quote notification received when a Quote is created

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"NEW",
         "quote":{
            "id":709037,
            "status":"OPEN",
            "maker":"DSK95",
            "created":1628041444199.396,
            "original_quantity":"50",
            "rfq_id":1232,
            "price":"0.004",
            "remaining_quantity":"50",
            "side":"BUY",
            "client_order_id":""
         }
      }
   }
}

An example of the quote notification received when a Quote is canceled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"CANCELED",
         "quote":{
            "id":2776215,
            "order":{
               "id":266357,
               "client_order_id":"st121221",
               "filled_quantity":"0",
               "filled_average_price":"0",
               "limit_price":"0.06",
               "requested_quantity":"50",
               "rfq_id":2073,
               "side":"SELL",
               "status":"OPEN",
               "venue":"DBT"
            },
            "status":"CLOSED",
            "maker":"DSK95",
            "remaining_quantity":"22",
            "side":"SELL",
            "created":1631590685753.57,
            "original_quantity":"22",
            "client_order_id":"st12122",
            "rfq_id":2073,
            "price":"0.06"
         }
      }
   }
}

An example of the quote notification received when a Quote is being executed upon

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"PENDING_FILL",
         "quote":{
            "original_quantity":"34",
            "order":{
               "id":266376,
               "client_order_id":"st12122121",
               "filled_quantity":"26",
               "filled_average_price":"0.0904",
               "limit_price":"0.1",
               "requested_quantity":"60",
               "rfq_id":2073,
               "side":"BUY",
               "status":"CLOSED",
               "venue":"DBT"
            },
            "id":2776296,
            "side":"BUY",
            "price":"0.1",
            "rfq_id":2073,
            "created":1631591051681.613,
            "status":"OPEN",
            "client_order_id":"st121221",
            "remaining_quantity":"7",
            "maker":"DSK95"
         }
      }
   }
}

An example of the quote notification received when a Quote has been partially filled

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"PARTIALLY_FILLED",
         "quote":{
            "rfq_id":816,
            "id":482399,
            "remaining_quantity":"1990000",
            "status":"OPEN",
            "client_order_id":"",
            "price":"9",
            "side":"SELL",
            "created":1626155762785.2932,
            "maker":"DSK95",
            "original_quantity":"2000000"
         }
      }
   }
}

An example of the quote notification received when a Quote has been partially filled & is partially executed again

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"PENDING_FILL",
         "quote":{
            "maker":"DSK95",
            "rfq_id":816,
            "client_order_id":"",
            "price":"-13",
            "side":"SELL",
            "id":482407,
            "created":1626156440976.632,
            "status":"OPEN",
            "original_quantity":"50000",
            "remaining_quantity":"20000"
         }
      }
   }
}

An example of the quote notification received when a Quote has been competely executed upon

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"quote",
      "data":{
         "kind":"PARTIALLY_FILLED",
         "quote":{
            "side":"BUY",
            "rfq_id":2073,
            "maker":"DSK95",
            "status":"CLOSED",
            "id":2776296,
            "created":1631591051681.613,
            "remaining_quantity":"7",
            "order":{
               "id":266376,
               "client_order_id":"st12",
               "filled_quantity":"26",
               "filled_average_price":"0.0904",
               "limit_price":"0.1",
               "requested_quantity":"60",
               "rfq_id":2073,
               "side":"BUY",
               "status":"CLOSED",
               "venue":"DBT"
            },
            "price":"0.1",
            "original_quantity":"34",
            "client_order_id":"st12"
         }
      }
   }
}

All updates relating to Quotes upon RFQs are sent through the quote WebSocket Notifications channel.

This is a private channel and only provides updates to the Maker who created the Quote.

Updates received through the quote WebSocket Notification channel can include newly created quotes, removed quotes, quotes pending settlement & clearing, quotes which are partially filled as well as quotes which are completely filled.

Quotes which are executed upon and a rejection occurs at the underlying venue are canceled upon rejected. The remaining_quantity of the Quote is no longer available on the Quote Book. It does not matter which party is to blame, the Quote is kind == CANCELED and status == CLOSED.

Quotes which have been [PATCH] /rfqs/{rfq_id}/quotes/ have the original quote kind == CANCELED and status == CLOSED and a new Quote with kind == NEW and status == OPEN.

Workflow Steps:

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon.
data object true
> kind string true The action of the message. Valid values include NEW, CANCELED, PENDING_FILL, PARTIALLY_FILLED, FILLED.
> quote object true
>> order object false Present if Quote crosses the existing market.
>>> id int false The Paradigm created unique identifier of the Order.
>>> client_order_id string false A unique user created identifier for the Order.
>>> filled_quantity string false The filled quantity of the Order in the contract units of the RFQ.
>>> filled_average_price string false The average filled price of the Order in the quote currency of the RFQ.
>>> limit_price string false The price of the Order in quote currency of the RFQ.
>>> requested_quantity string false The requested crossing quantity of the Order.
>>> rfq_id int false The Paradigm created unique identifier of the RFQ the Order is a child of.
>>> side string false The direction of the Order. Valid values include BUY and SELL.
>>> status string false The current status of the Order. Valid values include OPEN and CLOSED.
>>> venue string false Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.
>> created number true The time in unix milliseconds since the epoch when the Quote was created.
>> client_order_id string false A unique user created identifier for the Quote. Not present if th subscribed user is not the Maker.
>> id int true The Paradigm created unique identifier of the Quote.
>> maker string true The Paradigm desk name of the Maker.
>> original_quantity string true The initial available quantity of the Quote in the contract units of the RFQ.
>> price string true The price of the Quote in the Quote Currency of the RFQ.
>> remaining_quantity string true The remaining available quantity of the Quote in the contract units of the RFQ.
>> rfq_id int true The Paradigm created unique identifier of the RFQ.
>> side string true The side of the Quote. Valid values include BUY and SELL.
>> status string true The status of the Quote. Valid values include OPEN and CLOSED.
venue_error object false
> message string false Example: "Deribit error: Trade rejected"

order

An example of the order notification received when an Order is Pending Fill

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"order",
      "data":{
         "kind":"PENDING_FILL",
         "order":{
            "id":1113,
            "client_order_id":"",
            "filled_quantity":"0",
            "filled_average_price":"0",
            "limit_price":"0.0054",
            "requested_quantity":"25",
            "rfq_id":1232,
            "side":"BUY",
            "status":"OPEN",
            "venue":"DBT"
         }
      }
   }
}

An example of the order notification received when an Order has reached finality

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"order",
      "data":{
         "kind":"SUMMARY",
         "order":{
            "id":1113,
            "client_order_id":"",
            "filled_quantity":"25",
            "filled_average_price":"0.0054",
            "limit_price":"0.0054",
            "requested_quantity":"25",
            "rfq_id":1232,
            "side":"BUY",
            "status":"CLOSED",
            "venue":"DBT"
         }
      }
   }
}

All updates relating to Orders upon RFQs are sent through the order WebSocket Notifications channel.

This is a private channel and only provides updates to the Taker who submitted the Order.

Updates received through the order WebSocket Notification channel can include a pending fill notification as well as a summary of an order's execution at finality. You will receive a single kind == PENDING_FILL and kind == SUMMARY per order execution regardless of the number of Quotes consumed.

It is important to be aware that executions can be rejected by exchanges. You should the difference between the requested_quantity and the filled_quantity in the messages to be aware of the success of the execution(s).

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon.
data object true
> kind string true The action of the message. Valid values include PENDING_FILL, SUMMARY.
> order object true
>> id int true The Paradigm created unique identifier of the Order.
>> client_order_id string true The user created unique value associated with the Order.
>> filled_quantity string true The filled quantity upon finality of the Order.
>> filled_average_price string true The average price of the filled quantity of the Order upon finality.
>> limit_price string true The price in the Quote currency of the RFQ of the Order.
>> requested_quantity string true The requested quantity of the Order in the contract units of the RFQ.
>> rfq_id int true The Paradigm created unique identifier of the RFQ.
>> side string true The direction of the Order. Valid values include BUY and SELL.
>> status string true The status of the Order. Valid values include OPEN, CLOSED.
>> venue string true The underlying venue the trade was settled upon. Valid values include DBT, BIT, BYB.

trade

An example of the trade notification received when a Trade successfully settles and clears

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trade",
      "data":{
         "kind":"CONFIRMATION",
         "trade":{
            "quote_id":709033,
            "action":"BUY",
            "id":1257,
            "rfq_id":1232,
            "order_id":1120,
            "quantity":"25",
            "product_codes":[
               "DO"
            ],
            "traded":1628040498333.169,
            "api_credential":"ParadigmTestNinetySix",
            "price":"0.0055",
            "client_order_id":"",
            "status":"COMPLETED",
            "legs":[
               {
                  "id":2044,
                  "instrument":"BTC-4AUG21-39000-C",
                  "price":"0.0055",
                  "product_code":"DO",
                  "quantity":"25",
                  "ratio":"1",
                  "side":"BUY",
                  "action":"BUY",
                  "exec_id":"78144401"
               }
            ],
            "venue":"DBT",
            "mark_price":"0.0054",
            "quote_currency":"BTC",
            "description":"Call  4 Aug 21  39000"
         }
      }
   }
}

An example of the trade notification received when a Trade is rejected at settlement and clearing

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trade",
      "data":{
         "kind":"REJECTION",
         "trade":{
            "order_id":1121,
            "quote_currency":"BTC",
            "id":1258,
            "mark_price":"0.0054",
            "client_order_id":"",
            "price":"0.0055",
            "quote_id":709033,
            "quantity":"25",
            "traded":1628040604131.9612,
            "action":"BUY",
            "api_credential":"ParadigmTestNinetySix",
            "status":"REJECTED",
            "description":"Call  4 Aug 21  39000",
            "product_codes":[
               "DO"
            ],
            "legs":[
               {
                  "id":2045,
                  "instrument":"BTC-4AUG21-39000-C",
                  "price":"0.0055",
                  "product_code":"DO",
                  "quantity":"25",
                  "ratio":"1",
                  "side":"BUY",
                  "action":"BUY",
                  "exec_id":"None"
               }
            ],
            "venue":"DBT",
            "rfq_id":1232
         }
      },
      "venue_error":{
         "message":"DBT Error: Trade refused by exchange"
      }
   }
}

Updates relating to Trades upon RFQs are sent through the trade WebSocket Notifications channel.

This is a private channel and only provides updates to the Taker & Maker aparty to the Trade (matching of an Order and a Quote).

Updates received through the trade WebSocket Notification channel can include trade success and rejection at clearing & settlement.

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon.
data object true
> kind string true The action of the WS Message. Valid values include CONFIRMATION and REJECTION.
> trade object true
>> api_credential string false The name given the to the Exchange API Key entered on the Paradigm Client Admin dashboard.
>> description false true The Paradigm created description of the RFQ.
>> client_order_id string true A unique user created identifier for the Quote (Maker) or trade Order (Taker).
>> rfq_id int true The Paradigm created unique identifier of the RFQ.
>> id int true The Paradigm created unique identifier of the Trade.
>> mark_price string false The calculated mark price of the RFQ from the underlying venue's mark prices in the Quote Currency of the RFQ.
>> order_id int false The Paradigm created unique identifier of the Order that triggered execution.
>> price string false The price the Trade was executed at in the Quote Currency of the RFQ.
>> product_codes array of strings false The Paradigm created Product Codes of the trade.
>> quantity string false The size of the trade in contracts units of the RFQ.
>> quote_currency string false The Quote Currency of the RFQ executed upon.
>> quote_id int false The Paradigm created unique identifier of the Quote executed upon.
>> action string false The direction of the Trade from the perspective of the User. Valid values include BUY and SELL.
>> status string true Trade status. Valid values include COMPLETED, REJECTED.
>> traded number false The time in unix milliseconds since the epoch when the trade was cleared & settled.
>> venue string true Venue the underlying RFQ clears and settles upon. Valid values include DBT, BIT, BYB.
>> legs array of objects true
>>> id int true The Paradigm created unique individual leg trade identifier.
>>> exec_id string false The venue created leg trade execution identifier. Only available to participants of the trade.
>>> instrument string true The Paradigm standardized name of the Instrument.
>>> quantity string true The size of the leg traded in contract unit terms.
>>> price string true The price of the leg traded in the Quote Currency of the RFQ.
>>> product_code string true The Paradigm created product code of the Instrument traded.
>>> ratio string true The quantity multiplier relative to other Instrument legs.
>>> side string true The direction of the leg apart of the RFQ. Valid values include BUY, SELL.
>>> action string true The direction of the leg from the user's perspective Traded. Valid values include BUY, SELL.
venue_error object false Only present if the Trade was rejected by the underlying venue.
> message string false Reason the trade was rejected by the underlying venue.

trade_tape

An example of the trade_tape notification received when a trade settles & clears

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trade_tape",
      "data":{
         "kind":"COMPLETED",
         "trade":{
            "id":1260,
            "description":"Call  4 Aug 21  39000",
            "mark_price":"0.0054",
            "price":"0.0054",
            "product_codes":[
               "DO"
            ],
            "quantity":"25",
            "quote_currency":"BTC",
            "rfq_id":1232,
            "traded":1628041230769.151,
            "venue":"DBT"
         }
      }
   }
}

All updates relating to Trades upon RFQs are sent through the trade_tape WebSocket Notifications channel.

This is a public channel and provides updates about all Trades which are executed through Paradigm & successfully clear and settle on the underlying venue.

All notifications through the trade_tape WebSocket channel do not reveal Taker or Maker information or the side/action the RFQ/Order/Quote was executed.

Member Type Required Description
channel string true WebSocket Notification Channel message is received upon.
data object true
> kind string true The action of the WS Message. Valid values include COMPLETED.
> trade object true
>> id int true The Paradigm created unique identifier of the Trade.
>> description string true The Paradigm created description of the RFQ.
>> mark_price string true The calculated mark price of the RFQ from the underlying venue's mark prices in the Quote Currency of the RFQ.
>> price string true The price the Trade was executed at in the Quote Currency of the RFQ.
>> product_codes array of strings true The Paradigm created Product Codes of the trade.
>> quantity string true The size of the trade in contracts units of the RFQ.
>> quote_currency string true The Quote Currency of the RFQ executed upon.
>> rfq_id int true The Paradigm created unique identifier of the RFQ.
>> traded number true The time in unix milliseconds since the epoch when the trade was cleared & settled.
>> venue string true Venue the underlying RFQ clears and settles upon. Valid values include DBT, BIT, BYB.

GRFQ - REST Endpoints

[GET] /instruments/

/instruments/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/instruments/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/v1/instruments/
method = 'GET'
path = '/v1/grfq/instruments/?asset=BTC&kind=FUTURE'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/instruments/ Response example

{
   "count":1341,
   "next":"cD05NjE0Nw==",
   "results":[
      {
         "option_kind":"PUT",
         "name":"BTC-3JUL21-28000-P",
         "strike":"28000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-3JUL21-28000-C",
         "strike":"28000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-45000-P",
         "strike":"45000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-45000-C",
         "strike":"45000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-40000-P",
         "strike":"40000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-40000-C",
         "strike":"40000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-38000-P",
         "strike":"38000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-38000-C",
         "strike":"38000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-36000-P",
         "strike":"36000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-36000-C",
         "strike":"36000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-34000-P",
         "strike":"34000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-34000-C",
         "strike":"34000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-32000-P",
         "strike":"32000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-32000-C",
         "strike":"32000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-30000-P",
         "strike":"30000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-30000-C",
         "strike":"30000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-28000-P",
         "strike":"28000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-28000-C",
         "strike":"28000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-26000-P",
         "strike":"26000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-26000-C",
         "strike":"26000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"BTC-23JUL21-25000-P",
         "strike":"25000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"BTC-23JUL21-25000-C",
         "strike":"25000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2400-P",
         "strike":"2400",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2400-C",
         "strike":"2400",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2300-P",
         "strike":"2300",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2300-C",
         "strike":"2300",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2200-P",
         "strike":"2200",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2200-C",
         "strike":"2200",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2150-P",
         "strike":"2150",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2150-C",
         "strike":"2150",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2100-P",
         "strike":"2100",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2100-C",
         "strike":"2100",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2050-P",
         "strike":"2050",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2050-C",
         "strike":"2050",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-2000-P",
         "strike":"2000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-2000-C",
         "strike":"2000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-1950-P",
         "strike":"1950",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-1950-C",
         "strike":"1950",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-1900-P",
         "strike":"1900",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-1900-C",
         "strike":"1900",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-3JUL21-1800-P",
         "strike":"1800",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-3JUL21-1800-C",
         "strike":"1800",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1625299200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-23JUL21-3200-P",
         "strike":"3200",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-23JUL21-3200-C",
         "strike":"3200",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-23JUL21-3000-P",
         "strike":"3000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-23JUL21-3000-C",
         "strike":"3000",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-23JUL21-2800-P",
         "strike":"2800",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-23JUL21-2800-C",
         "strike":"2800",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"PUT",
         "name":"ETH-23JUL21-2600-P",
         "strike":"2600",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      },
      {
         "option_kind":"CALL",
         "name":"ETH-23JUL21-2600-C",
         "strike":"2600",
         "kind":"OPTION",
         "venue":"BIT",
         "expiration":1627027200000.0
      }
   ]
}

A [GET] /instruments/ request allows you to return all available Instruments upon Paradigm. Instruments are the legs apart of an RFQ.

Instrument names match the naming conventions of the underlying venue.

You must paginate to return the complete results.

Parameters

Name In Type Required Description
cursor query string false Cursor value used to paginate through pages.
asset query string false Base Currency of Instrument. Valid values include BTC, ETH, BCH, XRP, EOS.
ordering query string false How returned Instruments are sorted. Valid values include creation, expiration, and default.
page_size query string false Number of Instruments returned per pagination.
kind query string false The type of Instrument. Valid values include FUTURE and OPTION.
venue query string false The underlying venue the Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.
name query [string] false Paradigm Name of Instruments. Example /v1/grfq/instruments/?name=BTC-PERPETUAL,ETH-PERPETUAL.

Response Schema

Status Code 200

Name Type Required Description
count int true Total number of Instruments to paginate.
next string true Pagination cursor value.
results array of objects true
> option_kind string true The kind of Option. null if instrument is not an Option. Valid values include CALL, PUT, null.
> name string true The Paradigm standardized name of the Instrument.
> strike string true Option Instrument Strike Price. null if kind == FUTURE.
> kind string true The type of Instrument. Valid values include FUTURE and OPTION.
> venue string true Underlying venue Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.
> expiration number true Instrument expiration timestamp in unix milliseconds since the epoch. null if Instrument does not have an expiration.
> venue_name string true The name of the Instrument per the underlying venue's naming conventions.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 N/A "Invalid cursor" Use the string value from the next key in the first response to paginate.

[GET] /instruments/{venue}/{instrument_name}/

/instruments/{venue}/{instrument_name}/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/instruments/DBT/BTC-PERPETUAL/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/instruments/{venue}/{instrument_name}
method = 'GET'
path = '/v1/grfq/instruments/DBT/BTC-PERPETUAL/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/instruments/{venue}/{instrument_name}/ Response example

{
   "option_kind":null,
   "name":"BTC-4JUN21",
   "strike":null,
   "kind":"FUTURE",
   "venue":"DBT",
   "expiration":1622793600000.0
}

A [GET] /instruments/{venue}/{instrument_name}/ allows you to return information about a specific available Instrument.

Instruments are the legs apart of an RFQ.

Parameters

Name In Type Required Description
venue query string true The underlying venue the Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.
name query string true Paradigm Instrument Name.

Response Schema

Status Code 200

Name Type Required Description
count int true Total number of Instruments to paginate.
next string true Pagination cursor value.
results array of objects true
> option_kind string true The kind of Option. null if instrument is not an Option. Valid values include CALL, PUT, null.
> name string true The Instrument name per the underlying venue's naming convention.
> strike string true Option Instrument Strike Price. null if kind == FUTURE.
> kind string true The type of Instrument. Valid values include FUTURE and OPTION.
> venue string true Underlying venue Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.
> expiration number true Instrument expiration timestamp in unix milliseconds since the epoch. null if Instrument does not have an expiration.
> venue_name string true The name of the Instrument per the underlying venue's naming conventions.

Error Codes

HTTP Status Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.

[GET] /orders/

/orders/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/orders/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/orders/
method = 'GET'
path = '/v1/grfq/orders/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/orders/ Response example

{
   "count":2,
   "next":null,
   "results":[
      {
         "client_order_id":"",
         "rfq_id":551,
         "id":379,
         "filled_quantity":"0",
         "filled_average_price":"0",
         "limit_price":"0.1645",
         "requested_quantity":"25",
         "status":"CLOSED",
         "side": "BUY",
         "venue":"DBT"
      },
      {
         "client_order_id":"",
         "rfq_id":551,
         "id":378,
         "filled_quantity":"0",
         "filled_average_price":"0",
         "limit_price":"0.0642",
         "requested_quantity":"25",
         "satus":"CLOSED",
         "side": "BUY",
         "venue":"DBT"
      }
   ]
}

A [GET] /orders/ request will return all of the requesting user's and trading desks' Orders.

Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.

You must paginate to return the complete series of results.

Parameters

Name In Type Required Description
cursor query string false The pagination cursor value.
page_size query string false Number of orders to return per page.

Response Schema

Status Code 200

Name Type Required Description
count int true The total number of Orders available from request.
next string true The next pagination cursor. This value is null if there are no more pages.
results array of objects true
> client_order_id string true A unique user created identifier for the Order.
> rfq_id int true The Paradigm created unique identifier of the parent RFQ.
> id int true The Paradigm created unique identifier of the Order.
> filled_quantity string true The amount of the Order cleared & settled in the contract units of the RFQ.
> filled_average_price string true The average price of the filled quantity in the Quote Currency of the RFQ.
> limit_price string true The price of the submitted Order in the Quote Currency of the RFQ.
> requested_quantity string true The size of the Order in contract units of the RFQ.
> side string true The direction the Order executed upon the RFQ. Valid values include BUY and SELL.
> status string true The current status of the Order. Valid values include CLOSED.
> venue string true Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 N/A "Invalid cursor" Use the string value from the next key in the first response to paginate.

[GET] /orders/{order_id}/

/orders/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/orders/62/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/orders/{order_id}/
method = 'GET'
path = '/v1/grfq/orders/62/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/orders/ Response example

{
   "client_order_id":"",
   "rfq_id":589,
   "id":432,
   "filled_quantity":"0",
   "filled_average_price":"0",
   "limit_price":"2498",
   "requested_quantity":"50000000000",
   "side":"SELL",
   "status":"CLOSED",
   "venue":"DBT",
   "trades":[
      {
         "product_code":"CF",
         "quantity":"50000000000",
         "price":"2498",
         "id":479,
         "mark_price":"2498.93",
         "traded":1625193887212.47,
         "action":"SELL",
         "quote_currency":"USD",
         "quote_id":152838,
         "api_credential":"ParadigmTestNinetyFive"
      }
   ]
}

A [GET] /orders/{order_id}/ request will one of the requesting user's and trading desks' Orders.

Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm created unique identifier of the Order.

Response Schema

Status Code 200

Name Type Required Description
client_order_id string true A unique user created identifier for the trade Order.
rfq_id int true The Paradigm created unique identifier of the parent RFQ.
id int true The Paradigm created unique identifier of the Order.
filled_quantity string true The amount of the Order filled in the contract units of the RFQ.
filled_average_price string true The average price of the filled quantity in the Quote Currency of the RFQ.
limit_price string true The price of the submitted Order in the Quote Currency of the RFQ.
requested_quantity string true The size of the Order in contract units of the RFQ.
side string true The execution side of the Order on the RFQ. Valid values include BUY and SELL.
status string true The current status of the Order. Valid values include CLOSED.
venue string true Underlying venue Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.
trades array of objects true
> product_codes array of strings true The Paradigm Product Codes of the Trade.
> quantity string true The amount of contracts of the RFQ traded.
> price string true The price in the Quote Currency of the RFQ of the Trade.
> id int true The Paradigm created unique identifier of the Trade.
> mark_price string true The calculated mark price of the RFQ using the Venue's mark prices.
> traded number true The time in unix milliseconds since the epoch when the trade was cleared & settled.
> action string true The action taken on the Trade. valid values include BUY and SELL.
> quote_currency string true The asset which is the Quote Currency of the RFQ.
> quote_id int true The Paradigm created unique identifier of the Quote.
> api_credential string true The name given the to the Exchange API Key entered on the Paradigm Client Admin dashboard.
> status string true The status of the Trade. Valid values include PENDING, COMPLETED, REJECTED.

Error Codes

HTTP Status Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.

[GET] /quotes/

/quotes/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/quotes/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/quotes/
method = 'GET'
path = '/v1/grfq/quotes/?page_size=10&side=BUY'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/quotes/ Response example

{
   "count":5755,
   "next":"cD0yMDIxLTA3LTI2KzA2JTNBMjMlM0ExOC4xMTc1NDMlMkIwMCUzQTAw",
   "results":[
      {
         "id":2775578,
         "created":1631587522444.227,
         "maker":"DSK95",
         "price":"0.08",
         "remaining_quantity":"0",
         "side":"SELL",
         "status":"CLOSED",
         "client_order_id":"",
         "original_quantity":"25",
         "rfq_id":2073
      },
      {
         "id":2775577,
         "created":1631587522410.562,
         "maker":"DSK95",
         "price":"0.0795",
         "remaining_quantity":"0",
         "side":"BUY",
         "status":"CLOSED",
         "client_order_id":"",
         "original_quantity":"25",
         "rfq_id":2073
      },
      {
         "id":2775572,
         "created":1631587470993.799,
         "maker":"DSK95",
         "price":"0.09",
         "remaining_quantity":"24",
         "side":"BUY",
         "status":"CLOSED",
         "client_order_id":"",
         "order":{
            "id":266218,
            "client_order_id":"",
            "filled_quantity":"26",
            "filled_average_price":"0.0879",
            "limit_price":"0.09",
            "requested_quantity":"50",
            "rfq_id":2073,
            "side":"BUY",
            "status":"CLOSED",
            "venue":"DBT"
         },
         "original_quantity":"24",
         "rfq_id":2073
      },
      {
         "id":2775564,
         "created":1631587437845.888,
         "maker":"DSK95",
         "price":"0.0879",
         "remaining_quantity":"50",
         "side":"SELL",
         "status":"CLOSED",
         "client_order_id":"",
         "original_quantity":"50",
         "rfq_id":2073
      }
   ]
}

A [GET] /quotes/ request will return all of the requesting user's and trading desks' Quotes.

Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.

You must paginate to return the complete series of results.

Parameters

Name In Type Required Description
cursor query string false The pagination cursor value.
page_size query string false Number of Quotes to return per page.
rfq_id query string false The Paradigm created unique identifier of the RFQ.
side query string false The direction of the Quotes. Valid values include BUY and SELL.

Response Schema

Status Code 200

Name Type Required Description
count int true The total number of Quotes available to paginate over.
next string true The next pagination cursor. This value is null if there are no more pages.
results array of objects true
> created number true The time in unix milliseconds since the epoch when the Quote was created.
> id int true The Paradigm created unique identifier of the Quote.
> maker string true The Paradigm desk name of the Maker.
> price string true The price of the Quote in the Quote Currency of the Strategy.
> remaining_quantity string true The total remaining Quote size in contract units of the RFQ.
> side string true The direction of the Quote. Valid values include BUY and SELL.
> status string true The status of the Quote. Valid values include OPEN and CLOSED.
> client_order_id string true A unique user created identifier for the Quote.
> order object false Present if Quote crosses the existing market.
>> id int false The Paradigm created unique identifier of the Order.
>> client_order_id string false A unique user created identifier for the Order.
>> filled_quantity string false The filled quantity of the Order in the contract units of the RFQ.
>> filled_average_price string false The average filled price of the Order in the quote currency of the RFQ.
>> limit_price string false The price of the Order in quote currency of the RFQ.
>> requested_quantity string false The requested crossing quantity of the Order.
>> rfq_id int false The Paradigm created unique identifier of the RFQ the Order is a child of.
>> side string false The direction of the Order. Valid values include BUY and SELL.
>> status string false The current status of the Order. Valid values include OPEN and CLOSED.
>> venue string false Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.
> rfq_id int true The Paradigm created unique identifier of the RFQ the Quote is a child of.
> original_quantity string true The original Quote size in contract units of the RFQ.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 N/A "Invalid cursor" Use the string value from the next key in the first response to paginate.

[GET] /quotes/{quote_id}/

/quotes/{quote_id}/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/quotes/482199/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/quotes/{quote_id}/
method = 'GET'
path = '/v1/grfq/quotes/152780/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/quotes/{quote_id}/ Response example

{
   "id":2775572,
   "created":1631587470993.799,
   "maker":"DSK95",
   "price":"0.09",
   "remaining_quantity":"24",
   "side":"BUY",
   "status":"CLOSED",
   "client_order_id":"",
   "order":{
      "id":266218,
      "client_order_id":"",
      "filled_quantity":"26",
      "filled_average_price":"0.0879",
      "limit_price":"0.09",
      "requested_quantity":"50",
      "rfq_id":2073,
      "side":"BUY",
      "status":"CLOSED",
      "venue":"DBT"
   },
   "original_quantity":"24",
   "rfq_id":2073,
   "canceled":1631587471003.939
}

A [GET] /quotes/{quote_id}/ request will return the requesting user's and trading desks' specified Quote.

Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm created unique Quote identifier.

Response Schema

Status Code 200

Name Type Required Description
created number true The time in unix milliseconds since the epoch when the Quote was created.
id int true The Paradigm created unique identifier of the Quote.
maker string true The Paradigm desk name of the Maker who created the Quote.
price string true Price of the Quote in the Quote currency of the RFQ.
remaining_quantity string true The total remaining size of the Quote in contract units of the RFQ.
side string true The direction of the Quote. Valid values include BUY and SELL.
status string true The status of the quote. Valid values include OPEN and CLOSED.
client_order_id string true A unique user created identifier for the Quote.
order object false Present if Quote crosses the existing market.
> id int false The Paradigm created unique identifier of the Order.
> client_order_id string false A unique user created identifier for the Order.
> filled_quantity string false The filled quantity of the Order in the contract units of the RFQ.
> filled_average_price string false The average filled price of the Order in the quote currency of the RFQ.
> limit_price string false The price of the Order in quote currency of the RFQ.
> requested_quantity string false The requested crossing quantity of the Order.
> rfq_id int false The Paradigm created unique identifier of the RFQ the Order is a child of.
> side string false The direction of the Order. Valid values include BUY and SELL.
> status string false The current status of the Order. Valid values include OPEN and CLOSED.
> venue string false Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.
rfq_id int true The Paradigm created unique identifier of the RFQ the Quote is a child of.
original_quantity string true The original size of the Quote in contract units of the RFQ.
canceled number true The time in unix milliseconds since the epoch when the Quote was canceled. null if Quote has not been canceled.

Error Codes

HTTP Status Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.

[DELETE] /quotes/

/quotes/ Request example

# You can also use wget
curl -X DELETE https://api.test.paradigm.co/v1/grfq/quotes/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# DELETE /v1/grfq/quotes/
method = 'DELETE'
path = '/v1/grfq/quotes/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.delete(host+path,
                           headers=headers)

print(response.status_code)
print(response.text)

/quotes/ Response example

{
   "successes":{
      "count":2,
      "details":[
         152799,
         152798
      ]
   },
   "failures":{
      "count":0,
      "details":[

      ]
   }
}

A [DELETE] /quotes/ request cancels all existing Quotes.

Parameters

Name In Type Required Description
rfq_id query string false The Paradigm created unique identifier of the RFQ.
side query string false Cancel all Quotes by side. Valid values include BUY and SELL. Cancels all Quotes regardless of side if not specified.

Response Schema

Status Code 200

Name Type Required Description
successes array of objects true Information about Successful Quote Cancelations.
> count int true The number of OPEN Quotes that have now been Canceled.
> details array of objects true
>> id int true The Paradigm created unique identifier of the Quote.
>> created number true The time in unix milliseconds since the epoch when the Quote was created.
>> price string true The price in the Quote Currency of the RFQ of the Quote.
>> remaining_quantity string true The remaining quantity of the Quote in the contract units of the Quote.
>> side string true The direction of the Quote. Valid values include BUY and SELL.
>> status string true The status of the Quote. Valid values include CLOSED.
failures array of objects true Information about Unsuccessful Quote Cancelations.
> count int true The number of OPEN Quotes that have failed to be Canceled.
> details array of objects true
>> id int true The Paradigm created unique identifier of the Quote.
>> created number true The time in unix milliseconds since the epoch when the Quote was created.
>> price string true The price in the Quote Currency of the RFQ of the Quote.
>> remaining_quantity string true The remaining quantity of the Quote in the contract units of the Quote.
>> side string true The direction of the Quote. Valid values include BUY and SELL.
>> status string true The status of the Quote. Valid values include OPEN.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3305 "Invalid RFQ ID" Unavailable/Invalid RFQ Id requested.
400 3301 "Invalid quote side. Must either be BUY or SELL." Requested side query string value must be BUY or SELL.

[DELETE] /quotes/{quote_id}/

/quotes/{quote_id}/ Request example

# You can also use wget
curl -X DELETE https://api.test.paradigm.co/v1/grfq/quotes/15/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# DELETE /v1/grfq/quotes/{quote_id}/
method = 'DELETE'
path = '/v1/grfq/quotes/152797/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

response = requests.delete(host+path,
                           headers=headers)
print(response.status_code)
print(response.text)

A [DELETE] /quotes/{quote_id}/ request cancels an existing OPEN Quote created by the requesting user or user's trading desk.

You cannot cancel multiple Quotes with a single request using this endpoint.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm unique identifier of the Quote the user would like to cancel.

Response Schema

This request will return a HTTP Status Code of 204 to indicate success of operation.

Status Code 204

Schema below is solely for if the request resulted in a failed operation.

Name Type Required Description
code int true Error Code.
message string true The reason the request was unsuccessful.

Error Codes

HTTP Status Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3306 "Too late to cancel."
400 3308 "Unavailable quote

[GET] /rfqs/

/rfqs/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/rfqs/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/rfqs/
method = 'GET'
path = '/v1/grfq/rfqs/?rfq_id=57'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/rfqs/ Response example

{
   "count":13,
   "next":null,
   "results":[
      {
         "id":586,
         "venue":"DBT",
         "created":1625183214149.205,
         "description":"Put  9 Jul 21  32000",
         "last_trade":null,
         "latest_activity":1625183931073.739,
         "legs":[
            {
               "instrument":"BTC-9JUL21-32000-P",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":585,
         "venue":"DBT",
         "created":1625182846124.338,
         "description":"PFly  3 Jul 21  32000/33000/34000",
         "last_trade":null,
         "latest_activity":1625183645052.5972,
         "legs":[
            {
               "instrument":"BTC-3JUL21-32000-P",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            },
            {
               "instrument":"BTC-3JUL21-33000-P",
               "product_code":"DO",
               "ratio":"2",
               "side":"SELL"
            },
            {
               "instrument":"BTC-3JUL21-34000-P",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":583,
         "venue":"DBT",
         "created":1625181172208.664,
         "description":"Call  3 Jul 21  32000",
         "last_trade":null,
         "latest_activity":1625182827211.0642,
         "legs":[
            {
               "instrument":"BTC-3JUL21-32000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":584,
         "venue":"DBT",
         "created":1625182630789.73,
         "description":"Call  16 Jul 21  34000",
         "last_trade":null,
         "latest_activity":1625182651464.818,
         "legs":[
            {
               "instrument":"BTC-16JUL21-34000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":573,
         "venue":"DBT",
         "created":1625159972983.593,
         "description":"Put  16 Jul 21  34000",
         "last_trade":null,
         "latest_activity":1625182626036.611,
         "legs":[
            {
               "instrument":"BTC-16JUL21-34000-P",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":576,
         "venue":"DBT",
         "created":1625163614843.893,
         "description":"CFly  3 Jul 21  31000/32000/33000",
         "last_trade":null,
         "latest_activity":1625180836165.132,
         "legs":[
            {
               "instrument":"BTC-3JUL21-31000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            },
            {
               "instrument":"BTC-3JUL21-32000-C",
               "product_code":"DO",
               "ratio":"2",
               "side":"SELL"
            },
            {
               "instrument":"BTC-3JUL21-33000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":581,
         "venue":"BIT",
         "created":1625174242789.779,
         "description":"Straddle  3 Jul 21  1900",
         "last_trade":null,
         "latest_activity":1625180726439.838,
         "legs":[
            {
               "instrument":"ETH-3JUL21-1900-P",
               "product_code":"VT",
               "ratio":"1",
               "side":"BUY"
            },
            {
               "instrument":"ETH-3JUL21-1900-C",
               "product_code":"VT",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "VT"
         ],
         "status":"ACTIVE"
      },
      {
         "id":582,
         "venue":"DBT",
         "created":1625178072216.012,
         "description":"Cstm  +1  Call  3 Jul 21  32000\n      -2  Put  3 Jul 21  33000\n      +2  Call  9 Jul 21  34000\n      -1  Put  9 Jul 21  35000",
         "last_trade":null,
         "latest_activity":1625178072216.1091,
         "legs":[
            {
               "instrument":"BTC-3JUL21-32000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            },
            {
               "instrument":"BTC-3JUL21-33000-P",
               "product_code":"DO",
               "ratio":"2",
               "side":"SELL"
            },
            {
               "instrument":"BTC-9JUL21-34000-C",
               "product_code":"DO",
               "ratio":"2",
               "side":"BUY"
            },
            {
               "instrument":"BTC-9JUL21-35000-P",
               "product_code":"DO",
               "ratio":"1",
               "side":"SELL"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":575,
         "venue":"DBT",
         "created":1625160866037.8489,
         "description":"Call  9 Jul 21  32000",
         "last_trade":null,
         "latest_activity":1625173436428.965,
         "legs":[
            {
               "instrument":"BTC-9JUL21-32000-C",
               "product_code":"DO",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "status":"ACTIVE"
      },
      {
         "id":578,
         "venue":"DBT",
         "created":1625167876394.6099,
         "description":"Future  16 Jul 21",
         "last_trade":null,
         "latest_activity":1625172957461.732,
         "legs":[
            {
               "instrument":"BTC-16JUL21",
               "product_code":"CF",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "status":"ACTIVE"
      },
      {
         "id":580,
         "venue":"DBT",
         "created":1625172668390.126,
         "description":"FSpd  25 Mar 22 / 24 Jun 22",
         "last_trade":null,
         "latest_activity":1625172668390.178,
         "legs":[
            {
               "instrument":"BTC-25MAR22",
               "product_code":"CF",
               "ratio":"1",
               "side":"SELL"
            },
            {
               "instrument":"BTC-24JUN22",
               "product_code":"CF",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "status":"ACTIVE"
      },
      {
         "id":579,
         "venue":"DBT",
         "created":1625172652154.217,
         "description":"FSpd  Perpetual / 24 Jun 22",
         "last_trade":null,
         "latest_activity":1625172652154.271,
         "legs":[
            {
               "instrument":"BTC-PERPETUAL",
               "product_code":"CF",
               "ratio":"1",
               "side":"SELL"
            },
            {
               "instrument":"BTC-24JUN22",
               "product_code":"CF",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "status":"ACTIVE"
      },
      {
         "id":577,
         "venue":"BYB",
         "created":1625164847566.429,
         "description":"FSpd  24 Sep 21 / 31 Dec 21",
         "last_trade":null,
         "latest_activity":1625164847566.4849,
         "legs":[
            {
               "instrument":"BTCUSDU21",
               "product_code":"BB",
               "ratio":"1",
               "side":"SELL"
            },
            {
               "instrument":"BTCUSDZ21",
               "product_code":"BB",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "BB"
         ],
         "status":"ACTIVE"
      }
   ]
}

A [GET] /rfqs/ request returns information about ACTIVE RFQs.

Parameters

Name In Type Required Description
cursor query string false Cursor value, from the next key in the response, used to paginate through pages.
page_size query string false Number of RFQs to return per pagination.
product_codes query string false Paradigm Product Codes involved in RFQ. There can be multiple product codes. Example: /v1/grfq/rfqs/?product_codes=DO,CF
rfq_id query string false Paradigm created unique identifier for the RFQ.

Response Schema

Status Code 200

Name Type Required Description
count int true Total number of RFQs to paginate through from request.
next string true Pagination cursor value. null if no more pages are available.
results array of objects true
> id int true The Paradigm created unique identifier of the RFQ.
> venue string true The underlying venue the instruments are cleared & settled upon. Valid values include DBT, BIT, BYB.
> created number true Time in unix milliseconds since the epoch when the RFQ was created.
> description string true The description of the RFQ.
> last_trade object true null if RFQ has never been Traded.
>> traded number false Time in unix milliseconds since the epoch when the the Trade occurred.
>> quantity string false The size of the trade in the contract units of the RFQ.
>> price string false The price the RFQ was Traded at in the Quote Currency of the RFQ.
> latest_activity number true Time in unix milliseconds since the epoch when the RFQ, it’s quotes and trades were last updated.
> legs array of objects true
>> instrument string true The Paradigm standardizard name of the Instrument.
>> venue_instrument string true Instrument name per the underlying venue's naming convention.
>> product_code string true Paradigm Product Code of the Instrument.
>> ratio string true The multiplier applied to the quantity that the quote applies.
>> side string true The direction of the leg. Valid values include BUY and SELL.
> price string false Price of Instrument if the Instrument is a hedge leg in RFQ.
> product_codes array of strings true Paradigm Product Codes involved in the GRFQ.
> status string true Status of the RFQ. Valid values include ACTIVE.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 N/A "Invalid cursor" Use the string value from the next key in the first response to paginate.

[GET] /rfqs/{rfq_id}/

/rfqs/{rfq_id}/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/rfqs/20/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/rfqs/{rfq_id}/
method = 'GET'
path = '/v1/grfq/rfqs/581/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/ Response example

{
   "id":581,
   "venue":"BIT",
   "created":1625174242789.779,
   "description":"Straddle  3 Jul 21  1900",
   "last_trade":null,
   "latest_activity":1625180726439.838,
   "legs":[
      {
         "instrument":"ETH-3JUL21-1900-P",
         "product_code":"VT",
         "ratio":"1",
         "side":"BUY"
      },
      {
         "instrument":"ETH-3JUL21-1900-C",
         "product_code":"VT",
         "ratio":"1",
         "side":"BUY"
      }
   ],
   "product_codes":[
      "VT"
   ],
   "status":"ACTIVE"
}

A [GET] /rfqs/{rfq_id}/ request returns information about a specific RFQ.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm created unique identifier of the RFQ.

Response Schema

Status Code 200

Name Type Required Description
id int true The Paradigm created unique identifier of the RFQ.
venue string true The underlying venue the instruments are cleared & settled upon. Valid values include DBT, BIT, BYB.
created number true Time in unix milliseconds since the epoch when the RFQ was created.
description string true The description of the RFQ.
last_trade object true null if the RFQ has never been Traded.
> traded number false Time in unix milliseconds since the epoch when the the Trade occurred.
> quantity string false The size of the trade in the contract units of the RFQ.
> price string false The price the RFQ was Traded at.
latest_activity number true Time in unix milliseconds since the epoch when the RFQ, it’s quotes and trades were last updated.
legs array of objects true
> instrument string true The Paradigm standardized name of the Instrument.
> venue_instrument string true Instrument name per the underlying venue's naming conventions.
> price string false Price of Instrument if the Instrument is a hedge leg in RFQ.
> product_code string true Paradigm Product Code of the Instrument.
> ratio string true The multiplier applied to the quantity that the quote applies.
> side string true The direction of the leg. Valid values include BUY and SELL.
product_codes array of strings true Paradigm Product Codes involved in the RFQ.
status string true Status of the RFQ. Valid values include ACTIVE and EXPIRED.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3300 "Unavailable RFQ" Unavailable/invalid RFQ Id provided in request.

[POST] /rfqs/

/rfqs/ Request example

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# POST /v1/grfq/rfqs/
method = 'POST'
path = '/v1/grfq/rfqs/'

payload = {
           "venue":"DBT",
           "legs":[
               {
                "instrument":"BTC-PERPETUAL",
                "ratio":1,
                "side":"BUY"
               },
               {
                "instrument":"BTC-31DEC21",
                "ratio":1,
                "side":"SELL"
               }
           ]
           }
json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.post(host+path,
                         headers=headers,
                         json=payload)
print(response.status_code)
print(response.text)

/rfqs/ Response example

{
   "id":588,
   "venue":"DBT",
   "created":1625187733890.315,
   "description":"Cstm  +1  Future  Perpetual\n      -1  Future  31 Dec 21",
   "last_trade":null,
   "latest_activity":1625187733890.388,
   "legs":[
      {
         "instrument":"BTC-PERPETUAL",
         "product_code":"CF",
         "ratio":"1",
         "side":"BUY"
      },
      {
         "instrument":"BTC-31DEC21",
         "product_code":"CF",
         "ratio":"1",
         "side":"SELL"
      }
   ],
   "product_codes":[
      "CF"
   ],
   "status":"ACTIVE"
}

A [POST] /rfqs/ request allows a user to create a new RFQ and/or return the RFQ's information if one already exists.

The response schema and response is the same if the requester creates a new RFQ or an RFQ already exists.

Parameters

Name In Type Required Description
venue body string true The underlying venue the Instruments in the RFQ are cleared & settled upon. Valid values include DBT, BIT, BYB.
legs body array of objects true The individual legs of the RFQ.
> intrument body string true The name of the Instrument per the underlying venue's naming convention.
> price body string false The price of the leg in the Quote Currency of the Instrument if the leg is a hedge leg.
> ratio body sting true The quantity multiplier for the leg as apart of the Strategy.
> side body string true The direction of the leg. Valid values include BUY and SELL.

Response Schema

Status Code 201

Name Type Required Description
id int true The Paradigm created unique identifier of the RFQ.
venue string true The underlying RFQ venue the instruments are cleared & settled upon. Valid values include DBT, BIT, and BYB.
created number true The time in unix milliseconds since the epoch when the RFQ was created.
description string true The description of the RFQ.
last_trade object true null if no Trades have occured on the RFQ.
> traded number false Time in unix milliseconds since the epoch when the the Trade occurred.
> quantity string false The size of the trade in the contract units of the RFQ.
> price string false The price the RFQ was Traded at.
latest_activity number true The time in unix milliseconds since the epoch when the RFQ's quotes or trades were last updated.
legs array of objects true
> instrument string true The Paradigm standardized name of the RFQ leg.
> venue_instrument string true The name of the Instrument per the underlying venue's naming convention.
> product_code string true The Paradigm created product code of the Instrument in the leg.
> ratio number true The multiplier of the quantity of the instrument apart of the leg.
> side string true The direction of the leg in the strategy. Valid values include BUY and SELL.
> price string false The price of the leg in the Quote Currency of the Instrument. Only returned if the leg is a Hedge leg.
product_codes array of strings true The Paradigm created Product Codes of the instrument legs apart of the RFQ.
status string true The status of the RFQ. Valid values include ACTIVE.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
403 N/A "Your desk is not configured to trade in this venue's products" Ensure you have the venue key in your request payload. If so, ask Sales to enable the payload for your Desk.
400 1306 "Invalid instrument" An invalid Instrument name is apart of the request. Use the Paradigm standardized instrument key value.
400 3203 "Invalid leg parameters" There is an invalid leg parameter as apart of your request.

[POST] /rfqs/{rfq_id}/quotes/

/rfqs/{rfq_id}/quotes/ Request example

# built ins
import base64
import hmac
import time
import json

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# POST /v1/grfq/rfqs/{rfq_id}/quotes/
method = 'POST'
path = '/v1/grfq/rfqs/579/quotes/'

payload = {
           "account": "ParadigmTestNinetyFive",
           "client_order_id": "55",
           "legs": [
                {
                "instrument": "BTC-PERPETUAL",
                "price": "33000"
                },
                {
                "instrument": "BTC-24JUN22",
                "price": "33200"
                }
            ],
            "quantity": "1000000",
            "side": "SELL"
            }

json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.post(host+path,
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/quotes/ Response example

{
   "id":2776054,
   "created":1631589942042.397,
   "maker":"DSK95",
   "price":"0.09",
   "remaining_quantity":"24",
   "side":"BUY",
   "status":"CLOSED",
   "client_order_id":"stri1231321232121223231321132312213ng",
   "order":{
      "id":266318,
      "client_order_id":"stri1231321232121223231321132312213ng",
      "filled_quantity":"0",
      "filled_average_price":"0",
      "limit_price":"0.09",
      "requested_quantity":"50",
      "rfq_id":2073,
      "side":"BUY",
      "status":"OPEN",
      "venue":"DBT"
   },
   "original_quantity":"24",
   "rfq_id":2073
}

A [POST] /rfqs/{rfq_id}/quotes/ request creates a Quote upon a specific RFQ.

Takers & Makers use this endpoint to cross the existing market or create a resting Limit Order. Remaining amounts of the Quote remain on the Quote Book in the event of crossing.

If post_only == true and the submitted Quote crosses the existing market, the Quote is canceled in its entirety. This ensures you are always a Maker.

If a user submits a Quote which crosses the existing market, you will receive messages on both the quote and order JSON-RPCoverWebSockets Notification channels.

Parameters

Name In Type Required Description
id endpoint string true The unique Paradigm created identifier of the RFQ.
account body string true The name of the Exchange API Key entered on your Client Admin dashboard.
client_order_id body string true A unique user created identifier for the Quote.
legs body array of objects true Array of objects containing the strategy’s legs' quotes' attributes.
> instrument body string true The Paradigm standardized name of the Instrument.
> price body string true The price of the individual Instrument apart of the leg.
quantity body string true The total quantity of the strategy in contract units of the RFQ.
side body string true The direction of the Quote. Valid values include BUY and SELL.
post_only body boolean false If true, the quote is canceled and never enters the Quote Book if it crosses the existing market.

Response Schema

Status Code 200

Name Type Required Description
id int true The Paradigm created unique identifier of the Quote.
created number true The time in unix milliseconds since the epoch when the Quote was created.
maker string true The Paradigm desk name that created the Quote.
price string true The price of the strategy in the Quote Currency of the RFQ.
remaining_quantity string true Total size of the Quote in contract units of the RFQ remaining.
side string true The direction of the Quote. Valid values include BUY and SELL.
status string true The status of the Quote. Valid values include OPEN.
client_order_id string true A unique user created identifier for the Quote.
order object false Present if Quote crosses the existing market.
> id int false The Paradigm created unique identifier of the Order.
> client_order_id string false A unique user created identifier for the Order.
> filled_quantity string false The filled quantity of the Order in the contract units of the RFQ.
> filled_average_price string false The average filled price of the Order in the quote currency of the RFQ.
> limit_price string false The price of the Order in quote currency of the RFQ.
> requested_quantity string false The requested crossing quantity of the Order.
> rfq_id int false The Paradigm created unique identifier of the RFQ the Order is a child of.
> side string false The direction of the Order. Valid values include BUY and SELL.
> status string false The current status of the Order. Valid values include OPEN and CLOSED.
> venue string false Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.
original_quantity string true Initial size of the Quote in contract units of the RFQ.
rfq_id int true The Paradigm created unique identifier of the RFQ the Quote is a child of.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." N/A
400 100 "Invalid parameters" Invalid parameters in request such as a non-unique client_order_id value.
400 1302 "Invalid account information" The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard.
400 3203 "Invalid leg parameters" Ensure you are attempting to quote on the correct RFQ. Check your request format is correct.
400 3303 "An active BUY(SELL)-side quote already exists. Please cancel that quote before submitting a new quote." Refer to error message.
400 3304 "Your Bid/Ask was canceled. It crossed the available Ask/Bid." This occurs when you specify post_only == true and the submitted Quote crosses the market or if you cross your own existing Quote.
400 3304 "{instrument_name}. Bid/Ask price cannot be greater than Ask/Bid Price." This occurs when the Bid/Ask price of a leg apart of the submitting Quote is greater than the Ask/Bid price of the same leg in an existing Quote.

[PATCH] /rfqs/{rfq_id}/quotes/

/rfqs/{rfq_id}/quotes/ Request example

# built ins
import base64
import hmac
import time
import json

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# PATCH /v1/grfq/rfqs/{rfq_id}/quotes/
method = 'PATCH'
path = '/v1/grfq/rfqs/1230/quotes/'

payload = {
            "account": "ParadigmTestNinetyFive",
            "client_order_id": "1223322132123123321",
            "quantity": "5000000",
            "side": "BUY",
            "legs": [
                {
                "instrument": "BTC-PERPETUAL",
                "price": "38501"
                }
               ],
            "post_only": True
            }

json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.patch(host+path,
                          headers=headers,
                          json=payload)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/quotes/ Response example

{
   "id":2776054,
   "created":1631589942042.397,
   "maker":"DSK95",
   "price":"0.09",
   "remaining_quantity":"24",
   "side":"BUY",
   "status":"CLOSED",
   "client_order_id":"stri1231321232121223231321132312213ng",
   "order":{
      "id":266318,
      "client_order_id":"stri1231321232121223231321132312213ng",
      "filled_quantity":"0",
      "filled_average_price":"0",
      "limit_price":"0.09",
      "requested_quantity":"50",
      "rfq_id":2073,
      "side":"BUY",
      "status":"OPEN",
      "venue":"DBT"
   },
   "original_quantity":"24",
   "rfq_id":2073
}

A [PATCH] /rfqs/{rfq_id}/quotes/ request replaces an existing Quote upon a specific RFQ.

Takers & Makers use this endpoint to cross the existing market or update a resting Limit Order. Remaining amounts of the Quote remain on the Quote Book in the event of crossing.

If post_only == true and the submitted Quote crosses the existing market, the Quote is canceled in its entirety. This ensures you are always a Maker.

If a user submits a Quote which crosses the existing market, you will receive messages on both the quote and order JSON-RPCoverWebSockets Notification channels.

Parameters

Name In Type Required Description
id endpoint string true The unique Paradigm created identifier of the RFQ.
account body string true The name of the Exchange API Key entered on your Client Admin dashboard.
client_order_id body string true A unique user created identifier for the Quote.
legs body array of objects true Array of objects containing the strategy’s legs' quotes' attributes.
> instrument body string true The Paradigm standardized name of the Instrument.
> price body string true The price of the individual Instrument apart of the leg.
quantity body string true The total quantity of the strategy in contract units of the RFQ.
side body string true The direction of the Quote. Valid values include BUY and SELL.
post_only body boolean false If true, the quote is canceled and never enters the Quote Book if it crosses the existing market.

Response Schema

Status Code 200

Name Type Required Description
id int true The Paradigm created unique identifier of the Quote.
created number true The time in unix milliseconds since the epoch when the Quote was created.
maker string true The Paradigm desk name that created the Quote.
price string true The price of the strategy in the Quote Currency of the RFQ.
remaining_quantity string true Total size of the Quote in contract units of the RFQ remaining.
side string true The direction of the Quote. Valid values include BUY and SELL.
status string true The status of the Quote. Valid values include OPEN.
client_order_id string true A unique user created identifier for the Quote.
order object false Present if Quote crosses the existing market.
> id int false The Paradigm created unique identifier of the Order.
> client_order_id string false A unique user created identifier for the Order.
> filled_quantity string false The filled quantity of the Order in the contract units of the RFQ.
> filled_average_price string false The average filled price of the Order in the quote currency of the RFQ.
> limit_price string false The price of the Order in quote currency of the RFQ.
> requested_quantity string false The requested crossing quantity of the Order.
> rfq_id int false The Paradigm created unique identifier of the RFQ the Order is a child of.
> side string false The direction of the Order. Valid values include BUY and SELL.
> status string false The current status of the Order. Valid values include OPEN and CLOSED.
> venue string false Underlying venue RFQ is cleared & settled upon. Valid values include DBT, BIT, BYB.
original_quantity string true Initial size of the Quote in contract units of the RFQ.
rfq_id int true The Paradigm created unique identifier of the RFQ the Quote is a child of.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." N/A
400 100 "Invalid parameters" Invalid parameters in request such as a non-unique client_order_id value.
400 1302 "Invalid account information" The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard.
400 3203 "Invalid leg parameters" Ensure you are attempting to quote on the correct RFQ. Check your request format is correct.
400 3303 "An active BUY(SELL)-side quote already exists. Please cancel that quote before submitting a new quote." Refer to error message.
400 3304 "Your Bid/Ask was canceled. It crossed the available Ask/Bid." This occurs when you specify post_only == true and the submitted Quote crosses the market or if you cross your own existing Quote.
400 3304 "{instrument_name}. Bid/Ask price cannot be greater than Ask/Bid Price." This occurs when the Bid/Ask price of a leg apart of the submitting Quote is greater than the Ask/Bid price of the same leg in an existing Quote.

[POST] /rfqs/{rfq_id}/orders/

/rfqs/{rfq_id}/orders/ Request example

# built ins
import base64
import hmac
import time
import json

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# POST /v1/grfq/rfqs/{rfq_id}/orders/
method = 'POST'
path = '/v1/grfq/rfqs/810/orders/'

payload = {
           "account": "ParadigmTestNinetyFive",
           "client_order_id": "122321321321321321",
           "limit_price": "0.0267",
           "quantity": "25",
           "execution_side": "BUY"
           }

json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.post(host+path,
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/orders/ Response example

{
   "client_order_id":"1223213321321321321",
   "rfq_id":810,
   "id":767,
   "filled_quantity":"0",
   "filled_average_price":"0",
   "limit_price":"0.026",
   "requested_quantity":"35",
   "side":"BUY",
   "status":"OPEN",
   "venue":"DBT"
}

A [POST] /rfqs/{rfq_id}/orders/ request creates an Order upon a specific RFQ.

Takers use Orders to execute upon existing Quotes.

Your request must cross the market to be executed. If this request does not cross, no Quote will be created on the Quote Book and you will receive a 3400 code in response.

If you request a greater quantity then is possible to be consumed while satisfying the underlying venues' (except Bybit) "Minimum Block Size", your Order will consume as much quantity as possible and forget the remaining quantity of the request.

Parameters

Name In Type Required Description
rfq_id endpoint string true The unique Paradigm created identifier of the RFQ.
account body string true The name of the Exchange API Key entered on your Client Admin dashboard.
client_order_id body string false A unique user created identifier for the Order.
execution_side body string true The side to execute upon. Valid values include BUY and SELL.
limit_price body string true The limit price in the Quote Currency of the RFQ to execute at.
quantity body string true The total quantity of the strategy in contract units of the RFQ.

Response Schema

Status Code 200

Name Type Required Description
client_order_id string true A unique user created identifier for the trade Order.
rfq_id int true The Paradigm created unique identifier of the parent RFQ.
id int true The Paradigm created unique identifier of the Order.
filled_quantity string true The amount of the Order filled in the contract units of the RFQ.
filled_average_price string true The average price of the filled quantity in the Quote Currency of the RFQ.
limit_price string true The price of the submitted Order in the Quote Currency of the RFQ.
requested_quantity string true The size of the Order in contract units of the RFQ.
side string true The side of the Order executed on the RFQ. Valid values include BUY and SELL.
status string true The current status of the Order. Valid values include OPEN.
venue string true Underlying venue Instrument is cleared & settled upon. Valid values include DBT, BIT, BYB.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." N/A
400 100 "Invalid parameters" Invalid parameters in request such as a non-unique client_order_id value.
400 1302 "Invalid account information" The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard.
400 3400 "No Quotes available for execution" Refer to error message.
400 3203 "Invalid leg parameters" Ensure you are attempting to quote on the correct RFQ. Check your request format is correct.
400 3403 "Quantioty must be greater than or equal to 20000." This relates to the Block Size Minimum of the RFQ enforced by the underlying venue.

[POST] /pricing/

/pricing/ Request example

# built ins
import base64
import hmac
import time
import json

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# POST /v1/grfq/pricing/
method = 'POST'
path = '/v1/grfq/pricing/'

payload = {
           "venue": "DBT",
           "bid_price": "7950",
           "ask_price": "9600",
           "legs": [
               {
                   "ratio": "1",
                   "instrument": "BTC-PERPETUAL",
                   "side": "BUY"
               },
               {
                   "ratio": "1",
                   "instrument": "BTC-31DEC21",
                   "side": "SELL"
               }

           ]
            }
json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.post(host+path,
                         headers=headers,
                         json=payload)
print(response.status_code)
print(response.text)

/pricing/ Response example

{
   "bid_prices":[
      "32655.32",
      "24705.32"
   ],
   "ask_prices":[
      "33606.76",
      "24006.76"
   ]
}

A [POST] /pricing/ request will return the individual leg prices of a proposed Quote.

This endpoint does not create a Quote or complete any operation upon the matching engine.

Parameters

Name In Type Required Description
venue body string true The underlying venue the Instruments in the RFQ are cleared & settled upon. Valid values include DBT, BIT, and BYB.
bid_price body string true The total price of the Quote when the side is equal to BUY.
ask_price body string true The total price of the Quote when the side is equal to SELL.
legs body array of objects true The individual legs of the RFQ.
> ratio body string true The quantity multiplier for the leg as apart of the Strategy.
> instrument body string true The name of the Instrument apart of the leg per the underlying venue's naming convention.
> side body string true The direction of the leg. Valid values include BUY and SELL.

Response Schema

Status Code 200

Name Type Required Description
bid_prices array of numbers true The individual leg prices of the BUY sided quote in the order legs proposed in the user’s request.
ask_prices array of numbers true The individual leg prices of the SELL sided quote in the order legs proposed in the user’s request.

Error Codes

HTTP Status Code Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3002 "Invalid leg pricing parameters" Invalid leg pricing parameters was requested.
400 3304 "Quote price {-2100.32} outside strategy price bands ({7902.18} / {9627.5})" Quote must be within these price bands.

[GET] /rfqs/{rfq_id}/bbo

/rfqs/{rfq_id}/bbo Request example

# You can also use wget
curl -X POST https://api.test.paradigm.co/v1/grfq/rfqs/131/bbo/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = 'Z9gBdD05yiHLotRCxrSeFTfC'
secret_key = b'9qgG7DU0XNaqF9n5Q35iQtL5Bv7JFNUffagT7/qC9jlH0exj'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.nightly.paradigm.co'

# GET /v1/grfq/rfqs/{rfq_id}/bbo
method = 'GET'
path = '/v1/grfq/rfqs/579/bbo'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/bbo Response example

{
   "venue":"DBT",
   "best_bid":{
      "price":"-33118.5",
      "quantity":"0"
   },
   "best_ask":{
      "price":"-1118",
      "quantity":"148640"
   },
   "leg_prices":[
      {
         "instrument":"BTC-PERPETUAL",
         "best_bid_price":"33118",
         "best_bid_quantity":"148640",
         "best_ask_price":"33118.5",
         "best_ask_quantity":"491190",
         "mark_price":"33077.21",
         "timestamp":1625189984659
      },
      {
         "instrument":"BTC-24JUN22",
         "best_bid_price":"0",
         "best_bid_quantity":"0",
         "best_ask_price":"32000",
         "best_ask_quantity":"990000",
         "mark_price":"31948.95",
         "timestamp":1625189984174
      }
   ],
   "mark_price":"-1128.26",
   "product_code":"CF"
}

A [GET] /rfqs/{rfq_id}/bbo request returns the best Bid/Offer information from the underlying venue for a specific RFQ.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm created unique identifier of the RFQ.

Response Schema

Status Code 200

Name Type Required Description
venue string true The underlying venue where the Instruments apart of the RFQ are cleared & settled upon. Valid values include DBT, BIT, and BYB.
best_bid array of objects true
> price string true The calculated best bid price of the RFQ’s strategy per the legs' underlying screen price in the Quote Currency of the RFQ.
> quantity string true The calculated best bid price of the RFQ’s strategy per the legs' underlying screen quantity in contract units of the RFQ.
best_ask array of objects true
> price string true The calculated best ask price of the RFQ’s strategy per the legs' underlying screen price in the Quote Currency of the RFQ.
> quantity string true The calculated best ask price of the RFQ’s strategy per the legs' underlying screen quantity in contract units of the RFQ.
leg_prices array of objects true
> instrument string true The Paradigm standardized name of the Instrument.
> best_bid_price string true The best bid on the underlying exchange’s Instrument Quote Book in the Quote Currency of the Instrument.
> best_bid_quantity string true The best bid’s quantity on the underlying exchange’s Instrument Quote Book in contract units of the RFQ.
> best_ask_price string true The best ask on the underlying exchange’s Instrument Quote Book in the Quote Currency of the Instrument.
> best_ask_quantity string true The best ask’s quantity on the underlying exchange’s Instrument Quote Book in contract units of the RFQ.
> mark_price string true The Mark price from the underlying exchange for specific Instrument in the Quote Currency of the Instrument.
> timestamp number true The time in unix milliseconds since the epoch when the data was returned from the underlying venue.
mark_price string true The calculated Mark Price of the strategy in the Quote Currency of the RFQ.
product_code string true The Paradigm created Product Code of in the Instruments involved in the RFQ.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3300 "Unavailable RFQ" RFQ is unavailable to be priced.

[GET] /rfqs/{rfq_id}/quotes/

/rfqs/{rfq_id}/quotes/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/rfqs/131/quotes/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/rfqs/{rfq_id}/quotes/
method = 'GET'
path = '/v1/grfq/rfqs/576/quotes/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/rfqs/{rfq_id}/quotes/ Response example

{
   "id":576,
   "bids":[
      {
         "created":1625167826211.088,
         "id":152748,
         "price":"0.0078",
         "remaining_quantity":"29943.7",
         "side":"BUY",
         "status":"OPEN"
      }
   ],
   "asks":[
      {
         "created":1625173113830.57,
         "id":152762,
         "price":"0.0084",
         "remaining_quantity":"33.7",
         "side":"SELL",
         "status":"OPEN"
      }
   ]
}

A [GET] /rfqs/{rfq_id}/quotes/ request returns the OPEN Quotes upon the RFQ.

Parameters

Name In Type Required Description
id endpoint string true The Paradigm created unique identifier of the RFQ.

Response Schema

Status Code 200

Name Type Required Description
id int true The Paradigm created unique identifier of the RFQ.
bids array of objects true Empty array if no Quotes are available.
> created number true The time in unix milliseconds since the epoch when the Quote was created.
> id int true The Paradigm created unique identifier of the Quote.
> maker string false The Paradigm Desk Name of the Maker who created the quote. Only visible if requester is the Maker.
> remaining_quantity string true The total remaining size of the Quote in the contract units of the RFQ.
> price string true The price of the Quote in the Quote Currency of the RFQ.
> side string true The direction of the Quote. Valid values include BUY.
> status string true The status of the Quote. Valid values include OPEN
asks array of objects true Empty array if no Quotes are available.
> created number true The time in unix milliseconds since the epoch when the Quote was created.
> id int true The Paradigm created unique identifier of the Quote.
> maker string false The Paradigm Desk Name of the Maker who created the quote. Only visible if requester is the Maker.
> remaining_quantity string true The total remaining size of the Quote in the contract units of the RFQ.
> price string true The price of the Quote in the Quote Currency of the RFQ.
> side string true The direction of the Quote. Valid values include SELL.
> status string true The status of the Quote. Valid values include OPEN

Error Codes

HTTP Status Code Message Code Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 "Unavailable RFQ" 3300 RFQ is unavailable to be priced.

[GET] /trades/

/trades/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/trades/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time
import json

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/trades/
method = 'GET'
path = '/v1/grfq/trades/'

payload = {}

json_payload = json.dumps(payload)

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=json_payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                         headers=headers,
                         json=payload)

print(response.status_code)
print(response.text)

/trades/ Response example

{
   "count":909,
   "next":"cD0yMDIxLTA3LTI3KzE2JTNBMjElM0EyMC40MTQ3MjMlMkIwMCUzQTAw",
   "results":[
      {
         "id":1221,
         "description":"FSpd  Perpetual / 31 Dec 21",
         "mark_price":"1544.18",
         "order_id":1094,
         "price":"1550",
         "product_codes":[
            "CF"
         ],
         "quantity":"10000",
         "quote_currency":"USD",
         "quote_id":616016,
         "rfq_id":1178,
         "traded":1627440685659.369,
         "venue":"DBT",
         "action":"BUY",
         "api_credential":"ParadigmTestNinetyFive",
         "client_order_id":"",
         "status":"COMPLETED"
      },
      {
         "id":1219,
         "description":"Cstm  -13.3  Future  Perpetual\n      +1  Future  30 Jul 21\n      +19.9  Future  6 Aug 21",
         "mark_price":"289592.31",
         "price":"289467.236",
         "product_code":"CF",
         "quantity":"586",
         "quote_currency":"USD",
         "rfq_id":1176,
         "traded":1627419839512.485,
         "venue":"DBT"
      },
      {
         "id":1217,
         "description":"Cstm  +1  Put  30 Jul 21  38000\n      -1  Put  30 Jul 21  40000",
         "mark_price":"-0.0285",
         "price":"-0.0005",
         "product_code":"DO",
         "quantity":"13",
         "quote_currency":"BTC",
         "rfq_id":1174,
         "traded":1627418321044.7131,
         "venue":"DBT"
      },
      {
         "id":1216,
         "description":"Cstm  +1  Future  Perpetual\n      +1.7  Future  31 Dec 21\n      +2.8  Future  24 Sep 21",
         "mark_price":"210922.959",
         "price":"211492",
         "product_code":"BB",
         "quantity":"5",
         "quote_currency":"USD",
         "rfq_id":1172,
         "traded":1627402886964.928,
         "venue":"BYB"
      },
      {
         "id":1215,
         "description":"Cstm  +1  Future  Perpetual\n      +1.7  Future  31 Dec 21\n      +2.8  Future  24 Sep 21",
         "mark_price":"211042.936",
         "price":"211492",
         "product_code":"BB",
         "quantity":"4",
         "quote_currency":"USD",
         "rfq_id":1172,
         "traded":1627402880414.723,
         "venue":"BYB"
      }
   ]
}

A [GET] /trades/ request returns all completed Trades on Paradigm.

Parameters

Name In Type Required Description
cursor query string false The pagination page to return. Valid determined by the next key value in the response.
hide_public query string false Hide non-participant trades from results. Valid values include true and false.
page_size query string false The number of Trades to return per pagination.
status query string false The state of the Trades to return. Valid values include PENDING, COMPLETED, REJECTED.

Response Schema

Status Code 200

Name Type Required Description
count int true Total number of Trades to paginate through from request.
next string true null if no more pages to paginate. The value used for the cursor query string parameter to paginate pages.
results array of objects true
> id int true The Paradigm created unique identifier of the Trade.
> description string true The description of the RFQ.
> mark_price string true The mark price of the RFQ at execution in the Quote Currency of the RFQ using the underlying venue's mark price(s) of the RFQ.
> order_id int false The Paradigm created unique identifier of the Order if the user is the Taker of the Trade.
> price string true The price in the Quote Currency of the RFQ of the Trade.
> product_codes array of strings true The Paradigm created Product Codes apart of the RFQ.
> quantity string true The size of the trade in contract units of the RFQ.
> quote_currency string true The Quote Currency of the RFQ.
> rfq_id int true The Paradigm created unique identifier of the RFQ.
> status string true Trade status. Valid values include PENDING, COMPLETED, REJECTED.
> traded number true The time in unix milliseconds since the epoch when the was cleared & settled at.
> venue string true The underlying venue the Trade was cleared & settled upon. Valid values include DBT, BIT, BYB.
> action string false The side of the Order. Only available if the requester is the Taker of the Trade. Valid values include BUY and SELL.
> api_credential string false The name of the exchange API key used to execute upon the Quote. Only available if the requester is the Taker to the Trade.
> client_order_id string false The user created Order label if the user is the Taker of the Trade.
> quote_id int false The Paradigm created unique identifier of the executed Quote.

Error Codes

HTTP Status Code Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 N/A "Invalid cursor" Use the string value from the next key in the first response to paginate.

[GET] /trades/{trade_id}/

/trades/{trade_id}/ Request example

# You can also use wget
curl -X GET https://api.test.paradigm.co/v1/grfq/trades/50/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <access-key>'

# built ins
import base64
import hmac
import time

# installed
import requests

access_key = '<access-key>'
secret_key = b'<secret-key>'


def sign_request(secret_key, method, path, body):
    signing_key = base64.b64decode(secret_key)
    timestamp = str(int(time.time() * 1000)).encode('utf-8')
    message = b'\n'.join([timestamp, method.upper(), path, body])
    digest = hmac.digest(signing_key, message, 'sha256')
    signature = base64.b64encode(digest)
    return timestamp, signature


# Request Host
host = 'https://api.test.paradigm.co'

# GET /v1/grfq/trades/{trade_id}/
method = 'GET'
path = '/v1/grfq/trades/473/'

payload = ''

timestamp, signature = sign_request(secret_key=secret_key,
                                    method=method.encode('utf-8'),
                                    path=path.encode('utf-8'),
                                    body=payload.encode('utf-8'),
                                    )

headers = {
           'Paradigm-API-Timestamp': timestamp,
           'Paradigm-API-Signature': signature,
           'Authorization': f'Bearer {access_key}'
          }

# Send request
response = requests.get(host+path,
                        headers=headers)

print(response.status_code)
print(response.text)

/trades/{trade_id}/ Response example - User's Trade COMPLETED

{
   "id":1221,
   "description":"FSpd  Perpetual / 31 Dec 21",
   "mark_price":"1544.18",
   "order_id":1094,
   "price":"1550",
   "product_codes":[
      "CF"
   ],
   "quantity":"10000",
   "quote_currency":"USD",
   "quote_id":616016,
   "rfq_id":1178,
   "traded":1627440685659.369,
   "venue":"DBT",
   "action":"BUY",
   "api_credential":"ParadigmTestNinetyFive",
   "client_order_id":"",
   "status":"COMPLETED",
   "legs":[
      {
         "id":1989,
         "instrument":"BTC-PERPETUAL",
         "price":"39952.58",
         "product_code":"CF",
         "quantity":"10000",
         "ratio":"1",
         "side":"SELL",
         "action":"SELL",
         "exec_id":"77508944"
      },
      {
         "id":1990,
         "instrument":"BTC-31DEC21",
         "price":"41502.58",
         "product_code":"CF",
         "quantity":"10000",
         "ratio":"1",
         "side":"BUY",
         "action":"BUY",
         "exec_id":"77508943"
      }
   ]
}

/trades/{trade_id}/ Response example - User's Trade REJECTED

{
   "id":1220,
   "description":"FSpd  Perpetual / 31 Dec 21",
   "mark_price":"1537.57",
   "order_id":1093,
   "price":"1550",
   "product_codes":[
      "CF"
   ],
   "quantity":"10000",
   "quote_currency":"USD",
   "quote_id":616014,
   "rfq_id":1178,
   "traded":1627440566959.332,
   "venue":"DBT",
   "action":"BUY",
   "api_credential":"ParadigmTestNinetyFive",
   "client_order_id":"",
   "status":"REJECTED",
   "legs":[
      {
         "id":1987,
         "instrument":"BTC-PERPETUAL",
         "price":"39900.66",
         "product_code":"CF",
         "quantity":"10000",
         "ratio":"1",
         "side":"SELL",
         "action":"SELL",
         "exec_id":null
      },
      {
         "id":1988,
         "instrument":"BTC-31DEC21",
         "price":"41450.66",
         "product_code":"CF",
         "quantity":"10000",
         "ratio":"1",
         "side":"BUY",
         "action":"BUY",
         "exec_id":null
      }
   ]
}

/trades/{trade_id}/ Response example - User not aparty to COMPLETED

{
   "id":587,
   "description":"Call  22 Oct 21  52000",
   "mark_price":"0.0788",
   "price":"0.09",
   "product_codes":[
      "DO"
   ],
   "quantity":"25",
   "quote_currency":"BTC",
   "rfq_id":1118,
   "traded":1634064072771.3809,
   "venue":"DBT",
   "legs":[
      {
         "id":862,
         "instrument":"BTC-22OCT21-52000-C",
         "price":"0.09",
         "product_code":"DO",
         "quantity":"25",
         "ratio":"1",
         "side":"BUY"
      }
   ]
}

A [GET] /trades/{trade_id}/ request returns a specific Trade on Paradigm.

Parameters

Name In Type Required Description
id query string true The Paradigm created unique identifier of the Trade.

Response Schema

Status Code 200

Name Type Required Description
count int true Total number of Trades to paginate through from request.
next string true null if no more pages to paginate. The value used for the cursor query string parameter to paginate pages.
results array of objects true
> id int true The Paradigm created unique identifier of the Trade.
> description string true The description of the RFQ.
> mark_price string true The mark price of the RFQ at execution in the Quote Currency of the RFQ using the underlying venue's mark price(s) of the RFQ.
> price string true The price in the Quote Currency of the RFQ of the Trade.
> product_codes array of strings true The Paradigm created Product Codes apart of the RFQ.
> quantity string true The size of the trade in contract units of the RFQ.
> quote_currency string true The Quote Currency of the RFQ.
> rfq_id int true The Paradigm created unique identifier of the RFQ.
> traded number true The time in unix milliseconds since the epoch when the was cleared & settled at.
> venue string true The underlying venue the Trade was cleared & settled upon. Valid values include DBT, BIT, BYB.
> legs array of objects true
>> id int false The Paradigm created unique individual leg trade identifier.
>> instrument string true The Paradigm standardized name of the Instrument.
>> quantity string true The size of the leg traded in contract unit terms.
>> price string true The price of the leg traded in the Quote Currency of the RFQ.
>> product_code string true The Paradigm created product code of the Instrument traded.
>> ratio string true The quantity multiplier relative to other Instrument legs.
>> side string false The direction of the leg as apart of the original RFQ. Valid values include BUY and SELL. This does not reveal the direction of the Trade.
>> action string false The direction of the user for the specific leg of the RFQ. Valid values include BUY and SELL.
>> exec_id string false The venue created unique identifier of the trade.
> api_credentials string false The name of venue API key used by the user in the Trade.
> client_order_id string false The user created unique identifer.
> status string true If the trade succesfully cleared & settled on the underlying venue. Valid values include COMPLETED and REJECTED.

Error Codes

HTTP Status Code Message Meaning
401 "Authentication credentials provided were not provided." You did not provide authentication credentials.
404 "Not found." Invalid Trade Id value requested.