# Backpack Exchange Python API guide

### Prerequisites

Get your API keys if you are going to use account endpoints: \
<https://backpack.exchange/settings/api-keys>

Install the required Python libraries:

* cryptography – for X-Signature ([account endpoints](https://docs.backpack.exchange/#tag/Account) only)
* requests – for making HTTP requests (or aiohttp if you prefer async)

```
pip3 install cryptography requests 
```

Install dotenv-python to securely manage your keys using environment variables if you are going to use [account endpoints](https://docs.backpack.exchange/#tag/Account)

```
pip3 install python-dotenv
```

Create a .env file and store your keys like this:

```
PUBLIC_KEY=zDIJj9qneWIY0IYZ5aXoHcNMCm+XDhVcTssiT0HyY0A=
SECRET_KEY=4odxgSUxFrC/zsKWZF4OQwYAgnNu9hnWH3NxWfLAPz4=
```

Create a .gitignore file and add .env to exclude it from version control.

```
.env
```

For all examples, we will use the synchronous requests library. Let's import it:

```
import requests
```

### Public endpoints <a href="#public-endpoints" id="public-endpoints"></a>

For public endpoints, simply send a GET request.

No API keys are required.

#### Example: Accessing Public Data <a href="#example-accessing-public-data" id="example-accessing-public-data"></a>

```
# https://docs.backpack.exchange/#tag/Markets/operation/get_open_interest
BASE_URL: str = "https://api.backpack.exchange/"  # base api url for all endpoints
symbol: str = "SOL_USDC_PERP" # let's specify the symbol
result_url: str = f"{BASE_URL}api/v1/openInterest?symbol={symbol}"  # add your argument as a query string. For GET requests you need only query string
```

```
from json import JSONDecodeError

response = requests.get(url=result_url) # make a get request
print(f"response status code: {response}")
if response.status_code == 200:
    # make your code safe in case you receive unexpected data
    try:
        print(f"response json: {response.json()}") 

        open_interest: str = response.json()[0]["openInterest"]
        print(f"open interest: {open_interest}")
    except JSONDecodeError:
        print(f"response text if response isn't json: {response.text}")
else:
    ...
```

\
**Note:** If you have more than one argument, join them using the & symbol.

### Private endpoints <a href="#private-endpoints" id="private-endpoints"></a>

For private endpoints, we need to create specific headers and a request body (for POST requests). This requires authentication with your API keys.

```
import base64  # for base64 encoding the signature
from time import time  # for timestamp generation
import os  # to access environment variables

from cryptography.hazmat.primitives.asymmetric import ed25519  # to create a private key for signing
# from dotenv import load_dotenv, find_dotenv  # to load environment variables from .env file
```

```
# In production code, use this approach:
# load_dotenv(find_dotenv())
# public_key: str = os.getenv("PUBLIC_KEY")
# secret_key: str = os.getenv("SECRET_KEY")

# For demonstration purposes only - don't hardcode keys in production
public_key: str = "5+yQgwU0ZdJ/9s+GXfuPFfo7yQQpl9CgvQedJXne30o="
secret_key: str = "TDSkv44jf/iD/QCKkyCdixO+p1sfLXxk+PZH7mW/ams="  

# Create private key from secret key
private_key = ed25519.Ed25519PrivateKey.from_private_bytes(
            base64.b64decode(secret_key)
        )
```

#### Example: Retrieving a Deposit Address <a href="#example-retrieving-a-deposit-address" id="example-retrieving-a-deposit-address"></a>

Let's see how to retrieve a deposit address using the API: <https://docs.backpack.exchange/#tag/Capital/operation/get_deposit_address>

```
# Generate timestamp and window parameters
timestamp = int(time() * 1e3)  # Unix time in milliseconds
window: str = "5000"  # Time window in milliseconds that the request is valid for
```

Now that we have our authentication components ready (`X-Timestamp`, `X-Window`, and `X-API-Key`), let's create the signature.

```
# Define the instruction for this API call
instruction: str = "depositAddressQuery"
sign_str = f"instruction={instruction}"

# This endpoint requires the "blockchain" parameter
params: dict = {
    "blockchain": "Solana",
}

# Generate a valid query string from parameters
sorted_params_list = []
for key, value in sorted(params.items()):
    if isinstance(value, bool):  # boolean variables should be lowercase in query strings
        value = str(value).lower()
    sorted_params_list.append(f"{key}={value}")
sorted_params = "&".join(sorted_params_list)

# Combine all parts of the signature string
if sorted_params:
    sign_str += "&" + sorted_params
sign_str += f"&timestamp={timestamp}&window={window}" 

print(f"Signature string: {sign_str}")
```

#### Signing the Request <a href="#signing-the-request" id="signing-the-request"></a>

Now let's sign the request with our private key:

```
# Sign the string with our private key
signature_bytes = private_key.sign(sign_str.encode())
encoded_signature = base64.b64encode(signature_bytes).decode()
print(f"Base64 encoded signature: {encoded_signature}")
```

#### Creating Headers <a href="#creating-headers" id="creating-headers"></a>

Create the required headers for the API request:

```
# Prepare the headers with all required authentication parameters
headers = {
    "X-API-Key": public_key,
    "X-Signature": encoded_signature,
    "X-Timestamp": str(timestamp),
    "X-Window": window,
    "Content-Type": "application/json; charset=utf-8",
}
```

#### Sending the Request <a href="#sending-the-request" id="sending-the-request"></a>

Now we can send the authenticated request to the API:

```
# Send the GET request with our authentication headers
url = "https://api.backpack.exchange/wapi/v1/capital/deposit/address"
response = requests.get(url=url, headers=headers, params=params)
print(response.json())
```

### Using POST Requests <a href="#using-post-requests" id="using-post-requests"></a>

For `POST` requests, you need to include the JSON body and use the `post()` method instead of `get()`.

#### Example: Executing an Order <a href="#example-executing-an-order" id="example-executing-an-order"></a>

Let's see how to submit an order to the matching engine for execution using the API: <https://api.backpack.exchange/api/v1/order>

```
# Generate timestamp and window parameters
timestamp = int(time() * 1e3)  # Unix time in milliseconds
window = "5000"  # Time window in milliseconds that the request is valid for

# Define the instruction for this API call
instruction = "orderExecute"
sign_str = f"instruction={instruction}"

# Create the order request body
order_params = {
    "symbol": "SOL_USDC",       # Required: The market for the order
    "side": "Bid",              # Required: "Bid" (buy) or "Ask" (sell)
    "orderType": "Limit",       # Required: "Market" or "Limit"
    "price": "170.50",           # The order price (required for limit orders)
    "quantity": "1.0",          # The order quantity
    "timeInForce": "GTC",       # "GTC" (Good Till Cancelled), "IOC" (Immediate or Cancel), "FOK" (Fill or Kill)
    "clientId": 123456,         # Custom order ID (optional)
    "selfTradePrevention": "RejectTaker"  # Optional: "RejectTaker", "RejectMaker", "RejectBoth"
}

# Generate a valid query string from parameters
sorted_params_list = []
for key, value in sorted(order_params.items()):
    if isinstance(value, bool):  # boolean variables should be lowercase in query strings
        value = str(value).lower()
    sorted_params_list.append(f"{key}={value}")
sorted_params = "&".join(sorted_params_list)

# Combine all parts of the signature string
if sorted_params:
    sign_str += "&" + sorted_params
sign_str += f"&timestamp={timestamp}&window={window}" 

print(f"Signature string: {sign_str}")
```

```
# Sign the string with our private key
signature_bytes = private_key.sign(sign_str.encode())
encoded_signature = base64.b64encode(signature_bytes).decode()
print(f"Base64 encoded signature: {encoded_signature}")
```

```
# Prepare the headers with all required authentication parameters
headers = {
    "X-API-Key": public_key,
    "X-Signature": encoded_signature,
    "X-Timestamp": str(timestamp),
    "X-Window": window,
    "Content-Type": "application/json; charset=utf-8",
}
```

```
# Send the POST request with our authentication headers and order parameters
url = "https://api.backpack.exchange/api/v1/order"
response = requests.post(url=url, headers=headers, json=order_params)
print(f"Response status code: {response.status_code}")
try:
    print(f"Response JSON: {response.json()}")
except JSONDecodeError:
    print(f"Response text: {response.text}")
```

### Sources

SDK makes the development process much easier.

Example SDK: <https://github.com/sndmndss/bpx-py>

For more information, visit the official documentation: <https://docs.backpack.exchange/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://support.backpack.exchange/exchange/api-and-developer-docs/backpack-exchange-python-api-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
