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's three major products are Unified Markets (UM), the Future Spread Dashboard (FSPD), and Vault Request for Quote (VRFQ).

Paradigm provides a GUI to access all products via a desktop application as well as your internet browser.

Paradigm provides RESToverHTTP and JSON-RPCoverWebSockets API interfaces for users with workflows consistent with the broader crypto space.

Feel free to reach out to our account management team or technical solutions team as we would love to help!

UM - Brief Overview

Unified Markets (UM) has two products, Directed Request for Quote (DRFQ) and Global Request for Quote (GRFQ), which make up the UM user interface.

DRFQ enables users to create short-lived private auction RFQ markets. Users must specify the structure of the market as well as the counterparties who are able to return prices. In DRFQ, only the creator of the market is able to see the returned prices from the Makers and is able to cross a Maker's order. Makers are unable to see eachother's prices or their order's relative priority. To note, there are two versions of DRFQ, DRFQv1 and DRFQv2. Users should use DRFQv2 as DRFQv1 will be deprecated in due course.

GRFQ enables users to create long-lived public auction Central Limit Order Book markets. Users must specify the structure of the market and anyone is able to participate. In GRFQ, all orders submitted are blind and are actionable by any user.

Deribit, BIT, and Bybit are available as venues.

FSPD - Brief Overview

The Future Spread Dashboard (FSPD) enables users to trade two-legged Spot/Future or Future/Future strategies in long-lived public auction Central Limit Order Book markets. Paradigm manages the availability of markets. In FSPD, all orders submitted are blind and are actionable by any user.

Deribit and Bybit are available as venues.

VRFQ - Brief Overview

Vault Request for Quote (VRFQ) enables vault providers to create short-lived private auction RFQ markets. In VRFQ, only the creator of the market is able to see the returned prices, the associated counterparty & is able to execute upon the market.

Ribbon is available as a venue.

Rate Limits

Desks cannot scale their rate limit capacity by using multiple Paradigm API Keys.

DRFQv2

RESToverHTTP requests are rate limited to 500 requests per second per desk across all API Keys. This applies to all types of requests and is not configurable per desk.

GRFQ

RESToverHTTP requests are rate limited to 500 requests per second per desk across all API Keys. This applies to all types of requests and is not configurable per desk.

FSPD

RESToverHTTP requests are rate limited per desk and type of request. [GET] requests are limited to 100 requests per second, while [POST] / [PATCH] / [DELETE] requests are limited to 10 requests per second. Paradigm is able to configure these limits upon request by the user.

Onboarding

Paradigm offers both test and production environments. We would love to create as many Paradigm test accounts as you would like.

Paradigm's servers are based in AWS eu-west-2. You should ensure Paradigm's IPs have been added to your Settlement Venue API Credentials' IP whitelist.

We would love to create as many test environment accounts as you need. Please reach out to your account management representative or our technical solutions team with the following information:

API Connection URLs

Here are the base connection URLs for Paradigm's API interfaces & product suffixes to be concentated for requests.

Base URL | Live Environment

Base URL | Test Environment

Product & Version

Test Environment Examples

Helpful Reminders

Settlement Venue Testnet URLs

High Level Implementation Notes

Your solution should

Your solution should not

Taker Limits & Maker Protections

Paradigm enforces a number of limitations to ensure markets operate fairly and discourage negative practices. These limitations to specific user actions are at the sole discretion of Paradigm with changes communicated as they occur.

Taker Execution Limits

Taker Execution Limits limit the number of times Takers are able to execute upon markets in a rolling time window. Presently, this is one execution within a 2-second rolling window per product.

This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.

Taker Market Creation Limits

Taker Market Creation Limits limit the number of RFQs and Order Book markets users are able to create. Presently, users are able to create one market every three seconds on a rolling basis per product.

This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.

Market Maker Protection (MMP)

Market Maker Protection (MMP) protects Makers from rapid executions of orders in the market.

MMP is triggered when as a Maker two of your resting orders are executed upon within a one second rolling window.

When triggered:

To remove this protection, users are able to immediately request the [PATCH] /v1/{product}/mmp/status/ endpoint. The protection is automatically removed within 10 seconds of triggered by Paradigm without any neccessary interaction by the user.

This feature is enabled for all Paradigm users and cannot be disabled. The conditions of MMP being triggered cannot be configured by the user.

This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.

Errors

All RESToverHTTP error responses follow the same basic format. An Error object is returned in response to an erroneous RESToverHTTP request, accompanied by an 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 occurred.
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.paradigm.trade/

Test Environment

Paradigm Admin Dashboard URL: https://admin.testnet.paradigm.trade/

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 an 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.prod.paradigm.trade/v2/drfq/?api-key=<access-key>

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

VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.prod.paradigm.trade/v1/vrfq/?api-key=<access-key>

FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.prod.paradigm.trade/v1/fs/?api-key=<access-key>

Test Environment | URL Examples

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v2/drfq/?api-key=<access-key>

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

VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/vrfq/?api-key=<access-key>

FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.testnet.paradigm.trade/v1/fs/?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 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.testnet.paradigm.trade'

# GET example
method = b'GET'
path = b'/v1/drfq/instruments/?venue=DBT&asset=BTC'
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.testnet.paradigm.trade'

# 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 both the role of 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 and must be specifed as false to disable.

In Unified Markets: * Cancel on Disconnect will cancel all OPEN created RFQ markets. * Cancel on Disconnect will cancel all OPEN created Orders in DRFQ, GRFQ, and VRFQ.

In FSPD: * Cancel on Disconnect will cancel all OPEN created Orders.

Cancel on Disconnect mode will cancel all created RFQs & Orders that have been requested with the same Paradigm API Key used to authenticate the WebSocket connection & will only trigger when all associated WebSocket connections disconnect.

Connection String Examples

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

DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v2/drfq/?api-key=<access-key>&cancel_on_disconnect=false

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

VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/vrfq/?api-key=<access-key>&cancel_on_disconnect=false

FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.testnet.paradigm.trade/v1/fs/?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"
    }
}

An 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 an 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 regarding RFQs, Quotes, Orders (GRFQ+FSPD) 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.

For VRFQ, there are three subscription channels you can subscribe to: rfq, quote, and trade.

For FSPD, there are six subscription channels you can subscribe to: strategy_state.{venue}.{kind}, order_book.{strategy_id}.{level}, orders.{venue}.{kind}.{strategy_id}, trades.{venue}.{kind}.{strategy_id}, trade_tape.{venue}.{kind}.{strategy_id}, and venue_bbo.{strategy_id}.

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").

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

DRFQv2 WebSocket Notification Channels

DRFQ JSON-RPCoverWebSocket notification channels are:

GRFQ WebSocket Notification Channels

GRFQ JSON-RPCoverWebSocket notification channels are:

VRFQ WebSocket Notification Channels

VRFQ JSON-RPCoverWebSocket notification channels are:

FSPD WebSocket Notification Channels

FSPD JSON-RPCoverWebSocket notification channels are:

Shared - REST Endpoints

The following REST Endpoints have no version or 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.testnet.paradigm.trade/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.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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", "https://api.testnet.paradigm.trade/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.

Shared - WebSocket Notification Channels

market_maker_protection

An example of MMP being triggered

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params": {
    "channel": "market_maker_protection",
    "data": {
      "kind": "TRIGGERED"
    }
}
}

An update is sent to the market_maker_protection WebSocket Notification Channel when MMP has been triggered. There is no message published when it has been reset by the user or the system.

You must subscribe to this channel using the Connection URL with the Version and Product URL suffix of the respective products below. For example: wss://ws.api.testnet.paradigm.trade/v1/grfq.

If MMP is triggered from the DRFQ product, you will be notified on the market_maker_protection channel even if you subscribed using the GRFQ Version and Product URL.

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
> kind string Y Status of MMP. Valid values include TRIGGERED.

DRFQv2 - API Workflows

In our test environment, Paradigm runs "Auto Market Makers". These desks, when included as counterparties in RFQs, will return + update prices and you are able to cross. This allows RFQ Creators to experience the end to end workflow.

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

DRFQv2: High Level

RFQ Creators are referred to as Taker's and receivers of RFQs are referred to as Maker's throughout the documentation.

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

At a high level, the DRFQv2 workflow is:

  1. Taker creates an RFQ and chooses which counterparties to send it too.
  2. Maker(s) submits an order to the RFQ.
  3. Taker receives the order(s).
  4. Taker submits an order with a crossing price and the trade is sent for clearing on the underlying settlement venue.
  5. Taker & Maker receive confirmation that the trade has been successfully cleared or rejected at clearing by the underlying settlement venue.

Notes:

Key DRFQv2 Concepts

In DRFQv2,

DRFQv2: Taker's Perspective

  1. Taker creates an RFQ using [POST] /rfqs. 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 [DELETE] /rfqs/{rfq_id}.
  3. Maker, who is a requested counterparty to the RFQ, and is notified over the rfqs JSON-RPCoverWebSockets Notification channel, is then able to submit an order to the RFQ.
  4. Taker, who will be notified of RFQ Orders on the rfq_orders JSON-RPCoverWebSockets Notification channel, is able to attempt to cross by submiting an order using [POST] /orders.
  5. Taker will receive updates about the state of their order via the orders JSON-RPCoverWebSockets Notification channel.
  6. Taker will receive clearing finality via the trades JSON-RPCoverWebSockets Notification channel where the result can either be success or rejection.

DRFQv2: Maker's Perspective

  1. Taker will create an RFQ and the Maker will be notified on the rfqs JSON-RPCoverWebSockets Notification channel.
  2. Maker is able to create an order using [POST] /orders.
  3. Maker is able to cancel an existing order with [DELETE] /orders or [DELETE] /orders/{order_id}.
  4. Taker submits a crossing Order that matches with the Maker's existing order.
  5. Maker will receive updates about the state of their order via the orders JSON-RPCoverWebSockets Notification channel.
  6. Maker will receive clearing finality via the trades JSON-RPCoverWebSockets Notification channel where the result can either be success or rejection.

DRFQv2: Maker managing Orders

DRFQv2: Taker managing an RFQ's Orders

As a Taker, the desk who has created the RFQ, you will receive Orders from the Makers associated with the RFQ.

This pattern describes how as a Taker to build/store/manage Orders from Makers in relation to your RFQ:

  1. Subscribe to the rfq_orders JSON-RPCoverWebSockets WebSockets Notifications channel. Store all of the received events.
  2. Request the [GET] /rfqs/{rfq_id}/orders endpoint for the specific RFQ to return all OPEN associated Orders.
  3. Apply the received events for the associated {rfq_id} to associated group of Orders from the previous step.
  4. From the rfq_orders JSON-RPCoverWebSockets WebSockets Notifications channel, when you receive an event == ADDED, add this order to your storage of RFQ Orders.
  5. From the rfq_orders JSON-RPCoverWebSockets WebSockets Notifications channel, when you receive an event == REMOVED, add this order to your storage of RFQ Orders.

Updates about an RFQ's Orders are communicated via the rfq_orders JSON-RPCoverWebSockets WebSockets Notifications channel. They are communicated in a manner most similar to that of an Order Book with a depth of L3. As such, you will find your system adding and removing specific associated orders. At the present moment, partial fills are not possible and your system will not receive any update messages.

DRFQv2: Consequences of a Trade Rejection

All trades on Paradigm are submitted as "Block Trades" to the underlying settlement venue. The two key characteristics of "Block Trades" are atomicity of clearing and either complete success or rejection at clearing. As such, when Paradigm submits a "Block Trade" to an underlying settlement venue, all legs must successfully clear or the entire "Block Trade" is rejected.

With this being said, when two orders cross on Paradigm, Paradigm submits a "Block Trade" to the underlying settlement venue for clearing. Two orders crossing in DRFQv2 will result in each Orders state == CLOSED and a Trade object with the state == PENDING_SETTLEMENT. If the trade successfully clears, both the Taker and the Maker will receive a Trade message with the state == FILLED, if not, state == REJECTED.

In the event of a successful trade, the positions will appear in your underlying settlement account. In the event of a rejected trade, the positions will NOT appear in your underlying settlement account.

DRFQv2: Enums & Explanations

There are six resources present through the DRFQv2 API. They are the Instrument, RFQ, Order, RFQ Orders, Trade, and Trade Tape resources.

Users are able to engage with Paradigm via the RESToverHTTP and JSON-RPCoverWebSockets interfaces.

Resources have a state attribute which denotes the status or availability of the object.

The JSON-RPCoverWebSockets interface publishes messages which include an event key to help communicate what update the message is referring too.

DRFQv2: Instrument

This information is available from the RESToverHTTP inferface, but not the JSON-RPCoverWebSockets interface.

Valid state values include ACTIVE, EXPIRED.

There are no valid event values as there is no corresponding WebSockets Notifications channel.

Instrument objects with the following state values, mean the following things to users:

The Instrument state enums can only transition from ACTIVE -> EXPIRED.

DRFQv2: RFQ

This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.

Valid state values include OPEN, CLOSED.

Valid event values include ADDED, REMOVED.

RFQ objects with the following state values, mean the following things to users:

Published via the rfqs JSON-RPCoverWebSockets notifications channel, event values mean the following to users:

DRFQv2: Order

This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.

Users are strongly encouraged to use the quantity, pending_fill_quantity, canceled_quantity, filled_quantity attributes of an Order to be certain of the value at risk.

Valid state values include PENDING, OPEN, CLOSED.

Valid event values include NEW, CANCELED, PENDING_FILL, FILLED.

Order objects with the following state values, mean the following things to users:

Published via the orders JSON-RPCoverWebSockets notifications channel, event values mean the following to users:

DRFQv2: RFQ Orders

This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.

There are no valid state values as the RFQ Orders resource solely communicates actionable Maker Orders to the Taker.

Valid event values include ADDED, REMOVED, UPDATED.

Published via the rfq_orders JSON-RPCoverWebSockets notifications channel, event values mean the following to users:

DRFQv2: Trade

This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.

Valid state values include PENDING_SETTLEMENT, FILLED, REJECTED.

Valid event values include PENDING_SETTLEMENT, FILLED, REJECTED.

Trade objects with the following state values, mean the following things to users:

Published via the trades JSON-RPCoverWebSockets notifications channel, event values mean the following to users:

DRFQv2: Trade Tape

This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.

Valid state values include FILLED.

Valid event values include FILLED.

Trade Tape objects with the following state values, mean the following things to users:

Published via the trade_tape JSON-RPCoverWebSockets notifications channel, event values mean the following to users:

DRFQv2: Differences to DRFQv1

DRFQv1 was released at the beginnning of 2021 when both Paradigm & crypto were in very different places to where they are today. DRFQv1 was built in response to direct user feedback and was an iteration upon our first product; "Chat". "Chat" required users to bilaterally negotiate with multiple counterparties the same structure for each trade. As such, DRFQv1 (or MDRFQ), was created to solve this user problem.

With time, DRFQv1 has becoming increasingly slow, but has also become increasingly challenging to extend & to deliver the functionality requested by users today. As such, DRFQv2 has been created to address the existing performance & feature challenges of DRFQv1, but to also enable rapid solutions to future user requests.

DRFQv2 includes many of the elements of other Paradigm products, such as FSPD & GRFQ, that users have expressed positive feedback about. The intentions of DRFQv2 are threefold:

  1. To remedy the decreasing performance of DRFQv1.
  2. To include product functionality missing, but frequently requested & required by users.
  3. To provide an experience more akin to that of FSPDs & GRFQ + crypto exchanges. The intention is to reduce the amount of integration work required for users stemming from critically different workflows and patterns between both Paradigm products as well as the broader space.

With that said, the DRFQv2 API workflow is incredibly similar to that of what users are used to interacting with in FSPDs & GRFQ and also crypto exchanges.

Some small notes:

DRFQv2: DRFQv1 Support

DRFQv1 will continue to be supported for an extended period of time. A deprecation timeline will be communicated and the result of feedback & consensus of users.

Existing users of DRFQv1 will be able to continue until such a time without any disruption or changes required to existing systems.

The core motivations for existing DRFQv1 users to integrate with DRFQv2 are:

If you have any questions, we strongly recommend you reach out to your account manager as we would greatly appreciate any feedback.

DRFQv2 - 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.

DRFQv2: JSON-RPCoverWebSockets

DRFQv2: Authentication + Heartbeat + Subscribe to Notification Channel

Authenticate, establish & maintain a heartbeat and subscribe rfqs JSON-RPCoverWebSockets Notification Channel.

DRFQv2: Auto Market Maker

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 Auto Market Makers are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2" on the Test environment.

To note, this is purely a QA tool and not in any way to be used as apart of a trading system.

You can download the Auto Market Maker from here.

DRFQv2: Auto Market Taker

The Auto Market Taker will create random RFQ structures and cross them. You will need to update the counterparties you wish to RFQ (ie your desk acting as a Maker).

To note, this is purely a QA tool and not in any way to be used as apart of a trading system.

You can download the Auto Market Taker from here.

DRFQv2 - WebSocket Notification Channels

DRFQv2: rfqs

An example, as the RFQ Creator, role == TAKER, when state == OPEN

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfqs",
      "data":{
         "account_name":"ParadigmTestNinetyFive",
         "base_currency":"BTC",
         "clearing_currency":"USD",
         "closed_reason":"None",
         "counterparties":[
            "DSK3",
            "DSK2"
         ],
         "created_at":1670473243746.937,
         "description":"Future  16 Dec 22",
         "expires_at":1670473543747.062,
         "id":"r_2IcG1WoqoCCtjA0C0EhJxotCSu2",
         "is_taker_anonymous":true,
         "kind":"FUTURE",
         "label":"None",
         "last_trade":"None",
         "last_updated_at":1670473243747.062,
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "quantity":"200000",
         "quote_currency":"USD",
         "role":"TAKER",
         "side_layering_limit":1,
         "state":"OPEN",
         "strategy_code": "FT",
         "strategy_description":"CF_BTC-16DEC22",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"DSK95",
         "venue":"DBT"
      },
      "event":"ADDED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, as the RFQ Creator, role == TAKER, when state == CLOSED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfqs",
      "data":{
         "account_name":"ParadigmTestNinetyFive",
         "base_currency":"BTC",
         "clearing_currency":"USD",
         "closed_reason":"CANCELED_BY_CREATOR",
         "counterparties":[
            "DSK3",
            "DSK2"
         ],
         "created_at":1670473243746.937,
         "description":"Future  16 Dec 22",
         "expires_at":1670473581046.396,
         "id":"r_2IcG1WoqoCCtjA0C0EhJxotCSu2",
         "is_taker_anonymous":true,
         "kind":"FUTURE",
         "label":"None",
         "last_trade":"None",
         "last_updated_at":1670473281046.396,
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "quantity":"200000",
         "quote_currency":"USD",
         "role":"TAKER",
         "side_layering_limit":1,
         "state":"CLOSED",
         "strategy_code":"FT",
         "strategy_description":"CF_BTC-16DEC22",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"DSK95",
         "venue":"DBT"
      },
      "event":"REMOVED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, as an RFQ receiver, role == MAKER, when state == OPEN

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfqs",
      "data":{
         "account_name":null,
         "base_currency":"BTC",
         "clearing_currency":"USD",
         "closed_reason":"None",
         "counterparties": [],
         "created_at":1670473348810.261,
         "description":"Future  16 Dec 22",
         "expires_at":1670473648810.403,
         "id":"r_2IcGEiv9eQEA1CU4H1hfe9ZogAJ",
         "is_taker_anonymous":true,
         "kind":"FUTURE",
         "label":"None",
         "last_trade":"None",
         "last_updated_at":1670473348810.403,
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "quantity":"200000",
         "quote_currency":"USD",
         "role":"MAKER",
         "side_layering_limit":1,
         "state":"OPEN",
         "strategy_code":"FT",
         "strategy_description":"CF_BTC-16DEC22",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"None",
         "venue":"DBT"
      },
      "event":"ADDED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, as an RFQ receiver, role == MAKER, when state == CLOSED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfqs",
      "data":{
         "account_name":null,
         "base_currency":"BTC",
         "clearing_currency":"USD",
         "closed_reason":"CANCELED_BY_CREATOR",
         "counterparties": [],
         "created_at":1670473348810.261,
         "description":"Future  16 Dec 22",
         "expires_at":1670473663770.951,
         "id":"r_2IcGEiv9eQEA1CU4H1hfe9ZogAJ",
         "is_taker_anonymous":true,
         "kind":"FUTURE",
         "label":"None",
         "last_trade":"None",
         "last_updated_at":1670473363770.951,
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "CF"
         ],
         "quantity":"200000",
         "quote_currency":"USD",
         "role":"MAKER",
         "side_layering_limit":1,
         "state":"CLOSED",
         "strategy_code":"FT",
         "strategy_description":"CF_BTC-16DEC22",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"None",
         "venue":"DBT"
      },
      "event":"REMOVED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All updates relating to RFQs are sent through the rfqs WebSocket Notification channel.

This is a private channel and consumable by only those aparty to the RFQ. Those counterparties include the RFQ's creator as well as the specified counterparties to the RFQ.

Updates received through the rfqs WebSocket Notification channel can include RFQs being created, canceled, expired, filled and traded away.

The availability of an RFQ to be actioned by any user is denoted by the state key of the object. When an RFQ has a state == OPEN, it is actionable by both the RFQ creator and those specified as counterparties. When an RFQ has a state == CLOSED it is no longer actionable by either the RFQ creator or the specified counterparties.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include rfqs.
> event string true The change associated with the message. Valid values include ADDED, REMOVED.
> data object true An object containing the update’s information.
>> id string true The Paradigm created unique identifier of the RFQ.
>> account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER.
>> created_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was created.
>> expires_at decimal true The time in UNIX milliseconds since the epoch when the RFQ expires.
>> last_updated_at integer true The time in UNIX milliseconds since the epoch when the RFQ was last updated.
>> strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.
>> strategy_description string true The standardized description of the RFQ’s composite Instruments.
>> description string true The verbose description of the RFQ’s composite Instruments.
>> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
>> kind string true The composite Instrument kinds of the RFQ. Valid values include FUTURE, OPTION, OPTION_FUTURE.
>> base_currency string true The currency the RFQ is exposed to. Valid values include BTC, ETH, SOL.
>> quote_currency string true The currency of the price of the RFQ. Valid values include BTC, ETH, SOL, USD, USDC.
>> clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
>> counterparties Array of strings true The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER.
>> role string true The role of the user to the RFQ. Valid values include TAKER, MAKER.
>> group_signature string true A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such.
>> taker_desk_name string true The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True.
>> legs Array of Objects true The composite Instrument legs of the RFQ.
>>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>>> instrument_name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
>>> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
>>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places.
>>> side string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.
>>> quantity string true The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument.
>>> price string false The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE.
>> product_codes Array of strings true The Paradigm created Product Codes of the composite Instruments to the RFQ.
>> quantity string true The total size of the composite Instrument legs, denominated in the clearing_currency.
>> is_taker_anonymous boolean true If the Taker Desk Name is to be revealed to the counterparties to the RFQ.
>> label string true RFQ creator label of the RFQ.
>> side_layering_limit integer true The maximum number of Orders a Maker is able to have either side of an RFQ.
>> state string true The availability of the RFQ to trade. Valid values include OPEN, CLOSED.
>> closed_reason string true The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR, EXPIRED, EXECUTION_LIMIT. null if the RFQ’s state == OPEN.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

DRFQv2: rfq_orders

An example, as the RFQ Creator, RFQ role == TAKER, when event == ADDED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq_orders",
      "data":{
         "id":"o_2IcGsBLQIwl09jdflpb1iRnUT9B",
         "price":"16795",
         "quantity":"200000",
         "desk":"DSK94",
         "rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
         "side":"SELL"
      },
      "event":"ADDED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, as the RFQ Creator, RFQ role == TAKER, when event == REMOVED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"rfq_orders",
      "data":{
         "id":"o_2IcGsBLQIwl09jdflpb1iRnUT9B",
         "price":"16795",
         "quantity":"200000",
         "desk":"DSK94",
         "rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
         "side":"SELL"
      },
      "event":"REMOVED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All updates relating to an RFQ's Orders are sent through the rfq_orders WebSocket Notifications channel.

This is a private channel and only available to the creator of the RFQ who has the role == TAKER in the RFQ.

Updates received through the rfq_orders WebSocket Notification channel represent events relating to specific related orders. In terms of thinking, it's extremely similar to processing event updates to that of an Order Book with an L3 depth.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include rfq_orders.
> event string true The change associated with the message. Valid values include ADDED, REMOVED, UPDATED.
> data object true An object containing the update’s information.
>> rfq_id string true The Paradigm created unique identifier of the RFQ.
>> side string true The side of the RFQ. Valid values include BUY, SELL.
>> price string true The price of the Order, denominated in the quote_currency of the RFQ.
>> quantity string true The size of the Order, denominated in the clearing_currency of the RFQ.
>> desk string true The Paradigm Desk Name of the counterparty who created the Order.
>> id string true The Paradigm created unique identifier of the Order.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

DRFQv2: orders

An example, when Order has a state == OPEN

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"orders",
      "data":{
         "account_name":"ParadigmTestNinetyFour",
         "canceled_quantity":"0",
         "created_at":1670539033867.91,
         "filled_quantity":"0",
         "id":"o_2IePNBE9NPXk0xJnPmUNZSrri2G",
         "label":"just for me",
         "last_updated_at":1670539033868.4849,
         "pending_fill_quantity":"0",
         "price":"16800",
         "quantity":"200000",
         "rfq_id":"r_2IePMAohwEdvzcTT2SchQWSC7Wf",
         "role":"MAKER",
         "side":"SELL",
         "state":"OPEN",
         "time_in_force":"GOOD_TILL_CANCELED",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
            {
               "instrument_id": 12312312312,
               "price": "16800"
            }
         ]
      },
      "event":"NEW",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, when Order has a state == CLOSED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"orders",
      "data":{
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"0",
         "created_at":1670473741899.189,
         "filled_quantity":"0",
         "id":"o_2IcH26wODa1OAPgyCnwcFrJ6EGK",
         "label":"just for me",
         "last_updated_at":1670473741966.041,
         "pending_fill_quantity":"200000",
         "price":"16795",
         "quantity":"200000",
         "rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": []
      },
      "event":"PENDING_FILL",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All updates relating to a desks' Orders are sent through the orders WebSocket Notifications channel.

This is a private channel and provides updates solely about the desks' Orders.

When the RFQ creator, role == TAKER, submits an order, the first published orders WebSocket Notification channel message will always indicate state == CLOSED due to the Order either successfully crossing or being canceled due it's time_in_force attribute being FILL_OR_KILL.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include orders.
> event string true The change associated with the message. Valid values include NEW, CANCELED, PENDING_FILL, FILLED.
> data object true An object containing the update’s information.
>> id string true The Paradigm created unique identifier of the Order.
>> rfq_id string true The Paradigm created unique identifier of the associated RFQ.
>> state string true The availability of the Order for the user to action. Valid values include OPEN, CLOSED.
>> side string true The direction of the Order. Valid values include BUY, SELL.
>> type string true The type of Order. Valid values include LIMIT.
>> time_in_force string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
>> created_at decimal true The time in UNIX milliseconds since the epoch when the Order was created.
>> last_updated_at decimal true The time in UNIX milliseconds since the epoch when the Order was last updated.
>> venue string true The underlying settlement venue associated with the Order & RFQ. Valid values include DBT, BIT, BYB.
>> quantity string true The size of the Order, denominated in the clearing_currency of the RFQ.
>> legs Array of Objects false The composite Instrument legs of the Order.
>> price string true The price of the Order, denominated in the quote_currency of the RFQ.
>> label string true The user created label for the order.
>> pending_fill_quantity string true The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
>> filled_quantity string true The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
>> canceled_quantity string true The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ.
>> account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
>> role string true The role of the user in the RFQ. Valid values include TAKER, MAKER.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

DRFQv2: trades

An example, when a trade has a state == PENDING_SETTLEMENT

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trades",
      "data":{
         "id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
         "exec_id":"None",
         "order_id":"o_2IeNvhjR6zW0iCrkh6Q3T5lOyTn",
         "rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
         "venue":"DBT",
         "kind":"FUTURE",
         "state":"PENDING_SETTLEMENT",
         "role":"TAKER",
         "executed_at":1670538321612.0579,
         "filled_at":"None",
         "side":"BUY",
         "price":"17204",
         "quantity":"200000",
         "filled_quantity":"0",
         "rejected_quantity":"0",
         "rejected_party":"None",
         "rejected_reason":"None",
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "price":"17204",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"None",
               "fee_quantity":"None",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"CF_BTC-16DEC22",
         "description":"Future  16 Dec 22",
         "quote_currency":"USD",
         "mark_price":"17203.49"
      },
      "event":"PENDING_SETTLEMENT",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, when a trade has a state == FILLED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trades",
      "data":{
         "id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
         "exec_id":"366192",
         "order_id":"o_2IeNvhjR6zW0iCrkh6Q3T5lOyTn",
         "rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
         "venue":"DBT",
         "kind":"FUTURE",
         "state":"FILLED",
         "role":"TAKER",
         "executed_at":1670538321612.0579,
         "filled_at":1670538322000.0,
         "side":"BUY",
         "price":"17204",
         "quantity":"200000",
         "filled_quantity":"200000",
         "rejected_quantity":"0",
         "rejected_party":"None",
         "rejected_reason":"None",
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "price":"17204",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141327736",
               "fee_quantity":"0.0116252",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"CF_BTC-16DEC22",
         "description":"Future  16 Dec 22",
         "quote_currency":"USD",
         "mark_price":"17203.49"
      },
      "event":"FILLED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example, when a trade has a state == REJECTED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trades",
      "data":{
         "id":"bt_2IeOL5d0Bvh32XgJQMFSu7XMyPc",
         "exec_id":"None",
         "order_id":"o_2IeOL5cYl8HoJHBIAlb1mLWbo13",
         "rfq_id":"r_2IeOIha69NSwfkGG1qjJd7U3jEF",
         "venue":"DBT",
         "kind":"FUTURE",
         "state":"REJECTED",
         "role":"TAKER",
         "executed_at":1670538523874.681,
         "filled_at":"None",
         "side":"BUY",
         "price":"16800",
         "quantity":"200000",
         "filled_quantity":"0",
         "rejected_quantity":"200000",
         "rejected_party":"None",
         "rejected_reason":"Deribit error: Price for trade is lower than min sell price. Your Ask for Future 16 Dec 22 was CANCELED",
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "price":"16800",
               "product_code":"CF",
               "quantity":"200000",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"None",
               "fee_quantity":"None",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"CF_BTC-16DEC22",
         "description":"Future  16 Dec 22",
         "quote_currency":"USD",
         "mark_price":"17189.22"
      },
      "event":"REJECTED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All updates relating to a desks' Trades are sent through the trades WebSocket Notifications channel.

This is a private channel and provides updates solely about the desks' Trades.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include trades.
> event string true The change associated with the message. Valid values include PENDING_SETTLEMENT, FILLED, REJECTED.
> data object true An object containing the update’s information.
>> id string true The Paradigm created unique identifier of the Trade.
>> exec_id string true The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue.
>> order_id string true The Paradigm created unique Order identifier associated with the Trade.
>> rfq_id string true The Paradigm created unique identifier of the RFQ.
>> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
>> kind string true The nature of the strategy traded. Valid values include OPTION, FUTURE, OPTION_FUTURE.
>> state string true The indication if the trade has reached settlement finality. Valid values include PENDING_SETTTLEMENT, FILLED, REJECTED
>> role string true The role of the user in the Trade. Valid values include TAKER, MAKER.
>> executed_at decimal true The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm.
>> filled_at decimal true The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle.
>> side string true The direction of the user in the trade. Valid values include BUY , SELL.
>> price string true The strategy price of the trade, denominated the quote_currency of the RFQ.
>> quantity string true The amount of the trade, denominated in the clearing_currency of the RFQ.
>> filled_quantity string true The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ.
>> rejected_quantity string true The rejected amount of the trade, denominated in the clearing_currency of the RFQ.
>> rejected_party string true The counterparty responsible for the Trade Rejection. Valid values include USER, COUNTERPARTY. null If Trade successfully settled.
>> rejected_reason string true The reason for the Trade Rejection. null if Trade successfully settled.
>> legs Array of Objects true The composite Instrument legs of the Trade.
>>> intrument_id integer true The Paradigm created unique identifier of the Instrument.,
>>> instrument_name string true The Paradigm normalized name of the Instrument used across Paradigm’s API.
>>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ.
>>> side string true The direction of the composite Instrument to the Trade. Valid values include BUY, SELL.
>>> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
>>> quantity string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
>>> venue_trade_id string true The corresponding unique trade identifier present on the underlying settlement venue.
>>> fee_quantity string true The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency.
>>> fee_currency string true The currency the fee_amount is denominated in.
>> strategy_description string true The standardized description of the Trade’s composite Instruments.
>> description string true The verbose description of the Trade’s composite Instruments.
>> quote_currency string true The currency in the price is denominated in, denominated in the quote_currency of the RFQ.
>> mark_price string true The strategy mark price from the underlying settlement venue of the composite Instruments to the trade.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

DRFQv2: trade_tape

An example, when a trade has the state == FILLED

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "channel":"trade_tape",
      "data":{
         "id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
         "rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
         "venue":"DBT",
         "kind":"FUTURE",
         "state":"FILLED",
         "executed_at":1670538321612.0579,
         "filled_at":1670538322000.0,
         "side":"SELL",
         "price":"17204",
         "quantity":"200000",
         "legs":[
            {
               "instrument_id":184255,
               "instrument_name":"BTC-16DEC22",
               "ratio":"1",
               "side":"BUY",
               "price":"17204",
               "product_code":"CF",
               "quantity":"200000"
            }
         ],
         "strategy_description":"CF_BTC-16DEC22",
         "description":"Future  16 Dec 22",
         "quote_currency":"USD",
         "mark_price":"17203.49"
      },
      "event":"FILLED",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All successfully cleared Trades on Paradigm are sent through the trade_tape WebSocket Notifications channel.

This is a public channel and consumable by all.

As such, no identifiable information is apart of any messages and only successfully cleared trades upon the underlying settlement venue are published.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include trade_tape.
> event string true The change associated with the message. Valid values include FILLED.
> data object true An object containing the update’s information.
>> id string true The Paradigm created unique identifier of the Trade.
>> rfq_id string true The Paradigm created unique identifier of the RFQ.
>> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
>> kind string true The nature of the strategy traded. Valid values include OPTION, FUTURE, OPTION_FUTURE.
>> state string true The indication if the trade has reached settlement finality. Valid values include FILLED.
>> executed_at decimal true The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm.
>> filled_at decimal true The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm.
>> side string true The direction of the user in the trade. Valid values include BUY , SELL.
>> price string true The strategy price of the trade, denominated the quote_currency of the RFQ.
>> quantity string true The amount of the trade, denominated in the clearing_currency of the RFQ.
>> legs string true The composite Instrument legs of the Trade.
>>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>>> instrument_name string true The composite Instrument legs of the Trade.
>>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ.
>>> side string true The direction of the composite Instrument to the Trade. Valid values include BUY, SELL.
>>> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
>>> quantity string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
>> strategy_description string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
>> description string true The verbose description of the Trade’s composite Instruments.
>> quote_currency string true The verbose description of the Trade’s composite Instruments.
>> mark_price string true The strategy mark price from the underlying settlement venue of the composite Instruments to the trade.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

DRFQv2: bbo.{rfq_id}

An example, of an update message

{
   "jsonrpc":"2.0",
   "method":"subscription",
   "params":{
      "data":{
         "rfq_id":"r_2LA8TjDOjWAHtRJ7CeLWzQXf4Ah",
         "min_price":"23658.58",
         "max_price":"24379.14",
         "mark_price":"24019.18",
         "best_bid_price":"24017.50",
         "best_ask_price":"24018.00",
         "best_bid_amount":"342090.0",
         "best_ask_amount":"42500.0",
         "created_at":1675302554270,
         "legs":[
            {
               "best_bid_price":"24017.50",
               "best_ask_price":"24018.00",
               "best_bid_amount":"342090.0",
               "best_ask_amount":"42500.0",
               "instrument_id":26707,
               "instrument_name":"BTC-PERPETUAL",
               "mark_price":"24019.18"
            }
         ]
      },
      "channel":"bbo",
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

All updates relating to an RFQ's composite instrument & structure market data are sent via the bbo.{rfq_id} WebSocket Notification Channel.

This is a public channel and consumable by all.

This channel publishes real-time updates of the underlying market data from the composite instruments' settlement venue.

Parameters

Member Type Required Enums Description
rfq_id string true rfq_id The Paradigm created rfq_id of the RFQ which has a state == OPEN.

Response Schema

Member Type Required Description
jsonrpc string true Always 2.0.
method string true The value will always be subscription to indicate message type.
params object true
> channel string true The Websocket channel the message was delivered upon. Valid values include bbo.{rfq_id}.
> event string true The change associated with the message. Valid values include NEW.
> data object true An object containing the update’s information.
>> id string true The Paradigm created unique identifier of the RFQ.
>> min_price string true The minimum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ.
>> max_price string true The maximum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ.
>> mark_price string true The strategy mark price of the RFQ’s composite Instruments from the underlying settlement venue. Denominated in the quote_currency of the RFQ.
>> best_bid_price string true The RFQ’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
>> best_ask_price string true The RFQ’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
>> best_bid_amount string true The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
>> best_ask_amount string true The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
>> created_at decimal true The time in UNIX milliseconds since the epoch when the message was created by Paradigm.
>> legs Array of Objects true The composite Instruments of the RFQ.
>>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>>> instrument_name string true The Paradigm normalized name of the Instrument.
>>> mark_price string true The Instrument’s mark price from the underlying settlement venue, denominated in the quote_currency of the RFQ.
>>> best_bid_price string true The Instrument’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
>>> best_ask_price string true The Instrument’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
>>> best_bid_amount string true The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
>>> best_ask_amount string true The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group.

Message Structure with Sequence Numbers

WebSocket messages now include an additional meta field that contains the following properties:

Member Type Description
seq_group number Unique identifier for the group of messages
seq_num number Sequence number of the message within the group

Here's an example of a WebSocket message with sequence numbers:

{
  "jsonrpc": "2.0",
  "method": "subscription",
  "params": {
    "channel": "rfq",
    "data": {
    },
    "meta": {
      "seq_group": 1692463499,
      "seq_num": 1027
    }
  }
}

Handling Sequence Numbers

Clients should monitor the sequence numbers of the incoming messages to ensure they have not missed any messages. If a client detects a gap in the sequence numbers, it may have missed one or more messages and should take appropriate action, such as refreshing data from REST.

Sequences increase monotonically within the context of a sequence group. Sequences are only relevant within a sequence group, which represents a subscribed channel. Sequences may be re-used between sequence groups.

While messages are sent ordered according to their sequences, sequences are not guaranteed not to repeat.

DRFQv2 - REST Endpoints

DRFQv2: [GET] /instruments

/instruments Request example

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


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

fetch('https://api.testnet.paradigm.trade/v2/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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/instruments
method = 'GET'
path = '/v2/drfq/instruments?venue=DBT&kind=FUTURE&base_currency=BTC'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/instruments", data)
    req.Header = headers

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

A [GET] /instruments request returns all instruments that are or were tradeable on Paradigm.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
state query string false The present availability of the Instrument. Valid values include ACTIVE, EXPIRED.
venue query string false The underlying settlement venue to return Instruments for. Valid values include DBT, BIT, BYB.
kind query string false The type of contract. Valid values include FUTURE, OPTION.
base_currency query string false The currency the Instrument is exposed to. Valid values include BTC, ETH, SOL, BCH.
venue_instrument_name query string false The name of the Instrument on the underlying settlement venue.
margin_kind query string false The nature of how the contract is margined. Valid values include LINEAR, INVERSE.
include_greeks query string false To include greeks if available for the Instrument from the underlying settlement venue. Valid values include True and False.

/instruments Response example

{
  "count":2424,
  "next":"cD0xODUyNzc=",
  "results":[
    {
      "id": 3614,
      "name": "ETH-7APR23",
      "created_at": 1679644802000,
      "expires_at": 1680854400000,
      "kind": "FUTURE",
      "venue": "DBT",
      "option_kind": null,
      "strike": null,
      "margin_kind": "INVERSE",
      "base_currency": "ETH",
      "quote_currency": "USD",
      "clearing_currency": "USD",
      "settlement_currency": "ETH",
      "mark_price": "1714.76",
      "min_block_size": "100000",
      "min_order_size_increment": "1",
      "min_tick_size": "0.01",
      "product_code": "AZ",
      "venue_instrument_name": "ETH-7APR23",
      "state": "ACTIVE",
      "greeks": null
    },
    {
      "id": 3613,
      "name": "BTC-7APR23",
      "created_at": 1679644802000,
      "expires_at": 1680854400000,
      "kind": "FUTURE",
      "venue": "DBT",
      "option_kind": null,
      "strike": null,
      "margin_kind": "INVERSE",
      "base_currency": "BTC",
      "quote_currency": "USD",
      "clearing_currency": "USD",
      "settlement_currency": "BTC",
      "mark_price": "27091.94",
      "min_block_size": "200000",
      "min_order_size_increment": "10",
      "min_tick_size": "0.01",
      "product_code": "CF",
      "venue_instrument_name": "BTC-7APR23",
      "state": "ACTIVE",
      "greeks": null
    },
    {
      "id": 3358,
      "name": "ETH-29DEC23-9000-P",
      "created_at": 1679101560000,
      "expires_at": 1703836800000,
      "kind": "OPTION",
      "venue": "DBT",
      "option_kind": "PUT",
      "strike": "9000",
      "margin_kind": "INVERSE",
      "base_currency": "ETH",
      "quote_currency": "ETH",
      "clearing_currency": "ETH",
      "settlement_currency": "ETH",
      "mark_price": "4.1669",
      "min_block_size": "250",
      "min_order_size_increment": "1",
      "min_tick_size": "0.0001",
      "product_code": "EH",
      "venue_instrument_name": "ETH-29DEC23-9000-P",
      "state": "ACTIVE",
      "greeks": {
        "delta": "-0.99534",
        "gamma": "1e-05",
        "mark_price": "4.1669",
        "theta": "-0.02436",
        "vega": "0.206",
        "last_updated_at": 1679944965844
      }
    },
    {
      "id": 3357,
      "name": "ETH-29DEC23-9000-C",
      "created_at": 1679101560000,
      "expires_at": 1703836800000,
      "kind": "OPTION",
      "venue": "DBT",
      "option_kind": "CALL",
      "strike": "9000",
      "margin_kind": "INVERSE",
      "base_currency": "ETH",
      "quote_currency": "ETH",
      "clearing_currency": "ETH",
      "settlement_currency": "ETH",
      "mark_price": "0.0007",
      "min_block_size": "250",
      "min_order_size_increment": "1",
      "min_tick_size": "0.0001",
      "product_code": "EH",
      "venue_instrument_name": "ETH-29DEC23-9000-C",
      "state": "ACTIVE",
      "greeks": {
        "delta": "0.00466",
        "gamma": "1e-05",
        "mark_price": "0.0007",
        "theta": "-0.02436",
        "vega": "0.20599",
        "last_updated_at": 1679944965848
      }
    }
  ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Instruments.
> id integer true The Paradigm created unique identifier of the Instrument.
> name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
> created_at decimal true The time in UNIX milliseconds since the epoch when the Instrument was created on the underlying settlement venue.
> expires_at decimal true The time in UNIX nanoseconds since the epoch when the Instrument settles or is expired on the underlying settlement venue.
> kind string true The type of contract. Valid values include OPTION, FUTURE.
> venue string true The underlying settlement venue of the Instrument. Valid values include DBT, BIT, BYB.
> option_kind string true The kind of Option contract. Valid values include CALL and PUT. null if kind ≠ OPTION.
> strike string true The strike of the Option contract. null if kind ≠ OPTION.
> margin_kind string true The nature of how the contract is margined. Valid values include LINEAR, INVERSE.
> base_currency string true The currency the Instrument is exposed to. Valid values include BTC, ETH, SOL.
> quote_currency string true The currency of the price of the Instrument. Valid values include BTC, ETH, SOL, USD, USDC.
> clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
> settlement_currency string true The currency the Instrument is settled in on the underlying settlement venue. Valid values include BTC, ETH, SOL, USD, USDC.
> min_tick_size string true The minimum price increment step the Instrument can be traded in, denominated in the quote_currency.
> min_order_size_increment string true The minimum order increment size/quantity can be traded in, denominated in the clearing_currency.
> min_block_size string true The minimum order size/quantity the Instrument can be traded in, denominated in the clearing_currency.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> venue_instrument_name string true The name of the Instrument on the underlying settlement venue.
> state string true The availability of the Instrument to be used in RFQs. Valid values include ACTIVE, EXPIRED.
> mark_price string true The “Mark Price” from the underlying settlement venue at the time when the data was pulled.
> greeks string true An array of variables used to assess the risk & exposure of a derivatives contract.
>> last_updated_at decimal true The time in UNIX milliseconds since the epoch when the information was last updated.
>> delta string false The delta value of the Instrument.
>> theta string false The theta value of the Instrument.
>> vega string false The vega value of the Instrument.
>> gamma string false The gamma value of the Instrument.
>> mark_price string false The “Mark Price” from the underlying settlement venue at the time when the greeks were pulled. Deprecated: please use the top level mark_price

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3005 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [GET] /instruments/{instrument_id}

/instruments/{instrument_id} Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/instruments/123 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/instruments/123',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/instruments/{instrument_id}
method = 'GET'
path = '/v2/drfq/instruments/123'

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)
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", "https://api.testnet.paradigm.trade/isntruments/123", data)
    req.Header = headers

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

A [GET] /instruments/{instrument_id} request returns the specific instrument requested in the endpoint.

Parameters

Name In Type Required Description
instrument_id endpoint string true The Paradigm created unique instrument identifier.

/instruments/{instrument_id} Response example

200 Response

{
  "id": 123,
  "name": "ETH-29DEC23-9000-C",
  "created_at": 1679101560000,
  "expires_at": 1703836800000,
  "kind": "OPTION",
  "venue": "DBT",
  "option_kind": "CALL",
  "strike": "9000",
  "margin_kind": "INVERSE",
  "base_currency": "ETH",
  "quote_currency": "ETH",
  "clearing_currency": "ETH",
  "settlement_currency": "ETH",
  "mark_price": "0.0007",
  "min_block_size": "250",
  "min_order_size_increment": "1",
  "min_tick_size": "0.0001",
  "product_code": "EH",
  "venue_instrument_name": "ETH-29DEC23-9000-C",
  "state": "ACTIVE",
  "greeks": {
    "delta": "0.00466",
    "gamma": "1e-05",
    "mark_price": "0.0007",
    "theta": "-0.02436",
    "vega": "0.20599",
    "last_updated_at": 1679944965848
  }
}

Response Schema

Status Code: 200

Name Type Required Description
id integer true The Paradigm created unique identifier of the Instrument.
name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
created_at decimal true The time in UNIX milliseconds since the epoch when the Instrument was created on the underlying settlement venue.
expires_at decimal true The time in UNIX milliseconds since the epoch when the Instrument settles or is expired on the underlying settlement venue.
kind string true The type of contract. Valid values include OPTION, FUTURE.
venue string true The underlying settlement venue of the Instrument. Valid values include DBT, BIT, BYB.
option_kind string true The kind of Option contract. Valid values include CALL and PUT. null if kindOPTION.
strike string true The strike of the Option contract. null if kind ≠ OPTION.
margin_kind string true The nature of how the contract is margined. Valid values include LINEAR, INVERSE.
base_currency string true The currency the Instrument is exposed to. Valid values include BTC, ETH, SOL.
quote_currency string true The currency of the price of the Instrument. Valid values include BTC, ETH, SOL, USD, USDC.
clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
settlement_currency string true The currency the Instrument is settled in on the underlying settlement venue. Valid values include BTC, ETH, SOL, USD, USDC.
min_tick_size string true The minimum price increment step the Instrument can be traded in, denominated in the quote_currency.
min_order_size_increment string true The minimum order increment size/quantity can be traded in, denominated in the clearing_currency.
min_block_size string true The minimum order size/quantity the Instrument can be traded in, denominated in the clearing_currency.
product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
venue_instrument_name string true The name of the Instrument on the underlying settlement venue.
state string true The availability of the Instrument to be used in RFQs. Valid values include ACTIVE, EXPIRED.
mark_price string true The “Mark Price” from the underlying settlement venue at the time when the data was pulled.
greeks string true An array of variables used to assess the risk & exposure of a derivatives contract.
> last_updated_at decimal false The time in UNIX milliseconds since the epoch when the information was last updated.
> delta string false The delta value of the Instrument.
> theta string false The theta value of the Instrument.
> vega string false The vega value of the Instrument.
> gamma string false The gamma value of the Instrument.
> mark_price string false The “Mark Price” from the underlying settlement venue at the time when the greeks were pulled. Deprecated: please use the top level mark_price

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
404 3100 "Unavailable instrument" Unavailable/invalid instrument id provided in request.

DRFQv2: [GET] /counterparties

/counterparties Request example

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


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

fetch('https://api.testnet.paradigm.trade/v2/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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/counterparties
method = 'GET'
path = '/v2/drfq/counterparties?group=LP'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/counterparties", data)
    req.Header = headers

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

A [GET] /counterparties request returns all counterparties the desk is able add as counterparty to an RFQ.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
group query string false The Paradigm created list of the counterparties to return. Valid values include LP.
venues query string false The venues to return counterparties for. You can include multiple venues in a single request by ?venues=DBT,BYB.

/counterparties Response example

{
   "count":548,
   "next":"cD0xMjM0",
   "results":[
      {
         "desk_name":"05J2",
         "firm_name":"062020",
         "groups":[

         ],
         "venues":[
            "DBT"
         ]
      },
      {
         "desk_name":"05J3",
         "firm_name":"062020",
         "groups":[

         ],
         "venues":[
            "DBT"
         ]
      },
      {
         "desk_name":"0729",
         "firm_name":"ParadigmShift",
         "groups":[

         ],
         "venues":[
            "DBT"
         ]
      },
      {
         "desk_name":"0817",
         "firm_name":"ParadigmShift",
         "groups":[

         ],
         "venues":[
            "DBT"
         ]
      },
      {
         "desk_name":"1234",
         "firm_name":"ParadigmShift",
         "groups":[

         ],
         "venues":[
            "DBT"
         ]
      }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Counterparties.
> firm_name string true The Paradigm created name of the firm of the counterparty.
> desk_name string true The Paradigm created name of the desk of the counterparty.
> venues Array of strings true The venues the counterparty participates in and you can send RFQs to on Paradigm.
> groups Array of strings true The groups the counterparty is a part of. Currently, the only supported group are Liquidity Providers (LP).

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3005 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [GET] /rfqs

/rfqs Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/rfqs
method = 'GET'
path = '/v2/drfq/rfqs?venue=DBT&state=OPEN'

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)
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", "https://api.testnet.paradigm.trade/v1/drfq/instruments/", data)
    req.Header = headers

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

A [GET] /rfqs request returns all RFQs that are or were actionable.

The RFQ creator, denoted by role == TAKER, is able to cancel the RFQ if state == OPEN.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
role query string false The role of the desk in the created RFQ. Valid values include TAKER, MAKER.
state query string false The availability of the RFQ. Valid values include OPEN, CLOSED.
venue query string false The underlying settlement venue to return Instruments for. Valid values include DBT, BIT, BYB.
base_currency query string false The currency the Instrument is exposed to. Valid values include BTC, ETH, SOL.
product_codes query string false The Paradigm created Product Codes of the composite Instruments. The request can contain multiple codes such as ?product_codes=DO,CF.

/rfqs Response example

{
   "count":12239,
   "next":"cD0yMDIyLTEyLTA4KzAwJTNBNTglM0EwMC40NDE1MDclMkIwMCUzQTAw",
   "results":[
      {
         "account_name":"ParadigmTestNinetyFive",
         "base_currency":"BTC",
         "clearing_currency":"BTC",
         "closed_reason":"EXPIRED",
         "counterparties":[
            "DSK94",
            "AAT42",
            "AAT43",
            "AAT44"
         ],
         "created_at":1670461091765.508,
         "description":"Call  31 Mar 23  24000",
         "expires_at":1670461696044.232,
         "id":"r_2IbrOQ3zGMVrOb7RLRKAizy3lgK",
         "is_taker_anonymous":true,
         "kind":"OPTION",
         "label":null,
         "last_trade":null,
         "last_updated_at":1670461396044.232,
         "legs":[
            {
               "instrument_id":154406,
               "instrument_name":"BTC-31MAR23-24000-C",
               "product_code":"DO",
               "quantity":"25.0000",
               "ratio":"1",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "quantity":"25.0000",
         "quote_currency":"BTC",
         "role":"TAKER",
         "side_layering_limit":1,
         "state":"CLOSED",
         "strategy_code":"CL",
         "strategy_description":"DO_BTC-31MAR23-24000-C",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"DSK95",
         "venue":"DBT"
      },
      {
         "account_name":"ParadigmTestNinetyFive",
         "base_currency":"BTC",
         "clearing_currency":"BTC",
         "closed_reason":"EXPIRED",
         "counterparties":[
            "DSK94",
            "AAT42",
            "AAT43",
            "AAT44"
         ],
         "created_at":1670461080441.507,
         "description":"Cstm  +1  Call  30 Jun 23  28000\n      +2  Call  8 Dec 22  14000",
         "expires_at":1670461681005.817,
         "id":"r_2IbrN2Jt8tM8HQG0SHz6JTXaUz0",
         "is_taker_anonymous":true,
         "kind":"OPTION",
         "label":null,
         "last_trade":null,
         "last_updated_at":1670461381005.817,
         "legs":[
            {
               "instrument_id":154716,
               "instrument_name":"BTC-30JUN23-28000-C",
               "product_code":"DO",
               "quantity":"25.0000",
               "ratio":"1",
               "side":"BUY"
            },
            {
               "instrument_id":185066,
               "instrument_name":"BTC-8DEC22-14000-C",
               "product_code":"DO",
               "quantity":"50.0000",
               "ratio":"2",
               "side":"BUY"
            }
         ],
         "product_codes":[
            "DO"
         ],
         "quantity":"25.0000",
         "quote_currency":"BTC",
         "role":"TAKER",
         "side_layering_limit":1,
         "state":"CLOSED",
         "strategy_code":"CL",
         "strategy_description":"DO_BTC-30JUN23-28000-C_BTC-8DEC22-14000-C",
         "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
         "taker_desk_name":"DSK95",
         "venue":"DBT"
      }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Instruments.
> id string true The Paradigm created unique identifier of the RFQ.
> account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER.
> created_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was created.
> expires_at decimal true The time in UNIX milliseconds since the epoch when the RFQ expires.
> last_updated_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was last updated.
> strategy_description string true The standardized description of the RFQ’s composite Instruments.
> strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.
> description string true The verbose description of the RFQ’s composite Instruments.
> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
> kind string true The composite Instrument kinds of the RFQ. Valid values include FUTURE, OPTION, OPTION_FUTURE.
> base_currency string true The currency the RFQ is exposed to. Valid values include BTC, ETH, SOL.
> quote_currency string true The currency of the price of the RFQ. Valid values include BTC, ETH, SOL, USD, USDC.
> clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
> counterparties Array of strings true The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER.
> role string true The role of the user to the RFQ. Valid values include TAKER, MAKER.
> group_signature string true A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such.
> taker_desk_name string true The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True.
> legs Array of Objects true The composite Instrument legs of the RFQ.
>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>> instrument_name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
>> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places.
>> side string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.
>> quantity string true The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument.
>> price string false The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE.
> product_codes Array of strings true The Paradigm created Product Codes of the composite Instruments to the RFQ.
> quantity string true The total size of the composite Instrument legs, denominated in the clearing_currency.
> is_taker_anonymous boolean true If the Taker Desk Name is to be revealed to the counterparties to the RFQ.
> label string true RFQ creator label of the RFQ.
> side_layering_limit integer true The maximum number of Orders a Maker is able to have either side of an RFQ.
> state string true The availability of the RFQ to trade. Valid values include OPEN, CLOSED.
> closed_reason string true The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR, EXPIRED, EXECUTION_LIMIT. null if the RFQ’s state == OPEN.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3005 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [GET] /rfqs/{rfq_id}

/rfqs/{rfq_id} Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/rfqs/{rfq_id}
method = 'GET'
path = '/v2/drfq/rfqs/123'

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)
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", "https://api.testnet.paradigm.trade/v1/drfq//rfqs/123", data)
    req.Header = headers

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

A [GET] /rfqs/{rfq_id} request returns the specific RFQ requested in the endpoint.

The RFQ creator, denoted by role == TAKER, is able to cancel the RFQ if state == OPEN.

Parameters

Name In Type Required Description
rfq_id endpoint string true The Paradigm created unique RFQ identifier.

/rfqs/{rfq_id} Response example

{
   "account_name":"ParadigmTestNinetyFive",
   "base_currency":"BTC",
   "clearing_currency":"BTC",
   "closed_reason":"EXPIRED",
   "counterparties":[
      "DSK94",
      "AAT42",
      "AAT43",
      "AAT44"
   ],
   "created_at":1670461091765.508,
   "description":"Call  31 Mar 23  24000",
   "expires_at":1670461696044.232,
   "id":"r_2IbrOQ3zGMVrOb7RLRKAizy3lgK",
   "is_taker_anonymous":true,
   "kind":"OPTION",
   "label":null,
   "last_trade":null,
   "last_updated_at":1670461396044.232,
   "legs":[
      {
         "instrument_id":154406,
         "instrument_name":"BTC-31MAR23-24000-C",
         "product_code":"DO",
         "quantity":"25.0000",
         "ratio":"1",
         "side":"BUY"
      }
   ],
   "product_codes":[
      "DO"
   ],
   "quantity":"25.0000",
   "quote_currency":"BTC",
   "role":"TAKER",
   "side_layering_limit":1,
   "state":"CLOSED",
   "strategy_code": "CL",
   "strategy_description":"DO_BTC-31MAR23-24000-C",
   "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
   "taker_desk_name":"DSK95",
   "venue":"DBT"
}

Response Schema

Status Code: 200

Name Type Required Description
id string true The Paradigm created unique identifier of the RFQ.
account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER.
created_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was created.
expires_at decimal true The time in UNIX milliseconds since the epoch when the RFQ expires.
last_updated_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was last updated.
strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.
strategy_description string true The standardized description of the RFQ’s composite Instruments.
description string true The verbose description of the RFQ’s composite Instruments.
venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
kind string true The composite Instrument kinds of the RFQ. Valid values include FUTURE, OPTION, OPTION_FUTURE.
base_currency string true The currency the RFQ is exposed to. Valid values include BTC, ETH, SOL.
quote_currency string true The currency of the price of the RFQ. Valid values include BTC, ETH, SOL, USD, USDC.
clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
counterparties Array of strings true The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER.
role string true The role of the user to the RFQ. Valid values include TAKER, MAKER.
group_signature string true A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such.
taker_desk_name string true The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True.
legs Array of Objects true The composite Instrument legs of the RFQ.
> instrument_id integer true The Paradigm created unique identifier of the Instrument.
> instrument_name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places.
> side string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.
> quantity string true The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument.
> price string false The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE.
product_codes Array of strings true The Paradigm created Product Codes of the composite Instruments to the RFQ.
quantity string true The total size of the composite Instrument legs, denominated in the clearing_currency.
is_taker_anonymous boolean true If the Taker Desk Name is to be revealed to the counterparties to the RFQ.
label string true RFQ creator label of the RFQ.
side_layering_limit integer true The maximum number of Orders a Maker is able to have either side of an RFQ.
state string true The availability of the RFQ to trade. Valid values include OPEN, CLOSED.
closed_reason string true The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR, EXPIRED, EXECUTION_LIMIT. null if the RFQ’s state == OPEN.

Error Codes

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

DRFQv2: [POST] /rfqs

/rfqs Request example

# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/rfqs \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = `{
  "account_name": "ParadigmTestNinetyFive",
  "venue": "DBT",
  "quantity": "100",
  "is_taker_anonymous": true,
  "counterparties": ["DSK2", "DSK3"],
  "legs": [
    {
      "instrument_id": 12314,
      "ratio": "1",
      "side": "SELL"
    }
  ]
}`;
const headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer ACCESS_KEY'
};

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs',
{
  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
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.testnet.paradigm.trade'

# POST /v2/drfq/rfqs
method = 'POST'
path = '/v2/drfq/rfqs'

payload = {
            "account_name": "ParadigmTestNinetyFive",
            "venue": "DBT",
            "quantity": "100",
            "is_taker_anonymous": True,
            "counterparties": ["DSK2", "DSK3"],
            "legs": [
                    {
                        "instrument_id": 12314,
                        "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)
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", "https://api.testnet.paradigm.trade/v2/drfq/rfqs", data)
    req.Header = headers

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

A [POST] /rfqs request attempts to create an RFQ.

The creator of the RFQ will have the role == TAKER.

Only desks specified as counterparties in the request are able receive the RFQ & return prices. The desks aparty to the RFQ must price the full size requested in the RFQ as no partial fills are possible.

/rfqs Body parameter example

{
  "account_name":"ParadigmTestNinetyFive",
  "venue": "DBT",
  "quantity": "100",
  "is_taker_anonymous": true,
  "counterparties": ["DSK2", "DSK3"],
  "legs": [
    {
      "instrument_id": 12314,
      "ratio": "1",
      "side": "SELL"
    }
  ]
}

Parameters

Name In Type Required Description
account_name body string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
venue body string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
quantity body string true The total size of the composite Instrument legs, denominated in the clearing_currency.
is_taker_anonymous body boolean true If the Taker Desk Name is to be revealed to the counterparties to the RFQ.
counterparties body Array of strings true The Paradigm Desk Names or groups aparty to the RFQ.
label body string false User defined label for the RFQ.
legs body Array of Objects true The composite Instruments of the RFQ.
> instrument_id body integer true The Paradigm unique identifier of the Instrument.
> ratio body string true The relative multiplier applied to the quantity of the Instrument’s quantity relative to the quantity of the RFQ. Maximum of 2 decimal places.
> side body string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.
> price body string false The price of the leg, for hedge legs only, in the quote_currency of the Instrument.

/rfqs Response example

201 Response

{
   "id": "12312441241",
   "account_name": "ParadigmTestNinetyFive",
   "created_at": 1656095317329249937.1,
   "expires_at": 1656095317329249938.1,
   "last_updated_at": 1656095317329249939.1,
   "strategy_code": "PT",
   "strategy_description": "DO_BTC-9JUL21-32000-P",
   "description": "Put  9 Jul 21  32000",
   "venue": "DBT",
   "base_currency": "BTC",
   "quote_currency": "BTC",
   "clearing_currency": "BTC",
   "counterparties": ["DSK2", "DSK3"],
   "role": "TAKER",
   "group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
   "taker_desk_name": "DSK95",
   "legs": [
           {
            "instrument_id": 123213213,
            "instrument_name": "BTC-9PUT21-32000-C",
            "product_code": "DO"
            "ratio": "1",
            "side": "SELL",
            "amount": "100"
           }
           ],
   "product_codes": ["DO"],
   "amount": "100",
   "is_taker_anonymous": false,
   "side_layering_limit": 1,
   "state": "ACTIVE"
}

Response Schema

Status Code: 201

Name Type Required Description
id string true The Paradigm created unique identifier of the RFQ.
account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
created_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was created.
expires_at decimal true The time in UNIX milliseconds since the epoch when the RFQ expires.
last_updated_at decimal true The time in UNIX milliseconds since the epoch when the RFQ was last updated.
strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.
strategy_description string true The standardized description of the RFQ’s composite Instruments.
description string true The verbose description of the RFQ’s composite Instruments.
venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
base_currency string true The currency the RFQ is exposed to. Valid values include BTC, ETH, SOL.
quote_currency string true The currency of the price of the RFQ. Valid values include BTC, ETH, SOL, USD, USDC.
clearing_currency string true The currency order sizes/quantities are submitted in. Valid values include BTC, ETH, SOL, USD.
counterparties Array of strings true The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER.
role string true The role of the user to the RFQ. Valid values include TAKER, MAKER.
group_signature string true A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such.
taker_desk_name string true The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True.
legs Array of Objects true The composite Instrument legs of the RFQ.
> instrument_id integer true The Paradigm created unique identifier of the Instrument.
> instrument_name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places.
> side string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.
> quantity string true The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument.
> price string false The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE.
product_codes Array of strings true The Paradigm created Product Codes of the composite Instruments to the RFQ.
quantity string true The total size of the composite Instrument legs, denominated in the clearing_currency.
is_taker_anonymous boolean true If the Taker Desk Name is to be revealed to the counterparties to the RFQ.
label string true RFQ creator label of the RFQ.
side_layering_limit integer true The maximum number of Orders a Maker is able to have either side of an RFQ.
state string true The availability of the RFQ to trade. Valid values include OPEN and CLOSED.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
400 100 "Invalid parameters" You provided invalid value to one or more parameters.
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 1306 "Invalid instrument" You provided invalid instrument for one or more legs.
400 3001 "Venue is not currently supported for this product" Provided venue is not supported.
400 3002 "Invalid leg pricing parameters" You provided invalid price value for one or more legs.
400 3200 "Invalid RFQ leg configuration" You provided invalid configuration of legs.
400 3203 "Invalid leg parameters" You provided invalid value to one or more leg parameters.
400 3206 "An open RFQ for this strategy already exists. Please close that rfq before submitting a new one." There already exist an open RFQ for the same strategy.
400 3401 "Price is outside bands." You provided price that is outside of venue's price bands.

DRFQv2: [DELETE] /rfqs/{rfq_id}

/rfqs/{rfq_id} Request example

# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/rfqs/123 \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

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

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# 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.testnet.paradigm.trade'

# DELETE /v2/drfq/rfqs/{rfq_id}
method = 'DELETE'
path = '/v2/drfq/rfqs/123'

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)
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("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123", data)
    req.Header = headers

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

A [DELETE] /rfqs/{rfq_id} request attempts to cancel a desks' RFQ.

An RFQ's state must equal OPEN for it to be canceled.

Response Schema

Status Code: 204

There is no response payload.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
400 3207 "Too late to cancel RFQ" RFQ has already expired or been filled.
404 3300 "Unavailable RFQ" Unavailable/invalid RFQ Id provided in request.

DRFQv2: [GET] /rfqs/{rfq_id}/orders

/rfqs/{rfq_id}/orders Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/rfqs/{rfq_id}/orders
method = 'GET'
path = '/v2/drfq/rfqs/123/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)
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", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders", data)
    req.Header = headers

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

A [GET] /rfqs/{rfq_id}/orders request allows you to return all state == OPEN orders upon an RFQ.

Only the desk who created the RFQ, role == TAKER, is able to request this endpoint for the RFQ.

Parameters

Name In Type Required Description
rfq_id endpoint string true The Paradigm created unique RFQ identifier.

/rfqs/{rfq_id}/orders Example response

200 Response

{
    "id": "12312441241",
    "bids": [
            {
            "price": "0.001",
            "quantity": "10.01",
            "id": "12321321321",
            "desk": "LDGR"
            }
        ],
    "asks": []
}

Response Schema

Status Code: 200

Name Type Required Description
id string true The Paradigm created unique identifier of the RFQ.
bids Array of Objects true An array of Order objects offering to BUY the RFQ.
> price string true The price of the bid, denominated in the quote_currency of the RFQ.
> quantity string true The amount of the bid, denominated in the clearing_currency of the RFQ.
> id string true The Paradigm created unique identifier of the Order.
> desk string true The Paradigm Desk Name of the creator of the Order.
asks string true An array of Order objects offering to SELL the RFQ.
> price string true The price of the ask, denominated in the quote_currency of the RFQ.
> quantity string true The amount of the ask, denominated in the clearing_currency of the RFQ.
> id string true The Paradigm created unique identifier of the Order.
> desk string true The Paradigm Desk Name of the creator of the Order.

Error Codes

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

DRFQv2: [GET] /orders

/orders Request examples

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/orders \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

;

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
  method: 'GET',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# 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.testnet.paradigm.trade'

# GET /v2/drfq/orders
method = 'GET'
path = '/v2/drfq/orders?page_size=50&cursor=12331a'

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)
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("GET", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
    req.Header = headers

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

A [GET] /orders request allows you to return all of your desks' Orders.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
rfq_id query string false The Paradigm created unique identifier of the associated RFQ.
state query string false The availability of the Order for the user to action. Valid values include OPEN, CLOSED.
venue query string false The underlying settlement venue to return Instruments for. Valid values include DBT, BIT, BYB.
base_currency query string false The currency the Instrument is exposed to. Valid values include BTC, ETH, SOL.

/orders Example response

200 Response

{
   "count":8939,
   "next":"cD0yMDIyLTEyLTA4KzAwJTNBNDAlM0E1MS40MDc3OTElMkIwMCUzQTAw",
   "results":[
      {
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"0",
         "created_at":1670460131779.387,
         "filled_quantity":"50",
         "id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
         "label":"mmh",
         "last_updated_at":1670460132524.4802,
         "pending_fill_quantity":"0",
         "price":"0.2397",
         "quantity":"50",
         "rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
             {
                 "instrument_id": 194874,
                 "price": "0.2"
             }
         ]
      },
      {
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"0",
         "created_at":1670460088632.3892,
         "filled_quantity":"0",
         "id":"o_2IbpMNIiq6dPAlikmKaMJRmkDpQ",
         "label":"mmh",
         "last_updated_at":1670460088700.561,
         "pending_fill_quantity":"25",
         "price":"-0.7927",
         "quantity":"25",
         "rfq_id":"r_2IbpH63lIEI9UCpHS8uBTEy7h75",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
             {
                 "instrument_id": 194874,
                 "price": "0.2"
             }
         ]
      },
      {
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"0",
         "created_at":1670460086147.604,
         "filled_quantity":"25",
         "id":"o_2IbpM7f1EFwm4570NdZARA4IpL2",
         "label":"mmh",
         "last_updated_at":1670460086613.062,
         "pending_fill_quantity":"0",
         "price":"0.2724",
         "quantity":"25",
         "rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
             {
                 "instrument_id": 194874,
                 "price": "0.2"
             }
         ]
      },
      {
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"25",
         "created_at":1670460083979.475,
         "filled_quantity":"0",
         "id":"o_2IbpLkNx8hRgOfRO9aj40WvbXzR",
         "label":"mmh",
         "last_updated_at":1670460084428.182,
         "pending_fill_quantity":"0",
         "price":"-0.7929",
         "quantity":"25",
         "rfq_id":"r_2IbpH63lIEI9UCpHS8uBTEy7h75",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
             {
                 "instrument_id": 194874,
                 "price": "0.2"
             }
         ]
      },
      {
         "account_name":"ParadigmTestNinetyFive",
         "canceled_quantity":"0",
         "created_at":1670460051407.791,
         "filled_quantity":"0",
         "id":"o_2IbpHizejRbn6OXzJmsX0geCIxI",
         "label":"mmh",
         "last_updated_at":1670460051449.946,
         "pending_fill_quantity":"250",
         "price":"-3.0158",
         "quantity":"250",
         "rfq_id":"r_2IbpBRNYSQLfTHvyUNtjmxqB9zm",
         "role":"TAKER",
         "side":"BUY",
         "state":"CLOSED",
         "time_in_force":"FILL_OR_KILL",
         "type":"LIMIT",
         "venue":"DBT",
         "legs": [
             {
                 "instrument_id": 194874,
                 "price": "0.2"
             }
         ]
      }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Instruments.
> id string true The Paradigm created unique identifier of the Order.
> rfq_id string true The Paradigm created unique identifier of the associated RFQ.
> state string true The availability of the Order for the user to action. Valid values include OPEN, CLOSED.
> side string true The direction of the Order. Valid values include BUY, SELL.
> type string true The type of Order. Valid values include LIMIT.
> time_in_force string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
> created_at decimal true The time in UNIX milliseconds since the epoch when the Order was created.
> last_updated_at decimal true The time in UNIX milliseconds since the epoch when the Order was last updated.
> venue string true The underlying settlement venue associated with the Order & RFQ. Valid values include DBT, BIT, BYB.
> quantity string true The size of the Order, denominated in the clearing_currency of the RFQ.
> legs Array of Objects true The composite Instrument legs of the Order.
>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
> price string true The price of the Order, denominated in the quote_currency of the RFQ.
> label string true The user created label for the order.
> pending_fill_quantity string true The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
> filled_quantity string true The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
> canceled_quantity string true The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ.
> account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
> role string true The role of the user in the RFQ. Valid values include TAKER, MAKER.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3005 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [GET] /orders/{order_id}

/orders/{order_id} Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/orders/{order_id}
method = 'GET'
path = '/v2/drfq/orders/123'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
    req.Header = headers

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

A [GET] /orders/{order_id} request returns the specified Order in the endpoint.

Parameters

Name In Type Required Description
order_id endpoint string true The Paradigm created unique Order identifier.

/orders/{order_id} Response example

200 Response

{
   "account_name":"ParadigmTestNinetyFive",
   "canceled_quantity":"0",
   "created_at":1670460051407.791,
   "filled_quantity":"0",
   "id":"o_2IbpHizejRbn6OXzJmsX0geCIxI",
   "label":"mmh",
   "last_updated_at":1670460051449.946,
   "pending_fill_quantity":"250",
   "price":"-3.0158",
   "quantity":"250",
   "rfq_id":"r_2IbpBRNYSQLfTHvyUNtjmxqB9zm",
   "role":"TAKER",
   "side":"BUY",
   "state":"CLOSED",
   "time_in_force":"FILL_OR_KILL",
   "type":"LIMIT",
   "venue":"DBT",
   "legs":[
       {
           "instrument_id": 194874,
           "price": "0.1"
       }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
id string true The Paradigm created unique identifier of the Order.
rfq_id string true The Paradigm created unique identifier of the associated RFQ.
state string true The availability of the Order for the user to action. Valid values include OPEN, CLOSED.
side string true The direction of the Order. Valid values include BUY, SELL.
type string true The type of Order. Valid values include LIMIT.
time_in_force string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
created_at decimal true The time in UNIX milliseconds since the epoch when the Order was created.
last_updated_at decimal true The time in UNIX milliseconds since the epoch when the Order was last updated.
venue string true The underlying settlement venue associated with the Order & RFQ. Valid values include DBT, BIT, BYB.
quantity string true The size of the Order, denominated in the clearing_currency of the RFQ.
legs Array of Objects false The composite Instrument legs of the Order.
> instrument_id integer true The Paradigm created unique identifier of the Instrument.
> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
price string true The price of the Order, denominated in the quote_currency of the RFQ.
label string true The user created label for the order.
pending_fill_quantity string true The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
filled_quantity string true The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ.
canceled_quantity string true The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ.
account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
role string true The role of the user in the RFQ. Valid values include TAKER, MAKER.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
404 3500 "Unavailable order" Unavailable/invalid Order Id provided in request.

DRFQv2: [POST] /orders

/orders Request example

# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/orders \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = `{
  "rfq_id": "12312321321321",
  "account_name": "ParadigmTestNinetyFive",
    "label": "just for me",
    "type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCELED",
    "legs": [
        {
        "instrument_id": 12312312312,
        "price": "0.1"
        }
    ],
    "quantity": "0.1",
    "side": "SELL"
}`;
const headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer ACCESS_KEY'
};

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
  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
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.testnet.paradigm.trade'

# POST /v2/drfq/orders
method = 'POST'
path = '/v2/drfq/orders'

payload = {
            "rfq_id": "123456",
            "account_name": "ParadigmTestNinetyFive",
            "label": "just for me",
            "type": "LIMIT",
            "time_in_force": "GOOD_TILL_CANCELED",
            "legs": [
                    {
                        "instrument_id": 11434,
                        "price": "17000"
                    }
                    ],
            "quantity": "250000",
            "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)
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", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
    req.Header = headers

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

A [POST] /orders request attempts to create an Order.

The response, assuming a successful request, will always return with state == PENDING demonstrating that the matching engine is processing the request. From the orders WebSocket Notification channel, a following message with the state == OPEN indicates the Order is actionable by yourself or other counterparties (if you're the Maker). If the Order state == CLOSED it indicates the order is no longer actionable by anyone.

Desks who create the RFQ, role == TAKER, are only able to submit type == LIMIT orders with time_in_force == FILL_OR_KILL to attempt to cross with an existing Order.

Desks who create the RFQ, role == TAKER, should only submit a strategy price value and should NOT include a legs array in the request body.

Desks who are the counterparties to the RFQ, role == MAKER, are only able to submit type == LIMIT orders with time_in_force == GOOD_TILL_CANCELED.

Desks who are the counterparties to the RFQ, role == MAKER, should only submit individual legs price values and NOT a strategy price value.

Desks whose role == MAKER are not able to submit crossing orders. Only desks who are the RFQ creator, role == TAKER, are able to attempt to cross with the existing Orders.

/orders role == TAKER, Body parameter example

{
  "rfq_id": "12312321321321",
  "account_name": "ParadigmTestNinetyFive",
    "label": "just for me",
    "type": "LIMIT",
    "time_in_force": "FILL_OR_KILL",
    "quantity": "0.1",
    "side": "BUY",
  "price": "0.1",
}

/orders role == MAKER, Body parameter example

{
  "rfq_id": "12312321321321",
  "account_name": "ParadigmTestNinetyFive",
    "label": "just for me",
    "type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCELED",
    "legs": [
        {
            "instrument_id": 12312312312,
            "price": "0.1"
        }
    ],
    "quantity": "0.1",
    "side": "SELL"
}

Parameters

Name In Type Required Description
rfq_id body string true The Paradigm created unique identifier of the RFQ.
account_name body string true The user given name of the Venue API Credentials on the Client Admin Dashboard. This parameter is optional if role == TAKER.
label body string false The user created label for the order.
type body string true The type of Order. Valid values include LIMIT.
time_in_force body string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
legs body Array of Objects false The composite Instrument legs of the Order.
> instrument_id body integer true The Paradigm created unique identifier of the Instrument.
> price body string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
quantity body string true The size of the Order, denominated in the clearing_currency of the RFQ.
price body string false The total price of the Order, denominated in the quote_currency of the RFQ.
side body string true The direction of the Order. Valid values include BUY, SELL.

/orders Response example

201 Response

{
   "account_name": "ParadigmTestNinetyFive",
   "canceled_quantity": "0",
   "created_at": 1675170636837.993,
   "filled_quantity": "0",
   "id": "o_123123",
   "label": "just for me",
   "last_updated_at": 1675170636957.032,
   "legs": [],
   "quantity": "0.1",
   "pending_fill_quantity": "0.1",
   "price": "0.154",
   "rfq_id": "r_12312321321321",
   "role": "TAKER",
   "side": "SELL",
   "state": "PENDING",
   "time_in_force": "FILL_OR_KILL",
   "type": "LIMIT",
   "venue": "DBT"
}

Response Schema

Status Code 201

Name Type Required Description
id string true The Paradigm created unique identifier of the Order.
rfq_id string true The Paradigm created unique identifier of the RFQ.
account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
label string true The user created label for the order.
type string true The type of Order. Valid values include LIMIT.
time_in_force string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
created_at integer true The time in UNIX nanoseconds since the epoch when the Order was created.
quantity string true The total size of the Order, denominated in the clearing_currency of the RFQ.
legs Array of Objects true The composite Instrument legs of the RFQ.
> instrument_id integer false The Paradigm created unique identifier of the Instrument.
> price string false The price of the Instrument leg, denominated in the quote_currency of the RFQ.
price string true The total strategy price of the Order, denominated in the quote_currency of the RFQ.
side string true The direction of the Order. Valid values include BUY, SELL.
state string true The availability of the Order for the user to action. Valid values include PENDING, OPEN, CLOSED
role string true The role of the user in the RFQ. Valid values include TAKER, MAKER.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
400 100 "Invalid parameters" You provided invalid value to one or more parameters.
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" You provided invalid value to one or more leg parameters.
404 3300 "Unavailable RFQ" Unavailable/invalid RFQ Id provided in request.
400 3401 "Price is outside bands." You provided price that is outside of venue's price bands.
400 3503 "An open order for this rfq and side already exists." There already exist an order for the side and rfq provided in the request.

DRFQv2: [PUT] /orders/{order_id}

/orders/{order_id} Request example

# You can also use wget
curl -X PUT https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'

const inputBody = `{
   "account_name": "ParadigmTestNinetyFive",
   "label": "just for me",
   "type": "LIMIT",
   "time_in_force": "GOOD_TILL_CANCELED",
   "legs": [
           {
            "instrument_id": 12312312312,
            "price": "0.1"
           }
           ],
   "amount": "0.1",
   "side": "BUY",
   "rfq_id": "123"
}`;
const headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer ACCESS_KEY'
};

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

# 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.testnet.paradigm.trade'

# PUT /v2/drfq/orders/{order_id}
method = 'PUT'
path = '/v2/drfq/orders/123'

payload = {
            "account_name": "ParadigmTestNinetyFive",
            "label": "just for me",
            "type": "LIMIT",
            "time_in_force": "GOOD_TILL_CANCELED",
            "legs": [
                    {
                        "instrument_id": 1234,
                        "price": "0.1"
                    }
                ],
            "amount": "0.1",
            "side": "BUY",
            "rfq_id": "123"
            }

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.put(
    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("PUT", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
    req.Header = headers

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

A [PUT] /orders/{order_id} request allows a desk to replace an existing state == OPEN Order.

Desks who are the counterparties to the RFQ, role == MAKER, should only submit individual legs price values and NOT a strategy price value.

Upon a successful request, the order will lose it's time priority.

/orders/{order_id} role == MAKER, Body parameter example

{
   "account_name": "ParadigmTestNinetyFive",
   "label": "just for me",
   "type": "LIMIT",
   "time_in_force": "GOOD_TILL_CANCELED",
   "legs": [
           {
            "instrument_id": 12312312312,
            "price": "0.1"
           }
           ],
   "amount": "0.1",
   "side": "BUY",
   "rfq_id": "123"
}

Parameters

Name In Type Required Description
rfq_id body string false The Paradigm created unique identifier of the RFQ. It has to match rfq_id of the Order being replaced.
account_name body string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
label body string false The user created label for the order.
type body string true The type of Order. Valid values include LIMIT.
time_in_force body string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
legs body Array of Objects false The composite Instrument legs of the Order.
> instrument_id body integer false The Paradigm created unique identifier of the Instrument.
> price body string false The price of the Instrument leg, denominated in the quote_currency of the RFQ.
quantity body string true The size of the Order, denominated in the clearing_currency of the RFQ.
side body string false The direction of the Order. Valid values include BUY, SELL. It has to match the side of the Order that is being replaced.

/orders/{order_id} Response example

201 Response

{
  "id": "12312312321",
  "rfq_id": "12312312312",
    "account_name": "ParadigmTestNinetyFive",
    "label": "just for me",
    "type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCELED",
    "created_at": 1656095317329249937,
    "quantity": "0.1",
    "legs": [
           {
             "instrument_id": 123123321,
             "price": "0.154"
           }
            ],
    "price": "0.154",
    "side": "SELL",
    "state": "PENDING",
    "role": "MAKER"
}

Response Schema

Status Code: 201

Name Type Required Description
id string true The Paradigm created unique identifier of the Order.
rfq_id string true The Paradigm created unique identifier of the RFQ.
account_name string true The user given name of the Venue API Credentials on the Client Admin Dashboard.
label string true The user created label for the order.
type string true The type of Order. Valid values include LIMIT.
time_in_force string true The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED, FILL_OR_KILL.
created_at decimal true The time in UNIX milliseconds since the epoch when the Order was created.
quantity string true The total size of the Order, denominated in the clearing_currency of the RFQ.
legs Array of Objects true The composite Instrument legs of the RFQ.
> instrument_id integer false The Paradigm created unique identifier of the Instrument.
> price string false The price of the Instrument leg, denominated in the quote_currency of the RFQ.
price string true The total strategy price of the Order, denominated in the quote_currency of the RFQ.
side string true The direction of the Order. Valid values include BUY, SELL.
state string true The availability of the Order for the user to action. Valid values include PENDING, OPEN, CLOSED
role string true The role of the user in the RFQ. Valid values include TAKER, MAKER.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
400 100 "Invalid parameters" You provided invalid value to one or more parameters.
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" You provided invalid value to one or more leg parameters.
404 3300 "Unavailable RFQ" Unavailable/invalid RFQ Id provided in request.
400 3401 "Price is outside bands." You provided price that is outside of venue's price bands.
404 3500 "Unavailable order" Unavailable/invalid Order Id provided in request.
400 3505 "Invalid quantity." You provided invalid value for quantity.

DRFQv2: [DELETE] /orders

/orders Request example

# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/orders \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
  method: 'DELETE',

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

# 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.testnet.paradigm.trade'

# DELETE /v2/drfq/orders
method = 'DELETE'
path = '/v2/drfq/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.delete(
    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("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
    req.Header = headers

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

A [DELETE] /orders request allows you to attempt to cancel all of your desks' state == OPEN Orders.

Parameters

Name In Type Required Description
rfq_id query string false The Paradigm created unique identifier of the RFQ.
side query string false The direction of the Order. Valid values include BUY, SELL.
label query string false The user created label for the order.

/orders Response example

200 Response

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

Response Schema

Status Code: 200

Name Type Required Description
successes Object true This object demonstrates the successful cancel operations & associated Order IDs.
> count integer true The number of successfully canceled Orders.
> order_ids Array of strings true The Paradigm created Order IDs that have been successfully canceled. [] if no Orders are successfully canceled.
failures Object true This object demonstrates the failed cancel operations & associated Order IDs.
> count integer true The number of failed canceled Order operations.
> order_ids Array of strings true The Paradigm created Order IDs that failed to cancel. [] if no Orders fail to cancel.

Error Codes

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

DRFQv2: [DELETE] /orders/{order_id}

/orders/{order_id} Request example

# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
  method: 'DELETE',

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

# 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.testnet.paradigm.trade'

# DELETE /v2/drfq/orders/{order_id}
method = 'DELETE'
path = '/v2/drfq/orders/123'

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)
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("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
    req.Header = headers

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

A [DELETE] /orders/{order_id} request attempts to cancel the specified state == OPEN Order in the endpoint.

Parameters

Name In Type Required Description
order_id endpoint string true The Paradigm created unique Order identifier.

Response Schema

Status Code: 204

There is no response schema.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
404 3500 "Unavailable order" Unavailable/invalid Order Id provided in request.
400 3502 "Too late to cancel order" The requested order_id is already CLOSED or unavailable to cancel.

DRFQv2: [GET] /trades

/trades Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trades \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/trades',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/trades
method = 'GET'
path = '/v2/drfq/trades'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/trades", data)
    req.Header = headers

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

A [GET] /trades request returns all trades your desk has been aparty too.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
state query string false The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT, FILLED, REJECTED.
rfq_id query string false The Paradigm created unique identifier associated with the RFQ.
venue query string false The underlying settlement venue to return Instruments for. Valid values include DBT, BIT, BYB.
kind query string false The contract type of the associated RFQ. Valid values include OPTION, FUTURE, OPTION_FUTURE.
role query string false The role of the user in the Trade. Valid values include TAKER, MAKER.
order_id query string false The Paradigm created unique identifier associated with the Order.

/trades Response example

200 Response

{
   "count":2921,
   "next":"cD0yMDIyLTEyLTA4KzAwJTNBMzglM0E1MS4yMTY1NjglMkIwMCUzQTAw",
   "results":[
      {
         "id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
         "exec_id":"365636",
         "order_id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
         "rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"COMPLETED",
         "role":"TAKER",
         "executed_at":1670460131896.015,
         "filled_at":1670460132000.0,
         "side":"BUY",
         "price":"0.2397",
         "quantity":"50",
         "filled_quantity":"50",
         "rejected_quantity":"0",
         "rejected_party":null,
         "rejected_reason":null,
         "legs":[
            {
               "instrument_id":154564,
               "instrument_name":"BTC-30JUN23-14000-P",
               "price":"0.2397",
               "product_code":"DO",
               "quantity":"50",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141186632",
               "fee_quantity":"0.0075",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"DO_BTC-30JUN23-14000-P",
         "description":"Put  30 Jun 23  14000",
         "quote_currency":"BTC",
         "mark_price":"0.2407"
      },
      {
         "id":"bt_2IbpM7fQWGK1bILTw2OvwPnMc5P",
         "exec_id":"365635",
         "order_id":"o_2IbpM7f1EFwm4570NdZARA4IpL2",
         "rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"COMPLETED",
         "role":"TAKER",
         "executed_at":1670460086203.6682,
         "filled_at":1670460086000.0,
         "side":"BUY",
         "price":"0.2724",
         "quantity":"25",
         "filled_quantity":"25",
         "rejected_quantity":"0",
         "rejected_party":null,
         "rejected_reason":null,
         "legs":[
            {
               "instrument_id":182233,
               "instrument_name":"BTC-24FEB23-17000-C",
               "price":"0.2724",
               "product_code":"DO",
               "quantity":"25",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141186570",
               "fee_quantity":"0.00375",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"DO_BTC-24FEB23-17000-C",
         "description":"Call  24 Feb 23  17000",
         "quote_currency":"BTC",
         "mark_price":"0.2735"
      },
      {
         "id":"bt_2IbpBwZLazIBOcI24DYsD7ihRoy",
         "exec_id":"365634",
         "order_id":"o_2IbpBwYpwJEXsKQRnNZi8B6NxSQ",
         "rfq_id":"r_2Ibp7AUyp9HTimRTY1TiGqNcI9a",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"COMPLETED",
         "role":"TAKER",
         "executed_at":1670460005229.808,
         "filled_at":1670460005000.0,
         "side":"BUY",
         "price":"4.4713",
         "quantity":"50",
         "filled_quantity":"50",
         "rejected_quantity":"0",
         "rejected_party":null,
         "rejected_reason":null,
         "legs":[
            {
               "instrument_id":153021,
               "instrument_name":"BTC-30JUN23-100000-P",
               "price":"4.9549",
               "product_code":"DO",
               "quantity":"50",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141186463",
               "fee_quantity":"0",
               "fee_currency":"BTC"
            },
            {
               "instrument_id":153009,
               "instrument_name":"BTC-30JUN23-15000-P",
               "price":"0.2418",
               "product_code":"DO",
               "quantity":"100",
               "ratio":"2",
               "side":"SELL",
               "venue_trade_id":"141186462",
               "fee_quantity":"0.015",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"DO_BTC-30JUN23-100000-P_BTC-30JUN23-15000-P",
         "description":"Cstm  +1  Put  30 Jun 23  100000\n      -2  Put  30 Jun 23  15000",
         "quote_currency":"BTC",
         "mark_price":"4.4741"
      },
      {
         "id":"bt_2Ibp2e4vIBlyII2FDG4hcfV4aXr",
         "exec_id":"365633",
         "order_id":"o_2Ibp2e43lJPzyPW4S3j3NR3SwOV",
         "rfq_id":"r_2Ibozkpq0slrvDz93ZPH6u0AHRV",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"COMPLETED",
         "role":"TAKER",
         "executed_at":1670459931825.164,
         "filled_at":1670459932000.0,
         "side":"BUY",
         "price":"-0.4729",
         "quantity":"25",
         "filled_quantity":"25",
         "rejected_quantity":"0",
         "rejected_party":null,
         "rejected_reason":null,
         "legs":[
            {
               "instrument_id":182746,
               "instrument_name":"BTC-16DEC22-15000-P",
               "price":"0.0092",
               "product_code":"DO",
               "quantity":"25",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141186363",
               "fee_quantity":"0",
               "fee_currency":"BTC"
            },
            {
               "instrument_id":141457,
               "instrument_name":"BTC-31MAR23-100000-C",
               "price":"0.0007",
               "product_code":"DO",
               "quantity":"75",
               "ratio":"3",
               "side":"BUY",
               "venue_trade_id":"141186361",
               "fee_quantity":"0",
               "fee_currency":"BTC"
            },
            {
               "instrument_id":148427,
               "instrument_name":"BTC-31MAR23-15000-P",
               "price":"0.2421",
               "product_code":"DO",
               "quantity":"50",
               "ratio":"2",
               "side":"SELL",
               "venue_trade_id":"141186362",
               "fee_quantity":"0.0075",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"DO_BTC-16DEC22-15000-P_BTC-31MAR23-100000-C_BTC-31MAR23-15000-P",
         "description":"Cstm  +1  Put  16 Dec 22  15000\n      +3  Call  31 Mar 23  100000\n      -2  Put  31 Mar 23  15000",
         "quote_currency":"BTC",
         "mark_price":"-0.4699"
      },
      {
         "id":"bt_2Ibp2e0R8HNcoCd709gUyVs4zho",
         "exec_id":"365632",
         "order_id":"o_2Ibp2dzq4zEk6Yu3HcFs45n3NQ4",
         "rfq_id":"r_2Ibp1GHnnO13qvmGeJ6pwAyFAfP",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"COMPLETED",
         "role":"TAKER",
         "executed_at":1670459931216.5679,
         "filled_at":1670459931000.0,
         "side":"BUY",
         "price":"-1.0797",
         "quantity":"50",
         "filled_quantity":"50",
         "rejected_quantity":"0",
         "rejected_party":null,
         "rejected_reason":null,
         "legs":[
            {
               "instrument_id":175553,
               "instrument_name":"BTC-29SEP23-15000-C",
               "price":"0.3751",
               "product_code":"DO",
               "quantity":"50",
               "ratio":"1",
               "side":"BUY",
               "venue_trade_id":"141186360",
               "fee_quantity":"0",
               "fee_currency":"BTC"
            },
            {
               "instrument_id":155835,
               "instrument_name":"BTC-31MAR23-28000-P",
               "price":"0.7274",
               "product_code":"DO",
               "quantity":"100",
               "ratio":"2",
               "side":"SELL",
               "venue_trade_id":"141186359",
               "fee_quantity":"0.015",
               "fee_currency":"BTC"
            }
         ],
         "strategy_description":"DO_BTC-29SEP23-15000-C_BTC-31MAR23-28000-P",
         "description":"Cstm  +1  Call  29 Sep 23  15000\n      -2  Put  31 Mar 23  28000",
         "quote_currency":"BTC",
         "mark_price":"-1.0763"
      }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Trades.
> id string true The Paradigm created unique identifier of the Trade.
> exec_id string true The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue.
> order_id string true The Paradigm created unique Order identifier associated with the Trade.
> rfq_id string true The Paradigm created unique identifier of the RFQ.
> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
> kind string true The nature of the strategy traded. Valid values include OPTION, FUTURE, OPTION_FUTURE.
> state string true The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT, FILLED, REJECTED.
> role string true The role of the user in the Trade. Valid values include TAKER, MAKER.
> executed_at decimal true The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm.
> filled_at decimal true The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle.
> side string true The direction of the user in the trade. Valid values include BUY , SELL.
> price string true The strategy price of the trade, denominated the quote_currency of the RFQ.
> quantity string true The amount of the trade, denominated in the clearing_currency of the RFQ.
> filled_quantity string true The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ.
> rejected_quantity string true The rejected amount of the trade, denominated in the clearing_currency of the RFQ.
> rejected_party string true The counterparty responsible for the Trade Rejection. Valid values include USER, COUNTERPARTY. null of Trade successfully settled.
> rejected_reason string true The reason for the Trade Rejection. null if Trade successfully settled.
> legs Array of Objects true The composite Instrument legs of the Trade.
>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>> instrument_name string true The Paradigm normalized name of the Instrument used across Paradigm’s API.
>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ.
>> side string true The direction of the composite Instrument to the Trade. Valid values include BUY, SELL.
>> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
>> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
>> quantity string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
>> venue_trade_id string true The corresponding unique trade identifier present on the underlying settlement venue. Value to be -1 if rejected.
>> fee_quantity string true The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency.
>> fee_currency string true The currency the fee_amount is denominated in.
> strategy_description string true The standardized description of the Trade’s composite Instruments.
> description string true The verbose description of the Trade’s composite Instruments.
> quote_currency string true The currency in the price is denominated in, denominated in the quote_currency of the RFQ.
> mark_price string true The strategy mark price from the underlying settlement venue of the composite Instruments to the trade.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3005 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [GET] /trades/{trade_id}

/trades/{trade_id} Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trades/123 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/trades/123',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/trades/{trade_id}
method = 'GET'
path = '/v2/drfq/trades/123'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/trades/123", data)
    req.Header = headers

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

A [GET] /trades/{trade_id} request returns the trade specified in the endpoint.

Parameters

Name In Type Required Description
trade_id endpoint string true The Paradigm created unique Trade identifier.

/trades/{trade_id} Response example

200 Response

{
   "id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
   "exec_id":"365636",
   "order_id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
   "rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
   "venue":"DBT",
   "kind":"OPTION",
   "state":"COMPLETED",
   "role":"TAKER",
   "executed_at":1670460131896.015,
   "filled_at":1670460132000.0,
   "side":"BUY",
   "price":"0.2397",
   "quantity":"50",
   "filled_quantity":"50",
   "rejected_quantity":"0",
   "rejected_party":null,
   "rejected_reason":null,
   "legs":[
      {
         "instrument_id":154564,
         "instrument_name":"BTC-30JUN23-14000-P",
         "price":"0.2397",
         "product_code":"DO",
         "quantity":"50",
         "ratio":"1",
         "side":"BUY",
         "venue_trade_id":"141186632",
         "fee_quantity":"0.0075",
         "fee_currency":"BTC"
      }
   ],
   "strategy_description":"DO_BTC-30JUN23-14000-P",
   "description":"Put  30 Jun 23  14000",
   "quote_currency":"BTC",
   "mark_price":"0.2407"
}

Response Schema

Status Code: 200

Name Type Required Description
id string true The Paradigm created unique identifier of the Trade.
exec_id string true The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue.
order_id string true The Paradigm created unique Order identifier associated with the Trade.
rfq_id string true The Paradigm created unique identifier of the RFQ.
venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
kind string true The nature of the strategy traded. Valid values include OPTION, FUTURE, OPTION_FUTURE.
state string true The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT, FILLED, REJECTED.
role string true The role of the user in the Trade. Valid values include TAKER, MAKER.
executed_at decimal true The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm.
filled_at decimal true The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle.
side string true The direction of the user in the trade. Valid values include BUY, SELL.
price string true The strategy price of the trade, denominated the quote_currency of the RFQ.
quantity string true The amount of the trade, denominated in the clearing_currency of the RFQ.
filled_quantity string true The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ.
rejected_quantity string true The rejected amount of the trade, denominated in the clearing_currency of the RFQ.
rejected_party string true The counterparty responsible for the Trade Rejection. Valid values include USER, COUNTERPARTY. null of Trade successfully settled.
rejected_reason string true The reason for the Trade Rejection. null if Trade successfully settled.
legs Array of Objects true The composite Instrument legs of the Trade.
> instrument_id integer true The Paradigm created unique identifier of the Instrument.,
> instrument_name string true The Paradigm normalized name of the Instrument used across Paradigm’s API.
> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ.
> side string true The direction of the composite Instrument to the Trade. Valid values include BUY, SELL.
> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> quantity string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
> venue_trade_id string true The corresponding unique trade identifier present on the underlying settlement venue.
> fee_quantity string true The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency.
> fee_currency string true The currency the fee_amount is denominated in.
strategy_description string true The standardized description of the Trade’s composite Instruments.
description string true The verbose description of the Trade’s composite Instruments.
quote_currency string true The currency in the price is denominated in, denominated in the quote_currency of the RFQ.
mark_price string true The strategy mark price from the underlying settlement venue of the composite Instruments to the trade.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
404 3406 "Unavailable trade" Unavailable/invalid trade id provided in request.

DRFQv2: [GET] /trade_tape

/trade_tape Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trade_tape \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/trade_tape',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/trade_tape
method = 'GET'
path = '/v2/drfq/trade_tape'

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)
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", "https://api.testnet.paradigm.trade/v2/drfq/trade_tape", data)
    req.Header = headers

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

A [GET] /trade_tape request returns all successfully cleared trades.

To return complete results, users must paginate by providing the response's next key value for the cursor query string parameter in the subsequent request.

Parameters

Name In Type Required Description
cursor query string false The cursor value used to paginate through pages. The value to use is the next key value from the response.
page_size query string false The number of elements to return per page.
rfq_id query string false The Paradigm created unique identifier associated with the RFQ.
venue query string false The underlying settlement venue to return Instruments for. Valid values include DBT, BIT, BYB.
product_codes query string false The Paradigm created Product Codes of the composite Instruments. The request can contain multiple codes such as ?product_codes=DO,CF.
strategies query string false Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.

/trade_tape Response example

200 Response

{
   "count":2921,
   "next":"cD0yMDIyLTEyLTA4KzAwJTNBMzglM0E1MS4yMTY1NjglMkIwMCUzQTAw",
   "results":[
      {
         "id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
         "rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"FILLED",
         "executed_at":1670460131896.015,
         "filled_at":1670460132000.0,
         "side":"SELL",
         "price":"0.2397",
         "quantity":"50",
         "legs":[
            {
               "instrument_id":154564,
               "instrument_name":"BTC-30JUN23-14000-P",
               "ratio":"1",
               "side":"BUY",
               "price":"0.2397",
               "product_code":"DO",
               "quantity":"50"
            }
         ],
         "strategy_description":"DO_BTC-30JUN23-14000-P",
         "description":"Put  30 Jun 23  14000",
         "quote_currency":"BTC",
         "mark_price":"0.2407"
      },
      {
         "id":"bt_2IbpM7fQWGK1bILTw2OvwPnMc5P",
         "rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"FILLED",
         "executed_at":1670460086203.6682,
         "filled_at":1670460086000.0,
         "side":"SELL",
         "price":"0.2724",
         "quantity":"25",
         "legs":[
            {
               "instrument_id":182233,
               "instrument_name":"BTC-24FEB23-17000-C",
               "ratio":"1",
               "side":"BUY",
               "price":"0.2724",
               "product_code":"DO",
               "quantity":"25"
            }
         ],
         "strategy_description":"DO_BTC-24FEB23-17000-C",
         "description":"Call  24 Feb 23  17000",
         "quote_currency":"BTC",
         "mark_price":"0.2735"
      },
      {
         "id":"bt_2IbpBwZLazIBOcI24DYsD7ihRoy",
         "rfq_id":"r_2Ibp7AUyp9HTimRTY1TiGqNcI9a",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"FILLED",
         "executed_at":1670460005229.808,
         "filled_at":1670460005000.0,
         "side":"SELL",
         "price":"4.4713",
         "quantity":"50",
         "legs":[
            {
               "instrument_id":153021,
               "instrument_name":"BTC-30JUN23-100000-P",
               "ratio":"1",
               "side":"BUY",
               "price":"4.9549",
               "product_code":"DO",
               "quantity":"50"
            },
            {
               "instrument_id":153009,
               "instrument_name":"BTC-30JUN23-15000-P",
               "ratio":"2",
               "side":"SELL",
               "price":"0.2418",
               "product_code":"DO",
               "quantity":"100"
            }
         ],
         "strategy_description":"DO_BTC-30JUN23-100000-P_BTC-30JUN23-15000-P",
         "description":"Cstm  +1  Put  30 Jun 23  100000\n      -2  Put  30 Jun 23  15000",
         "quote_currency":"BTC",
         "mark_price":"4.4741"
      },
      {
         "id":"bt_2Ibp2e4vIBlyII2FDG4hcfV4aXr",
         "rfq_id":"r_2Ibozkpq0slrvDz93ZPH6u0AHRV",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"FILLED",
         "executed_at":1670459931825.164,
         "filled_at":1670459932000.0,
         "side":"SELL",
         "price":"-0.4729",
         "quantity":"25",
         "legs":[
            {
               "instrument_id":182746,
               "instrument_name":"BTC-16DEC22-15000-P",
               "ratio":"1",
               "side":"BUY",
               "price":"0.0092",
               "product_code":"DO",
               "quantity":"25"
            },
            {
               "instrument_id":141457,
               "instrument_name":"BTC-31MAR23-100000-C",
               "ratio":"3",
               "side":"BUY",
               "price":"0.0007",
               "product_code":"DO",
               "quantity":"75"
            },
            {
               "instrument_id":148427,
               "instrument_name":"BTC-31MAR23-15000-P",
               "ratio":"2",
               "side":"SELL",
               "price":"0.2421",
               "product_code":"DO",
               "quantity":"50"
            }
         ],
         "strategy_description":"DO_BTC-16DEC22-15000-P_BTC-31MAR23-100000-C_BTC-31MAR23-15000-P",
         "description":"Cstm  +1  Put  16 Dec 22  15000\n      +3  Call  31 Mar 23  100000\n      -2  Put  31 Mar 23  15000",
         "quote_currency":"BTC",
         "mark_price":"-0.4699"
      },
      {
         "id":"bt_2Ibp2e0R8HNcoCd709gUyVs4zho",
         "rfq_id":"r_2Ibp1GHnnO13qvmGeJ6pwAyFAfP",
         "venue":"DBT",
         "kind":"OPTION",
         "state":"FILLED",
         "executed_at":1670459931216.5679,
         "filled_at":1670459931000.0,
         "side":"SELL",
         "price":"-1.0797",
         "quantity":"50",
         "legs":[
            {
               "instrument_id":175553,
               "instrument_name":"BTC-29SEP23-15000-C",
               "ratio":"1",
               "side":"BUY",
               "price":"0.3751",
               "product_code":"DO",
               "quantity":"50"
            },
            {
               "instrument_id":155835,
               "instrument_name":"BTC-31MAR23-28000-P",
               "ratio":"2",
               "side":"SELL",
               "price":"0.7274",
               "product_code":"DO",
               "quantity":"100"
            }
         ],
         "strategy_description":"DO_BTC-29SEP23-15000-C_BTC-31MAR23-28000-P",
         "description":"Cstm  +1  Call  29 Sep 23  15000\n      -2  Put  31 Mar 23  28000",
         "quote_currency":"BTC",
         "mark_price":"-1.0763"
      }
   ]
}

Response Schema

Status Code: 200

Name Type Required Description
count integer true The number of elements returned in the response.
next string true Cursor string value to use to paginate results. Equal to null if no more pages are available.
results Array of Objects true Array of Objects with details related to specific Trades.
> id string true The Paradigm created unique identifier of the Trade.
> rfq_id string true The Paradigm created unique identifier of the RFQ.
> venue string true The underlying settlement venue of the RFQ. Valid values include DBT, BIT, BYB.
> kind string true The nature of the strategy traded. Valid values include OPTION, FUTURE, OPTION_FUTURE.
> state string true The indication if the trade has reached settlement finality. Valid values include FILLED.
> executed_at decimal true The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm.
> filled_at decimal true The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm.
> side string true The direction of the user in the trade. Valid values include BUY, SELL.
> price string true The strategy price of the trade, denominated the quote_currency of the RFQ.
> quantity string true The amount of the trade, denominated in the clearing_currency of the RFQ.
> legs string true The composite Instrument legs of the Trade.
>> instrument_id integer true The Paradigm created unique identifier of the Instrument.
>> instrument_name string true The Paradigm normalized name of the Instrument to be used across Paradigm’s API.
>> ratio string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ.
>> side string true The direction of the composite Instrument to the Trade. Valid values include BUY, SELL.
>> price string true The price of the Instrument leg, denominated in the quote_currency of the RFQ.
>> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
>> quantity string true The size of the Instrument leg, denominated in the clearing_currency of the RFQ.
> strategy_description string true The standardized description of the Trade’s composite Instruments.
> description string true The verbose description of the Trade’s composite Instruments.
> quote_currency string true The currency the price is denominated in.
> mark_price string true The strategy mark price from the underlying settlement venue of the composite Instruments to the trade.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 100 "Invalid filter parameter" You provided invalid value to one or more filter parameters.

DRFQv2: [POST] /pricing

/pricing Request example

# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/pricing \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/pricing',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# POST /v2/drfq/pricing
method = 'POST'
path = '/v2/drfq/pricing'

payload = {
            "bid_price": "7950",
            "ask_price": "9600",
            "legs": [
                    {
                        "instrument_id": 1234,
                        "ratio": "1",
                        "side": "BUY"
                    },
                    {
                        "instrument_id": 123,
                        "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)
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("POST", "https://api.testnet.paradigm.trade/v2/drfq/pricing", data)
    req.Header = headers

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

A [POST] /pricing request returns the strategy pricing of the specified composite instruments.

Parameters

Name In Type Required Description
bid_price body string false The strategy price of the Order from the BUY side direction.
ask_price body string false The strategy price of the Order from the SELL side direction.
legs body Array of Objects true The composite Instrument legs of the RFQ.
> instrument_id body integer true The Paradigm created unique identifier of the Instrument.
> ratio body string true The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places.
> side body string true The direction of the composite leg relative to the RFQ. Valid values include BUY, SELL.

/pricing Response example

200 Response

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

Response Schema

Status Code: 200

Name Type Required Description
bid_prices Array of strings true Individual leg composite leg prices for the BUY direction. [] if bid_price is not a part of request payload.
ask_prices Array of strings true Individual leg composite leg prices for the SELL direction. [] if ask_price is not a part of request payload.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials 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.
400 3002 "Invalid leg pricing parameters" You provided invalid value to one or more pricing parameters.
400 3200 "Invalid RFQ leg configuration" You provided invalid legs to the pricing endpoint.
400 3304 "Submitted quote/s were outside venue's price bands" Provided leg prices were outside of price bands of the underlying venue.
400 3310 "Cannot calculate sensical leg prices." Leg prices couldn't be calculated.
400 3311 "Cannot calculate leg prices." Leg prices couldn't be calculated.

DRFQv2: [GET] /rfqs/{rfq_id}/bbo

/rfqs/bbo/{rfq_id} Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer ACCESS_KEY'


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

fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo',
{
  method: 'GET',

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

# 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.testnet.paradigm.trade'

# GET /v2/drfq/rfqs/{rfq_id}/bbo
method = 'GET'
path = '/v2/drfq/rfqs/123/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)
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", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo", data)
    req.Header = headers

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

A [GET] /rfqs/{rfq_id}/bbo request returns the market data for the RFQ's composite instruments from the underlying settlement venue.

If the best_bid_quantity and best_bid_price or best_ask_quantity and best_ask_price are equal to 0, it means that one of the composite instruments of the market does not have an underlying screen order. We are working to remedy this in due course as so we return null when this occurs.

Parameters

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

/rfqs/bbo/{rfq_id} Response example

200 Response

{
    "rfq_id": "123213213",
    "min_price": "21000.00",
    "max_price": "22000.00",
    "mark_price": "21500.00",
    "best_bid_price": "0.01",
    "best_ask_price": "0.011",
    "best_bid_quantity": "10",
    "best_ask_quantity": "10",
    "created_at": 12321321321321321,
    "legs": [
        {
            "best_bid_price": "0.01",
            "best_ask_price": "0.011",
            "best_bid_quantity": "10",
            "best_ask_quantity": "10",
            "instrument_id": 123231213213,
            "instrument_name": "BTC-PERPETUAL",
            "mark_price": "21500.00"
        }
    ]
}

Response Schema

Status Code: 200

Name Type Required Description
rfq_id string true The Paradigm created unique identifier of the RFQ.
min_price string true The minimum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ.
max_price string true The maximum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ.
mark_price string true The strategy mark price of the RFQ’s composite Instruments from the underlying settlement venue. Denominated in the quote_currency of the RFQ.
best_bid_price string true The RFQ’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
best_ask_price string true The RFQ’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
best_bid_quantity string true The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
best_ask_quantity string true The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
created_at decimal true The time in UNIX milliseconds since the epoch when the market data was received from the underlying venue.
legs Array of Objects true The composite Instruments of the RFQ.
> instrument_id integer true The Paradigm created unique identifier of the Instrument.
> instrument_name string true The Paradigm normalized name of the Instrument.
> mark_price string true The Instrument’s mark price from the underlying settlement venue, denominated in the quote_currency of the RFQ.
> best_bid_price string true The Instrument’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
> best_ask_price string true The Instrument’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ.
> best_bid_quantity string true The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.
> best_ask_quantity string true The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ.

Error Codes

HTTP Status Code Paradigm Code Message Meaning
401 N/A "Authentication credentials were not provided." You did not provide authentication credentials.
400 3300 "Unavailable RFQ" Unavailable/invalid RFQ Id provided in request.
400 3202 "Cannot calculate strategy bbo" BBO strategy for provider RFQ Id could not be computed.

DRFQv2: [GET] /mmp/status/

/mmp/status/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/mmp/status/ \
  -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.testnet.paradigm.trade'

# GET /v1/grfq/mmp/status/
method = 'GET'
path = '/v1/grfq/mmp/status/'

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)

/mmp/status/ Response example

{
   "rate_limit_hit": false
}

A [GET] /mmp/status/ request returns the desk's Market Maker Protection (MMP) status.

This endpoint takes no parameters as part of the request.

Response Schema

Status Code: 200

Name Type Required Description
rate_limit_hit bool true A flag indicating if rate limit was hit

DRFQv2: [PATCH] /mmp/status/

/mmp/status/ Request example

# You can also use wget
curl -X PATCH https://api.testnet.paradigm.trade/v1/grfq/mmp/status/ \
  -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.testnet.paradigm.trade'

# PATCH /v1/grfq/mmp/status/
method = 'PATCH'
path = '/v1/grfq/mmp/status/'

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.patch(host+path,
                          headers=headers)

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

A [PATCH] /mmp/status/ resets the Market Maker Protection (MMP) if triggered and enables the user to create new Quotes.

This endpoint takes no parameters as part of the request.

Response Schema

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

Status Code 204

GRFQ - API Workflows

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

GRFQ: 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 underlying venue for clearing & settlement.
  5. Taker and Maker of 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,

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 composed 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.

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

Replace an existing Quote on an RFQ

Users are able to replace a previously submitted Quote for an existing RFQ.

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

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.

GRFQ: 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 accommodate 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:

GRFQ: Comprehensive API Workflow Paths

GRFQ: RFQ Created

Taker's & Maker's Perspective:

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

GRFQ: RFQ Expires

Taker's & Maker's Perspective:

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

GRFQ: Quote Created

Taker's & Maker's Perspective:

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

GRFQ: Quote Canceled

Taker's & Maker's Perspective:

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

GRFQ: 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 part 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 part of the Order.
    • In the event of Successful/Rejected executions at clearing & settlement:
      • Receives WS messages 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 part 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 part 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.

GRFQ: JSON-RPCoverWebSockets

GRFQ: 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

GRFQ: 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":null,
            "latest_activity":1628038165427.839,
            "product_codes":[
               "DO"
            ],
            "status":"ACTIVE",
            "strategy_code": "CP",
            "venue":"DBT",
            "legs":[
               {
                  "instrument":"BTC-4AUG21-39000-C",
                  "product_code":"DO",
                  "ratio":"1",
                  "venue_instrument":"BTC-4AUG21-39000-C",
                  "side":"BUY"
               }
            ]
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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":null,
            "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",
            "strategy_code": "FS"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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

This is a public channel and consumable by all.

Notifications received through the rfq WebSocket channel can include RFQ creations, expirations, and updates. Updates are used to update the latest_activity and last_trade fields while the rfq is active.

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, UPDATED.
> 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 null 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 underlying 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 being traded in the RFQ.
>> status string true Status of the RFQ. Valid values include ACTIVE and EXPIRED.
>> strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group

GRFQ: 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
            "last_activity":1626155549137.600
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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,
            "last_activity":1626155407461.512,
            "rfq_id":816,
            "status":"CLOSED",
            "price":"-13",
            "remaining_quantity":"20000"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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.293
            "last_activity":1626155762785.315
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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 identifier 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.
> last_activity number true The time in unix milliseconds since the epoch when the Quote was updated.
> remaining_quantity string true The remaining Quantity upon the Quote in contract units of the RFQ.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired with seq_group.

GRFQ: 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":""
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

An example of the quote notification received when a Quote has been completely 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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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/{quote_id}/ 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"
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired with this identifier.

GRFQ: 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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired within seq_group

GRFQ: 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"
         }
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
      }
   }
}

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":null
               }
            ],
            "venue":"DBT",
            "rfq_id":1232
         }
      },
      "venue_error":{
         "message":"DBT Error: Trade refused by exchange"
      },
      "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
     }
   }
}

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 of 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 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.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired with this identifier.

GRFQ: 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"
         }
     },
     "meta": {
        "seq_group": 1692463499,
        "seq_num": 1027
     }
   }
}

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.
meta object true
> seq_num int true Incrementing sequence number, relevant to messages within the sequence_group/channel.
> seq_group int true Identifier for a channel group. Sequence numbers are only relevant paired with this identifier.

Message Sequence Numbers

WebSocket messages contain sequence numbers to help clients identify if they have missed any messages during temporary disconnections or network errors. The sequence number is included in the WebSocket messages under the meta field.

Message Structure with Sequence Numbers

WebSocket messages now include an additional meta field that contains the following properties:

Member Type Description
seq_group number Unique identifier for the group of messages
seq_num number Sequence number of the message within the group

Here's an example of a WebSocket message with sequence numbers:

{
  "jsonrpc": "2.0",
  "method": "subscription",
  "params": {
    "channel": "rfq",
    "data": {
    },
    "meta": {
      "seq_group": 1692463499,
      "seq_num": 1027
    }
  }
}

Handling Sequence Numbers

Clients should monitor the sequence numbers of the incoming messages to ensure they have not missed any messages. If a client detects a gap in the sequence numbers, it may have missed one or more messages and should take appropriate action, such as refreshing data from REST.

Sequences increase monotonically within the context of a sequence group. Sequences are only relevant within a sequence group, which represents a subscribed channel. Sequences may be re-used between sequence groups.

While messages are sent ordered according to their sequences, sequences are not guaranteed not to repeat.

GRFQ - REST Endpoints

GRFQ: [GET] /instruments/

/instruments/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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": [
   {
      "expiration": 1680854400000,
      "greeks": null,
      "base_currency": "ETH",
      "margin_kind": "INVERSE",
      "kind": "FUTURE",
      "mark_price": "1718.3",
      "name": "ETH-7APR23",
      "option_kind": null,
      "product_code": "AZ",
      "strike": null,
      "venue": "DBT",
      "venue_name": "ETH-7APR23"
   },
   {
      "expiration": 1680854400000,
      "greeks": null,
      "base_currency": "BTC",
      "margin_kind": "INVERSE",
      "kind": "FUTURE",
      "mark_price": "27144.7",
      "name": "BTC-7APR23",
      "option_kind": null,
      "product_code": "CF",
      "strike": null,
      "venue": "DBT",
      "venue_name": "BTC-7APR23"
   },
   {
      "expiration": 1703836800000,
      "greeks": {
         "delta": "0.46821",
         "gamma": "0.00043",
         "mark_price": "0.1437",
         "theta": "-0.67045",
         "vega": "6.03833",
         "last_updated_at": 1679945359701
      },
      "base_currency": "ETH",
      "margin_kind": "INVERSE",
      "kind": "OPTION",
      "mark_price": "0.1437",
      "name": "ETH-29DEC23-2100-C",
      "option_kind": "CALL",
      "product_code": "EH",
      "strike": "2100",
      "venue": "DBT",
      "venue_name": "ETH-29DEC23-2100-C"
   },
   {
      "expiration": 1703836800000,
      "greeks": {
         "delta": "-0.52159",
         "gamma": "2e-05",
         "mark_price": "0.3911",
         "theta": "-11.79815",
         "vega": "95.74543",
         "last_updated_at": 1679945357964
      },
      "base_currency": "BTC",
      "margin_kind": "INVERSE",
      "kind": "OPTION",
      "mark_price": "0.3911",
      "name": "BTC-29DEC23-34000-P",
      "option_kind": "PUT",
      "product_code": "DO",
      "strike": "34000",
      "venue": "DBT",
      "venue_name": "BTC-29DEC23-34000-P"
   }
  ]
}

A [GET] /instruments/ request allows you to return all available Instruments upon Paradigm. Instruments are the legs part 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.
include_greeks query boolean false Include greeks in the response.

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
> base_currency string true The currency the Instrument is exposed to. Valid values include BCH, BTC, ETH.
> margin_kind string true The nature of how the contract is margined. Valid values include LINEAR, INVERSE.
> option_kind string true The kind of Option. null if instrument is not an Option. Valid values include CALL, PUT, null.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> 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.
> mark_price string true The mark price of the Instrument.
> greeks object false The greeks of the Instrument.
>> delta string true The delta of the Instrument.
>> gamma string true The gamma of the Instrument.
>> theta string true The theta of the Instrument.
>> vega string true The vega of the Instrument.
>> mark_price string true The mark price of the Instrument. Deprecated: please use the top level mark_price
>> last_updated_at int true The timestamp in unix milliseconds since the epoch when the greek values were last updated.

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.

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

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

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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

{
   "expiration": 1703836800000,
   "greeks": {
      "delta": "-0.52159",
      "gamma": "2e-05",
      "mark_price": "0.3911",
      "theta": "-11.79815",
      "vega": "95.74543",
      "last_updated_at": 1679945357964
   },
   "base_currency": "BTC",
   "margin_kind": "INVERSE",
   "kind": "OPTION",
   "mark_price": "0.3911",
   "name": "BTC-29DEC23-34000-P",
   "option_kind": "PUT",
   "product_code": "DO",
   "strike": "34000",
   "venue": "DBT",
   "venue_name": "BTC-29DEC23-34000-P"
}

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

Instruments are the legs part 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.
include_greeks query boolean false Include greeks in the response.

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
> base_currency string true The currency the Instrument is exposed to. Valid values include BCH, BTC, ETH.
> margin_kind string true The nature of how the contract is margined. Valid values include LINEAR, INVERSE.
> option_kind string true The kind of Option. null if instrument is not an Option. Valid values include CALL, PUT, null.
> product_code string true The Paradigm created unique two-letter code to represent the specific Instrument.
> 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.
> mark_price string true The mark price of the Instrument.
> greeks object false The greeks of the Instrument.
>> delta string true The delta of the Instrument.
>> gamma string true The gamma of the Instrument.
>> theta string true The theta of the Instrument.
>> vega string true The vega of the Instrument.
>> mark_price string true The mark price of the Instrument. Deprecated: please use the top level mark_price
>> last_updated_at int true The timestamp in unix milliseconds since the epoch when the greek values were last updated.

Error Codes

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

GRFQ: [GET] /orders/

/orders/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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 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.

GRFQ: [GET] /orders/{order_id}/

/orders/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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.

GRFQ: [GET] /quotes/

/quotes/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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 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.
status query string false The status of the Quotes. Valid values include OPEN and CLOSED.

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.
> last_activity number true The time in unix milliseconds since the epoch when the Quote was updated.
> 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.
> type string true The Quote OrderType. Valid values include LIMIT.
> description string true The RFQ strategy description.
> product_codes array of strings true The RFQ product codes.
> 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.

GRFQ: [GET] /quotes/{quote_id}/

/quotes/{quote_id}/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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.

GRFQ: [DELETE] /quotes/

/quotes/ Request example

# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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 active 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.
price query decimal false Cancel all Quotes matching the given price.

Response Schema

Status Code 200

In the case of a failure to cancel any quote, the request will return an HTTP Status Code of 207

Quotes that are being processed (previously cancelled, under execution) at the time of request may be returned as failures

Name Type Required Description
successes array of objects true Information about successful Quote cancellations.
> 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 cancellations.
> 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.

GRFQ: [DELETE] /quotes/{quote_id}/

/quotes/{quote_id}/ Request example

# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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 an 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 Code Message Meaning
401 N/A "Authentication credentials provided were not provided." You did not provide authentication credentials.
400 3306 "Too late to cancel." The requested quote_id is already CLOSED or unavailable to cancel.
400 3308 "Unavailable quote You are not the desk who created the Quote.

GRFQ: [GET] /rfqs/

/rfqs/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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",
         "strategy_code": "PT"
      },
      {
         "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",
         "strategy_code":"IY"
      },
      {
         "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",
         "strategy_code":"CL"
      },
      {
         "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",
         "strategy_code":"CL"
      },
      {
         "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",
         "strategy_code":"PT"
      },
      {
         "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",
         "strategy_code":"IB"
      },
      {
         "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",
         "strategy_code":"ID"
      },
      {
         "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",
         "strategy_code":"CM"
      },
      {
         "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",
         "strategy_code":"CL"
      },
      {
         "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",
         "strategy_code":"FT"
      },
      {
         "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",
         "strategy_code":"FS"
      },
      {
         "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",
         "strategy_code":"FS"
      },
      {
         "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",
         "strategy_code":"FS"
      }
   ]
}

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 standardized 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.
> strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.

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.

GRFQ: [GET] /rfqs/{rfq_id}/

/rfqs/{rfq_id}/ Request example

# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/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.testnet.paradigm.trade'

# 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.
> strategy_code string true Strategy code of the RFQ. Valid values include CL, CB, CC, CR, CS, CM, FT, FS, PT, PB, PC, PR, PS, SD, SG, IC, IP, IB, IY, ID, IG, IS.

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.

GRFQ: [POST] /rfqs/

/rfqs/ Request example

# built ins
import base64
import hmac
import json
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.testnet.paradigm.trade'

# 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",
   "strategy_code":"CM"
}

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.
> instrument body string true The name of the Instrument per Paradigm'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 s