# Getting Started with Crypto Swaps
Leverage SideShift's trading infrastructure to add fast, direct-to-wallet shifts to your project. Our API lets you request quotes, create shifts, and support 200+ assets across multiple networks. Track your earnings and configure automatic withdrawals via your [dashboard](https://sideshift.ai/dashboard).
## 1. Create an Account
1. A SideShift.ai account is created in three ways:
- When creating a shift on the site
- When visiting the [account page](https://sideshift.ai/account)
- Programmatically via [`POST /v2/create-account`](/endpoints/v2/createaccount)
If you already have an account from the site, skip to the **Already have an account on the site?** note below.
2. To create one programmatically, generate an Ed25519 keypair offline. See [Authentication](/api-intro/authentication#1-generate-a-keypair).
:::warning
Never share your secret key with anyone. It grants full access to your account and SideShift cannot recover it.
:::
3. Create your account with the public key via [`POST /v2/create-account`](/endpoints/v2/createaccount):
```bash
curl -L 'https://sideshift.ai/api/v2/create-account' \
-H 'Content-Type: application/json' \
-d '{ "pubKey": "PUBLIC_KEY" }'
```
4. Save the returned **Account ID** (`id`) – passed as `affiliateId`.
:::info
Your account represents your integration, not your individual users. Use the same credentials for all shift requests. End users are identified by their `shiftId`.
:::
```bash title=".env"
SIDESHIFT_SECRET_KEY=YOUR_ED25519_SECRET_KEY #NEVER COMMIT THIS
SIDESHIFT_PUB_KEY=YOUR_ED25519_PUBLIC_KEY
AFFILIATE_ID=YQMi62XMb #REPLACE WITH YOUR SIDESHIFT ACCOUNT ID
```
Authenticated requests are signed with your secret key and carry three headers: `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature`. See [Authentication](/api-intro/authentication#3-sign-each-request) for how to build them.
:::note Already have an account on the site?
Click **Show Private Key** on the [account page](https://sideshift.ai/account) and copy the key. If it is 64 hex characters, it is your Ed25519 secret key and is already registered, so you can sign with it straight away. It is not your old account secret. If it is 32 characters, it is a legacy account secret: send it as the `x-sideshift-secret` header instead of the three signature headers. It works during a migration period, so [register a key](/api-intro/authentication#migrate-to-signed-requests) and switch to signing.
:::
## 2. Request a Quote
Replace `PUBLIC_KEY`, `TIMESTAMP` and `SIGNATURE` with the headers built for this exact request (`POST`, `/api/v2/quotes` and the body), as shown in [Authentication](/api-intro/authentication#3-sign-each-request). Replace `AFFILIATE_ID` with your account ID.
```
curl -L 'https://sideshift.ai/api/v2/quotes' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-d '{
"depositCoin": "eth",
"depositNetwork": "arbitrum",
"settleCoin": "eth",
"settleNetwork": "mainnet",
"depositAmount": "0.14364577",
"settleAmount": null,
"affiliateId": "AFFILIATE_ID"
}'
```
Save the returned `id` as `QUOTE_ID`.
## 3. Create a Fixed Shift
```
curl -L 'https://sideshift.ai/api/v2/shifts/fixed' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-d '{
"settleAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"affiliateId": "AFFILIATE_ID",
"quoteId": "QUOTE_ID"
}'
```
Display the `depositAddress` to your user and poll `/v2/shifts/{shiftId}` to monitor the shift's status.
:::warning
The returned shift `id` is sensitive data. The order page is reachable by ID alone, so anyone with the ID can open it and, if the `refundAddress` was not set at order creation, choose where a refund is sent or cancel the order.
:::
## Relevant Resources
- [How to create a SideShift.ai account and backup your private key?](https://help.sideshift.ai/en/articles/8974541-how-to-create-a-sideshift-ai-account-and-backup-your-private-key)
- [How to recover/restore my account?](https://help.sideshift.ai/en/articles/4667810-how-do-i-recover-restore-my-account)
# API Authentication with Signed Requests
SideShift.ai authenticates API requests with an **Ed25519 keypair** that you generate yourself. You register the public key with your account and sign each request with the secret key. SideShift only stores the public key, so the secret key never leaves your server.
New integrations should use signed requests. The [legacy account secret](#legacy-account-secret) (`x-sideshift-secret`) still works during a migration period. If you use it, [migrate to signed requests](#migrate-to-signed-requests).
## 1. Generate a Keypair
Generate the keypair offline, once. Both keys are 32 bytes, hex encoded (64 characters).
```js title="JavaScript"
import { ed25519 } from '@noble/curves/ed25519.js';
import { bytesToHex } from '@noble/curves/utils.js';
const secretKey = crypto.getRandomValues(new Uint8Array(32));
const pubKey = bytesToHex(ed25519.getPublicKey(secretKey));
const secretKeyHex = bytesToHex(secretKey); // store this
```
```python title="Python (PyNaCl)"
from nacl.signing import SigningKey
signing_key = SigningKey.generate()
secret_key = signing_key.encode().hex()
pub_key = signing_key.verify_key.encode().hex()
```
:::warning
Store the secret key like a password. Anyone who has it can act as your account, and SideShift cannot recover it for you.
:::
## 2. Create an Account with Your Public Key
Send the public key to [`POST /v2/create-account`](/endpoints/v2/createaccount):
```bash
curl -L 'https://sideshift.ai/api/v2/create-account' \
-H 'Content-Type: application/json' \
-d '{ "pubKey": "PUBLIC_KEY" }'
```
```json title="Response"
{
"id": "YQMi62XMb",
"pubKey": "PUBLIC_KEY"
}
```
Use the returned `id` as your `affiliateId`. An account created this way has **no secret**: the keypair is its only credential.
### Using the Private Key from the Account Page
If you created your account on the site, open the [account page](https://sideshift.ai/account), click **Show Private Key** and copy the key. Check its length:
- **64 hex characters:** this is your Ed25519 secret key. It is already registered to your account, so you can sign requests with it straight away. It is not your legacy account secret, even though it is shown under the same button. Your public key is derived from it:
```js
const pubKey = bytesToHex(ed25519.getPublicKey(hexToBytes(secretKeyHex)));
```
- **32 characters:** this is a [legacy account secret](#legacy-account-secret). Send it as `x-sideshift-secret`, and [migrate to signed requests](#migrate-to-signed-requests) when you can.
## 3. Sign Each Request
Build the message by joining these four values, with no separators and no hashing:
```
timestamp + METHOD + path + body
```
| Part | Value |
| ----------- | --------------------------------------------------------------------------------------------------------- |
| `timestamp` | Current Unix time in **milliseconds**, as a string. The same value goes in `x-sideshift-timestamp`. |
| `METHOD` | HTTP method in uppercase, e.g. `GET`, `POST`. |
| `path` | Everything after the host, including `/api` and the query string, e.g. `/api/v2/shifts/variable`. |
| `body` | The exact request body string you send. Use an empty string for requests without a body, such as `GET`. |
Sign the message with your secret key and send these three headers:
| Header | Value |
| ----------------------- | --------------------------------------------- |
| `x-sideshift-key` | Your public key, hex (a `0x` prefix is optional) |
| `x-sideshift-timestamp` | The timestamp used in the message |
| `x-sideshift-signature` | The Ed25519 signature, hex (128 characters) |
```js title="JavaScript"
import { ed25519 } from '@noble/curves/ed25519.js';
import { bytesToHex, hexToBytes } from '@noble/curves/utils.js';
const signRequest = ({ method, path, body = '' }, secretKeyHex, pubKey) => {
const timestamp = Date.now().toString();
const message = new TextEncoder().encode(timestamp + method.toUpperCase() + path + body);
const signature = bytesToHex(ed25519.sign(message, hexToBytes(secretKeyHex)));
return {
'x-sideshift-key': pubKey,
'x-sideshift-timestamp': timestamp,
'x-sideshift-signature': signature,
};
};
const path = '/api/v2/shifts/variable';
const body = JSON.stringify({
settleAddress: '0xde2642b2120fd3011fe9659688f76e9E4676F472',
affiliateId: 'YQMi62XMb',
depositCoin: 'btc',
depositNetwork: 'bitcoin',
settleCoin: 'eth',
settleNetwork: 'mainnet',
});
const response = await fetch(`https://sideshift.ai${path}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-user-ip': END_USER_IP,
...signRequest({ method: 'POST', path, body }, secretKeyHex, pubKey),
},
body,
});
```
```python title="Python"
import time
from nacl.signing import SigningKey
def sign_request(method, path, body, secret_key):
signing_key = SigningKey(bytes.fromhex(secret_key))
timestamp = str(int(time.time() * 1000))
message = (timestamp + method.upper() + path + body).encode()
signature = signing_key.sign(message).signature.hex()
return {
"x-sideshift-key": signing_key.verify_key.encode().hex(),
"x-sideshift-timestamp": timestamp,
"x-sideshift-signature": signature,
}
```
### Signing Rules
- **Sign the exact bytes you send.** Serialize the body once, sign that string, and send that same string. Re-serializing after signing (different key order or spacing) breaks the signature.
- **Send `Content-Type: application/json`** on requests with a body. Without it, the body is not included when the signature is checked, and the request fails with `Invalid authorisation signature`.
- **The timestamp must be within 60 seconds of server time.** If it is not, the error response includes `serverTime` so you can correct your clock offset.
- **Sign again on every retry.** Generate a new timestamp and signature for each attempt.
- **A signature takes priority over a secret.** If `x-sideshift-signature` is present, the request is authenticated by signature only, and an invalid signature fails with `401` even on endpoints that do not require authentication.
Signed requests work on every endpoint that accepts `x-sideshift-secret`.
## Errors
Signature failures return `401` with code `INVALID_SIGNATURE`. See [Error Codes](/error-codes) for every message and how to fix it.
If your clock is off by more than 60 seconds, the error includes `serverTime`. Use it to correct your clock offset:
```json title="Example"
{
"error": {
"message": "Timestamp outside of valid 60s range",
"serverTime": 1792743050123,
"code": "INVALID_SIGNATURE"
}
}
```
## Managing Keys
An account can have up to **5 active keys**. Use these endpoints to rotate a key without creating a new account:
- [`GET /v2/account/auth-keys`](/endpoints/v2/accountauthkeys): list your keys.
- [`POST /v2/account/auth-keys`](/endpoints/v2/addaccountauthkey): register another key.
- [`DELETE /v2/account/auth-keys/{id}`](/endpoints/v2/disableaccountauthkey): disable a key.
To rotate a key:
1. Generate a new keypair.
2. Register it with `POST /v2/account/auth-keys`, authenticated with your current key. To prove you own the new key, sign your **account ID** string with the new secret key and send it as `signature`. A proof signed over anything else, or with the current key, fails with `400 Invalid signature`.
3. Switch your integration to the new key.
4. Disable the old key with `DELETE /v2/account/auth-keys/{id}`.
```js title="Proof of ownership for a new key"
const signature = bytesToHex(
ed25519.sign(new TextEncoder().encode(accountId), hexToBytes(newSecretKeyHex))
);
// body: { "pubKey": newPubKey, "signature": signature }
```
:::info
You cannot disable the last active key of an account that has no secret, because the account would be locked.
:::
## Legacy Account Secret
Older accounts, and accounts created with `POST /v2/create-account` without a `pubKey`, have a 32 character account **secret**. Send it as the `x-sideshift-secret` header:
```bash
curl -L 'https://sideshift.ai/api/v2/account' \
-H 'x-sideshift-secret: YOUR_ACCOUNT_SECRET'
```
The secret works during a migration period.
### Migrate to Signed Requests
You keep the same account and account ID. You only add a key to it.
1. [Generate a keypair](#1-generate-a-keypair).
2. Sign your **account ID** string with the new secret key. This proves you own the key. See the [proof of ownership](#managing-keys) example.
3. Register the public key with [`POST /v2/account/auth-keys`](/endpoints/v2/addaccountauthkey). Authenticate this request with your account secret:
```bash
curl -L -X POST 'https://sideshift.ai/api/v2/account/auth-keys' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-secret: YOUR_ACCOUNT_SECRET' \
-d '{
"pubKey": "PUBLIC_KEY",
"signature": "ACCOUNT_ID_SIGNED_WITH_NEW_KEY"
}'
```
4. [Sign your requests](#3-sign-each-request) with the new key and stop sending `x-sideshift-secret`.
Your secret keeps working after you register a key, so you can switch at your own pace.
# Earn Crypto Commissions
:::info
Integrators earn a default 0.5% commission on all shifts, configurable from 0% to 2% using the `commissionRate` parameter. Users of integrations shift at competitive rates; the commission is included in the exchange rate, not added on top.
:::
## Setup Requirements
To receive commissions, you must include your `Account ID` as the `affiliateId` in all shift creation requests. SideShift.ai uses this to track and attribute shifts to your integration.
## Commission Rate Examples
:::note
**Website rate** : `1 USDC → 0.981 USDT` (includes default 0.5% commission)
*Example figures for illustration only. Live quotes vary.*
:::
| `commissionRate` | Relative to website | Example user rate |
|------------------|---------------------|---------------------------|
| `0%` | **0.5% better** | `1 USDC → 0.986 USDT` |
| `0.5%` | **same** | `1 USDC → 0.981 USDT` |
| `1%` | **0.5% worse** | `1 USDC → 0.976 USDT` |
| `2%` | **1.5% worse** | `1 USDC → 0.966 USDT` |
## Commission Payouts
- **Automatic payouts**: Available once you configure your payout settings
- **Supported coins**: Receive payouts in any supported coin on our listed networks
- **Payout schedules**: Threshold-based triggers (e.g., when reaching 5,000 USD, 20,000 USD)
## Dashboard
The [dashboard](https://sideshift.ai/dashboard) gives you a dedicated place to monitor monetization performance and manage how commission payouts are handled.
### Earnings Overview
From the dashboard, you can:
- View your commission summary and earnings history
- Download CSV reports of your earned commissions
### Automatic Withdrawals
Configure automatic payout settings directly in the dashboard:
- Payout wallet address
- Preferred payout coin
- Payout amount thresholds
## Relevant Resources
- [How to withdraw XAI commissions?](https://help.sideshift.ai/en/articles/4559672-how-do-i-withdraw-my-xai-balance)
# User Permissions & Availability
SideShift.ai is not available in certain jurisdictions. Learn [more](https://help.sideshift.ai/en/articles/2874595-why-am-i-blocked-from-using-sideshift-ai).
Integrators are advised to use the [`/v2/permissions`](/endpoints/v2/permissions) endpoint to determine if the user is allowed to use SideShift.ai.
### Proxying User Requests
SideShift.ai does not allow proxying user requests. This means that the user should either directly interact with the SideShift.ai REST API, or if the API requests are sent from the integration's own server, the `x-user-ip` header must be set to the end-user's IP address.
### The x-user-ip Header
The `x-user-ip` header helps SideShift.ai identify the original source of the request, which is important for security reasons and ensuring that the service is not being used by users in restricted countries. It’s crucial that this header is set correctly by integrations to prevent any issues with using the API.
SideShift.ai reserves the right to suspend, modify, or terminate access to the SideShift.ai API or related services at any time and for any reason. This includes violations of these terms, legal requirements, or operational changes. Where practicable, we will endeavor to provide reasonable notice. By accessing or using this API, you acknowledge and agree to this policy.
# How Crypto Shifts Work
To trade with SideShift.ai, users must first create a shift. A shift can be of type fixed or variable rate.
### Fixed rate
- These shifts lock in the exchange rate for 15 minutes, including all fees. The rate is secured once the quote is created using the [`/v2/quotes`](/endpoints/v2/requestquote) endpoint. After 15 minutes, the quote and the shift expire, and any deposit made to the shift is refunded. To create a fixed-rate shift, first request a quote, then create the shift via the [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) endpoint.

### Variable rate
- These shifts don’t lock in the rate until the user makes a deposit, at which point network fees are included in the rate calculation. They remain valid for seven days and can be requested in one step using the [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoint.

:::tip
For integrations that allow their users to input an amount before creating either a fixed or variable rate shift, the [`/v2/pair`](/endpoints/v2/pair) endpoint can be used to accurately estimate the impact of [network fees](/api-intro/network-fees) on the rate for the specified pair. This can be done by setting the input amount as the optional `amount` query parameter.
When integrations are unaware of the exact amount their users will send for a variable rate shift, they can choose to present on their application either:
- `settleCoinNetworkFee`, denominated in `settle coin`
- `networkFeeUsd`, denominated in `USD`
Both represent the estimated sum of network fees that will be charged for the shift.
:::
# Deposit Mechanics & Limits
A deposit is a transaction a user makes to a shift to receive the equivalent amount in the coin they select.
## Minimum and Maximum Deposit Range
The Minimum Deposit Range has a default value of 3 USD and is determined after incorporating the network fees. The Maximum Deposit Range is always set by SideShift.ai and varies from coin to coin.
For more detailed information to help if the amount sent is outside the deposit range, please check out:
- [Under-Minimum Shift Deposit](https://help.sideshift.ai/en/articles/3735849-i-sent-below-the-minimum-amount-for-my-shift-what-can-i-do)
- [Over-Maximum Shift Deposit](https://help.sideshift.ai/en/articles/3825201-i-sent-over-the-maximum-amount-for-my-shift-what-can-i-do)
## Determining the Minimum Deposit Range
Here’s how to calculate the `Minimum Deposit Range`, assuming the network fee is 20 USD:
```
Minimum Deposit = (1 / 0.2) * network fee
Minimum Deposit = (1 / 0.2) * 20
Minimum Deposit = 100
```
In this scenario, we compare the calculated value of 100 USD to the default minimum deposit, assuming a default minimum deposit of 3 USD, to determine the `Minimum Deposit Range`. The `Minimum Deposit Range` is the higher of these two values, which in this case is 100 USD.
## Deposit status
| Status | Name | Remarks |
| ------------ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `waiting` | Waiting for deposit | No deposit detected for the shift |
| `pending` | Detected | SideShift.ai has detected the deposit and is waiting for one block confirmation for most coins and two confirmations for Litecoin, Dash, and Doge. The rate is locked in. |
| `processing` | Confirmed | The deposit has been confirmed in the blockchain and is being processed by SideShift.ai |
| `review` | Under human review | The deposit cannot be automatically processed. After human review it can be settled or refunded. |
| `settling` | Settlement in progress | SideShift.ai has created the transaction which settles the deposit and it's waiting for 1 confirmation. |
| `settled` | Settlement completed | Settlement transaction has received 1 block confirmation |
| `refund` | Queued for refund | A refund address is required. If it was not provided when the shift was created, the user can enter it at [https://sideshift.ai/orders/SHIFT_ID](https://sideshift.ai/orders/SHIFT_ID) or it can be set via the [`/v2/shifts/{shiftId}/set-refund-address`](/endpoints/v2/setrefundaddress) endpoint. |
| `refunding` | Refund in progress | Refund transaction created, waiting for 1 confirmation into the blockchain. |
| `refunded` | Refund completed | Refund transaction has received 1 block confirmation. |
| `expired` | Shift expired | The created shift has reached the end of its validity period without receiving any deposits. |
| `multiple` | Multiple deposits detected | Use the `deposits` array in the endpoint response for data about each deposit |
## Handling Multiple Deposits
### Fixed Shifts
Only the first valid deposit is settled. Any additional deposits that are received after the first deposit are refunded to the user.
### Variable Shifts
The shift can receive and process multiple deposits individually. Deposits are not merged; each one is handled based on its own specific conditions and the prevailing market rates at the time of processing.
:::note
It is not desirable for users to make multiple deposits to the same shift, and integrators should avoid encouraging this behavior.
:::
## Deposits within EVM networks
For supported EVM networks, SideShift.ai uses a deposit address, which is a smart contract for tokens, for each created shift. When a balance is detected on this contract, the system performs a sweep operation. This operation sends the funds from the deposit address to SideShift.ai's main address. The sweeper transaction is then detected as a "deposit".
:::note
For EVM networks, TRON, Aptos, Sui, NEAR, and Algorand, the `depositHash` returned in the API represents the sweep transaction hash.
:::
Occasionally, this sweeper transaction isn't broadcasted to the network, which triggers another attempt to sweep the funds from the deposit address. In this case, another deposit is created with `pending` status that will be processed, while the first deposit remains in `pending` status.
## Deposit address lifecycle
- `depositAddress` stays assigned to a shift for 60 days (40 days for EVM token deposit addresses).
- Once unassigned, the field becomes `null`, and the address can later be assigned to other shifts. Never send funds to an address from an expired shift.
- Persist the address when the shift is created and always treat it as nullable when parsing the [`/v2/shifts/{shiftId}`](/endpoints/v2/shift) and [`/v2/shifts`](/endpoints/v2/bulkshifts) responses.
## Deposit Issues
Sometimes deposits will not be automatically processed for various reasons as summarized in the table below. The `issue` field will have a value when `status` is `review` or `refund`. If `status` is `multiple` and one of the deposits are in `review` or `refund` status, this deposit object will have an `issue` field.
| Issue | Remarks | Resolution |
| -------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------- |
| `amount over max` | User sent over the maximum amount. | Processed or refund after human review |
| `amount under min` | User sent below the minimum amount. | Processed or refund after human review |
| `refund required` | The shift will be refunded after a refund address is provided | Refund after an address is provided |
| `incorrect amount` | User sent the incorrect amount for a fixed rate shift. | Processed or refund after human review |
| `order expired` | The shift has already expired when SideShift.ai detected the deposit | Processed or refund after human review |
| `max 1 deposit` | Fixed rate shifts can have maximum one deposit | Refund after an address is provided |
| `too many deposits` | More than 5 deposits have been made to a variable rate shift | Refund after an address is provided |
| `review` | Shift is under human review and will be processed or refunded | Processed or refund after human review |
| `coin unavailable` | Either the deposit or settle method is currently not available for shifts. | Refund after human review |
| `rate drift` | The rate changed too much between the time the quote was created and the deposit was detected. | Processed or refund after human review |
| `duplicate` | The deposit is a duplicate of another deposit. | Refund after human review |
| `low effective rate` | The effective rate is too low as the network fees would consume too high % of the shift value | Refund after an address is provided |
## Deposit Rejection Rules
#### Below Minimum Rejection
`Applies to:` Variable rate shifts
`Rule:` Deposits below the minimum amount might be settled if the coin for settlement has low network fees. If the network fees are high (e.g., BTC), the deposit will remain rejected.
#### Incorrect Amount Rejection
`Applies to:` Fixed rate shifts
`Rule:` Deposits with an incorrect amount will be auto-refunded if the coin for refund has low network fees and the refund address has been set. Otherwise, the refund address will be requested. If the network fees are high, the deposit will remain rejected for review. Incorrect amount deposits with a slightly different value might be settled.
# Refund Process & Policies
SideShift.ai may have to refund the user’s deposit for multiple reasons mentioned in [Deposit Issues](/api-intro/deposits#deposit-issues).
Refunds are processed automatically if a `refundAddress` is set when creating shifts. This applies to both fixed rate shifts via the [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) endpoint and variable rate shifts via the [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoint.
For coins that require a memo, the `refundMemo` is optional but can be included.

## Refund flow example
The example below shows a fixed rate shift where the user sends the wrong deposit amount. Because the integration already supplied a `refundAddress`, SideShift.ai can move from detecting the issue into the refund flow without waiting for additional user input.
```bash title="Create a fixed shift with a predefined refund destination"
curl -L -X POST 'https://sideshift.ai/api/v2/shifts/fixed' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-H 'x-user-ip: END_USER_IP_ADDRESS' \
--data-raw '{
"settleAddress": "0xF189eD5F2102402B5E8BD03936b009030f5732c7",
"refundAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"affiliateId": "ACCOUNT_AFFILIATE_ID",
"quoteId": "46a272bb-0234-4429-ac30-135dc9a92477"
}'
```
1. The integration creates the shift and stores the returned data.
2. The user sends funds to the `depositAddress`, but the amount does not match the fixed quote.
3. When SideShift.ai detects the deposit, the shift enters `refund` with an `issue` such as `incorrect amount`.
4. Because `refundAddress` is already known, SideShift.ai can create and broadcast the refund transaction without waiting for user input.
5. After the refund transaction is created and confirmed, the shift eventually progresses through `refunding` to `refunded`.
```json title="Status after the bad deposit is detected"
{
"id": "3907c0c08d9791ed1fc1",
"createdAt": "2024-05-24T23:40:35.726Z",
"depositCoin": "BNB",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x9Ee1119931c1C0C1aCF49c82E8D68532E665e066",
"settleAddress": "0xF189eD5F2102402B5E8BD03936b009030f5732c7",
"depositMin": "0.0167",
"depositMax": "0.0167",
"type": "fixed",
"quoteId": "46a272bb-0234-4429-ac30-135dc9a92477",
"depositAmount": "0.01",
"expiresAt": "2024-05-24T23:55:27.526Z",
"status": "refund",
"averageShiftSeconds": "24.435887",
"updatedAt": "2024-05-24T23:41:44.181Z",
"depositHash": "0x9b56e915677ab1bfb678d9ad6846cd724c538496cb199a4045032745f719a88a",
"depositReceivedAt": "2024-05-24T23:41:32.305Z",
"rate": "586.537938323353",
"issue": "incorrect amount"
}
```
```json title="Status after the refund is completed"
{
"id": "3907c0c08d9791ed1fc1",
"createdAt": "2024-05-24T23:40:35.726Z",
"depositCoin": "BNB",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x9Ee1119931c1C0C1aCF49c82E8D68532E665e066",
"settleAddress": "0xF189eD5F2102402B5E8BD03936b009030f5732c7",
"depositMin": "0.0167",
"depositMax": "0.0167",
"refundAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"type": "fixed",
"quoteId": "46a272bb-0234-4429-ac30-135dc9a92477",
"depositAmount": "0.01",
"expiresAt": "2024-05-24T23:55:27.526Z",
"status": "refunded",
"averageShiftSeconds": "24.435887",
"updatedAt": "2024-05-24T23:41:44.181Z",
"depositHash": "0x9b56e915677ab1bfb678d9ad6846cd724c538496cb199a4045032745f719a88a",
"settleHash": "0xccf5021fcadd7ca624ae89a2a16ba70c28f39ff3beafddb2dfaa0adcde427d4b",
"depositReceivedAt": "2024-05-24T23:41:32.305Z",
"rate": "586.537938323353"
}
```
`settleHash` contains the refund transaction hash once the refund has been broadcast and confirmed.
If a `refundAddress` was not provided when the shift was created, it can be added later with [`/v2/shifts/{shiftId}/set-refund-address`](/endpoints/v2/setrefundaddress), or the user can enter it manually at `https://sideshift.ai/orders/{shiftId}`.
Without a refund address, a shift can still move to `refund`, but it cannot progress through the refund flow until the refund destination is supplied. Integrations should treat `refund` as an actionable state and prompt the user immediately.
:::tip
Replace `{shiftId}` with the actual shift ID, for example `3907c0c08d9791ed1fc1`.
:::
# API Terminology & Key Concepts
**deposit**\[Amount\]\[Address\]\[Memo\]\[Coin\]\[Network\]\[Tx\]: Refers to data about the coin the user is shifting **from**. For example, in a shift from BTC to ETH:
- `depositCoin`: the ticker of the coin the user needs to send to SideShift.ai, or a token contract address for the selected `depositNetwork`, e.g. `btc` or `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`
- `depositNetwork`: the id of the `depositCoin` network, e.g. `bitcoin` or `mainnet`
- `depositAmount`: the amount of BTC the user needs to deposit
- `depositAddress`: the address the user needs to send the BTC to
- `depositMemo`: The memo that the user needs to include when sending to the deposit address for some coins, e.g., XRP, XLM, ATOM, and KAVA
**settle**\[Amount\]\[Address\]\[Memo\]\[Coin\]\[Network\]\[Rate\]\[Tx\]: Refers to data about the coin the user is shifting **to**. For example:
- `settleCoin`: the ticker of the coin SideShift.ai will send the user, e.g. `eth`
- `settleNetwork`: the ID of the network of the `settleCoin`, e.g. `ethereum` or `optimism`
- `settleAmount`: the amount of ETH SideShift.ai will send
- `settleRate`: the rate at which the coins are exchanged. For example, if a user sends 0.1 BTC and receives 1 ETH, the `settleRate` is 10
- `settleAddress`: The address SideShift.ai will send the ETH to
- `settleTx`: details of the transaction SideShift.ai sent to the user
- `settleMemo`: SideShift supports sending coins to addresses that require a memo on some chains, such as XRP, XLM, ATOM, KAVA, and ALGO
**auth key** (keypair): The Ed25519 keypair you generate to authenticate API requests. It is only used to sign API requests and has nothing to do with a crypto wallet. See [Authentication](/api-intro/authentication).
- **secret key**: the private half of the keypair. Keep it on your server and never send it in a request. The account page shows it as **Private Key**.
- `x-sideshift-key`: your **public** key, hex encoded. Never send your secret key here.
- `x-sideshift-signature`: the signature of `timestamp + METHOD + path + body`, made with the secret key of an auth key registered to your account. It is not a wallet or on-chain transaction signature.
- `x-sideshift-timestamp`: the Unix time in milliseconds used in the signed message.
- `x-sideshift-secret`: the legacy account secret. It still works during the migration period, but integrations should migrate to signing.
See the [`/v2/coins`](/endpoints/v2/coins) endpoint for a full list of coins and their respective networks supported by SideShift.ai.
# Shift Integration Guide
## Integrating Fixed and Variable Shifts
### Best Practices
1. Set up environment variables for sensitive data:
```env
SIDESHIFT_SECRET_KEY=your_ed25519_secret_key
SIDESHIFT_PUB_KEY=your_ed25519_public_key
AFFILIATE_ID=your_affiliate_id
API_BASE_URL=https://sideshift.ai/api/v2
```
:::warning
Never share your secret key with anyone. It grants full access to your account and should be kept secret.
:::
Sign every authenticated request with your secret key. `PUBLIC_KEY`, `TIMESTAMP` and `SIGNATURE` in the examples below are the signature headers described in [Authentication](/api-intro/authentication). Integrations with a legacy account secret should migrate to signing. `x-sideshift-secret` still works for the migration period.
2. Error handling and monitoring:
- Implement a logging system
- Monitor API response times
- Track failed requests
### Fixed Shift
**Request a Quote:** The first step is to request a quote using the [`/v2/quotes`](/endpoints/v2/requestquote) endpoint. This will provide you with a `quoteId` that you will use in the next step. Always [sign the request](/api-intro/authentication), and if the request originates from the integration's server, the end user’s IP address should be forwarded in the `x-user-ip` header.
```bash title="Example of a quote request"
curl -L -X POST 'https://sideshift.ai/api/v2/quotes' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-H 'x-user-ip: END_USER_IP_ADDRESS' \
--data-raw '{
"affiliateId": "ACCOUNT_AFFILIATE_ID",
"depositCoin": "BTC",
"depositNetwork": "bitcoin",
"settleCoin": "ETH",
"settleNetwork": "ethereum",
"depositAmount": "0.01"
}'
```
:::info
`depositCoin` can be a ticker or a token contract address.
:::
**Implementation notes:**
- Store the returned `quoteId`
- Implement quote expiration handling
- Add error handling for network issues
- Skip the fixed rate flow if [`/v2/coins`](/endpoints/v2/coins) lists the deposit network in `depositVariableOnly` or the settle network in `settleVariableOnly`
**Create a Fixed Shift**: After obtaining the `quoteId`, you can create a fixed rate shift using the [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) endpoint. The `affiliateId` used in this step must match the one used to request the quote.
```bash title="Example of creating a fixed shift"
curl -L -X POST 'https://sideshift.ai/api/v2/shifts/fixed' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-H 'x-user-ip: END_USER_IP_ADDRESS' \
--data-raw '{
"settleAddress": "SETTLE_ADDRESS",
"affiliateId": "ACCOUNT_AFFILIATE_ID",
"quoteId": "QUOTE_ID"
}'
```
**Implementation notes:**
- Validate quote hasn't expired
- Implement proper error handling
- Start status monitoring after creation
### Variable Shift
**Create a Variable Shift:** To create a variable shift, use the [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoint with the required parameters. Always [sign the request](/api-intro/authentication), and if the request originates from the integration's server, the end user’s IP address should be forwarded in the `x-user-ip` header.
```bash title="Example of creating a variable shift"
curl -L -X POST 'https://sideshift.ai/api/v2/shifts/variable' \
-H 'Content-Type: application/json' \
-H 'x-sideshift-key: PUBLIC_KEY' \
-H 'x-sideshift-timestamp: TIMESTAMP' \
-H 'x-sideshift-signature: SIGNATURE' \
-H 'x-user-ip: END_USER_IP_ADDRESS' \
--data-raw '{
"settleAddress": "SETTLE_ADDRESS",
"affiliateId": "ACCOUNT_AFFILIATE_ID",
"depositCoin": "BTC",
"depositNetwork": "bitcoin",
"settleCoin": "ETH",
"settleNetwork": "ethereum",
}'
```
**Implementation notes:**
- Display min/max deposit ranges
- Show real-time rate updates
- Implement proper error handling
- Start status monitoring
**Monitor Status:**
- Poll the shift status every few seconds using the [`/v2/shifts/{shiftId}`](/endpoints/v2/shift) endpoint
- Handle all possible status states
- Implement proper UI feedback for each status
## Key Integration Guidelines:
### User Permissions
The [`/v2/permissions`](/endpoints/v2/permissions) endpoint can be used to determine if the user is allowed to use SideShift.ai. This endpoint can be called before any shift creation.
### Deposit
For fixed rate shifts, a deposit of exactly the amount of `depositAmount` must be made before the `expiresAt` timestamp, otherwise the deposit will be refunded. For variable rate shifts, the user can send any amount within the minimum and maximum deposit ranges. The exchange rate will be determined when the user's deposit is received.
### Set Refund Address (Optional)
`refundAddress` and `refundMemo` are optional. If they aren’t defined, the user will be prompted to enter a refund address manually on the SideShift.ai order page if the shift needs to be refunded. Alternatively, the [`/v2/shifts/{shiftId}/set-refund-address`](/endpoints/v2/setrefundaddress) endpoint can be used to set the refund address if the shift has a `refund` status.
### Handle Memos (Optional)
For shifts that return a `depositMemo`, the deposit transaction must include this memo; otherwise, the deposit might be lost. For shifts settling in coins where the network is included in the `networksWithMemo` array in the [`/v2/coins`](/endpoints/v2/coins) endpoint, integrations can specify a `settleMemo` field.
### Receive Settlement
Once the deposit is confirmed in the blockchain, SideShift.ai will process the shift and send the settled amount to the `settleAddress`.
# Support & Contact Options
In case something goes wrong with the user's shift, they can receive support from SideShift.ai through the following methods:
1. **Email Support:** Users can send an email to [help@sideshift.ai](mailto:help@sideshift.ai) to receive support. To ensure a faster resolution, users should include their shift ID in the support email. The shift ID is returned when creating a shift using the [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) or [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoint. It's recommended for integrations to pre-populate the email template with the user's shift ID.
2. **Support Chat:** Users can access support by clicking on the chat icon at SideShift.ai and providing their shift ID. Similarly, integrations can leverage the SideShift.ai support chat to offer a seamless support experience to their users. It's recommended for integrations to include a link directing users to the SideShift.ai support chat. To initiate a support chat session with a pre-filled shift ID, integrations can use the following as reference: [https://sideshift.ai/orders/4c3839c16640704410b0?openSupport=true](https://sideshift.ai/orders/4c3839c16640704410b0?openSupport=true)
# API Endpoints Overview
## V2 vs V1 API
SideShift.ai strongly advises integrators to use the new V2 API version. It handles multi-network coins much more efficiently and uses easier to understand terminology. V1 API is deprecated and will not be developed further. The documentation for V1 will remain here to support already existing integrations, who are also strongly encouraged to make the switch to V2.
# List Supported Coins
Returns the list of coins and their respective networks available on SideShift.ai.
`fixedOnly`, `variableOnly`, `depositVariableOnly` and `settleVariableOnly` return `false` when no network applies, otherwise an array of the networks that do, including for single network assets. `depositOffline` and `settleOffline` follow the same pattern, except they return `true` instead of an array when the asset has a single network and that network is paused.
`depositVariableOnly` lists networks that only support variable rate shifts as a deposit. `settleVariableOnly` lists networks that only support variable rate shifts as a settle. `variableOnly` is the union of those two fields and is deprecated.
:::tip
Do not request a quote or create a fixed shift when the deposit network is in `depositVariableOnly` or the settle network is in `settleVariableOnly`. Use a variable shift instead.
:::
`tokenDetails[network].contractAddress` can be used as `depositCoin` in [`/v2/quotes`](/endpoints/v2/requestquote) and [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) when you need to target a specific token implementation on a specific network.
### 200
OK
Schema
- **networks** `string[]` *(required)*
- **coin** `string` *(required)*
- **name** `string` *(required)*
- **hasMemo** `boolean` *(required)*
- **fixedOnly** `string[] or boolean` *(required)*
- **variableOnly** `string[] or boolean` *(required)*
- **depositVariableOnly** `string[] or boolean` *(required)*
- **settleVariableOnly** `string[] or boolean` *(required)*
tokenDetails
object(s)
- **contractAddress** `string` *(required)*
- **decimals** `number` *(required)*
- **networksWithMemo** `string[]` *(required)*
- **depositOffline** `string[] or boolean`
- **settleOffline** `string[] or boolean`
# Coin Icon
Coin icon
Returns the icon of the coin in svg or png format.
The coin can be `coin-network` or if `network` is omitted, it will default to the `mainnet`. E.g `btc-bitcoin`, `btc-mainnet` or `btc` all return the BTC on chain logo. `btc-liquid` return the Liquid BTC logo.
## Request
Path Parameters
- **coin-network** `string` *(required)*
### 200
OK
Schema
- **image/svg+xml or image/png** *(required)*
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Method USDT/ripple not found",
"code": "METHOD_NOT_FOUND"
}
}
```
# Check Permissions
Permissions
Returns whether or not the user is allowed to create shifts on SideShift.ai. Learn [more](https://help.sideshift.ai/en/articles/2874595-why-am-i-blocked-from-using-sideshift-ai).
:::info
SideShift.ai does not allow proxying user requests. This means that the user should either directly interact with the SideShift.ai REST API, or if the API requests are sent from the integration's own server, the x-user-ip header must be set to the end-user IP address.
:::
## Request
Header Parameters
- **x-user-ip** `string` — end-user IP address for integrations API requests
### 200
OK
Schema
- **createShift** `boolean` *(required)*
Allowed
```json
{
"createShift": true
}
```
Restricted
```json
{
"createShift": false
}
```
# Get Swap Pair Details
Pair
Returns the minimum and maximum deposit amount and the rate for a pair of coins.
`from` and `to` can be `coin-network` or if `network` is omitted, it will default to the `mainnet`. E.g `eth-ethereum`, `eth-mainnet` or `eth` all refer to ETH on the Ethereum network. `eth-arbitrum` refers to ETH on Arbitrum network.
The rate is determined after incorporating network fees. Without specifying an `amount`, the system will assume a deposit value of `500 USD`. This can be adjusted by adding the `amount` query parameter.
Rate Example Computations
- BTC price: 30000 USD
- USDT price: 1 USD
- depositCoin: USDT
- depositNetwork: ethereum
- settleCoin: BTC
- USDT receiving fee: 10 USD
- BTC sending fee: 5 USD
- Default deposit amount: 500 USD
```
/pair/usdt-eth/btc
Without specifying the amount at the endpoint, we can calculate the rate as follows:
Rate X = ( default deposit amount - (USDT receiving fee + BTC sending fee) / default deposit amount) / BTC price
Rate X = 0.000032333333333
```
```
/pair/usdt-eth/btc?amount=10000
With a specified amount at the endpoint, such as 10000, we can calculate the rate as follows:
Rate Y = ( specified amount - (USDT receiving fee + BTC sending fee) / specified amount) / BTC price
Rate Y = 0.000033283333333
With a specified amount of 10000, the rate is higher. This is because the 15 USD combined network fee has a reduced impact on larger shifts, making it less significant in the overall cost of the 500 USD shift.
```
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
:::info
Use the same `commissionRate` in this endpoint as when creating the shift/quote to get an accurate rate information.
:::
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
Path Parameters
- **from** `string` *(required)*
- **to** `string` *(required)*
Query Parameters
- **affiliateId** `string` *(required)*
- **amount** `number`
- **commissionRate** `string`
### 200
OK
Schema
- **min** `string` *(required)*
- **max** `string` *(required)*
- **rate** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Cannot shift between the same coin network pair",
"code": "BAD_USER_INPUT"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Shift unavailable",
"code": "RATE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Invalid coin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid network",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Amount is above the maximum of 30000 USDT",
"depositRangeMax": "30000",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Amount is below the minimum of 3 USDT",
"depositRangeMin": "3",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Deposit range unavailable",
"code": "SHIFT_UNAVAILABLE"
}
}
```
# List All Swap Pairs
Pairs
Returns the minimum and maximum deposit amount and the rate for every possible pair of coins listed in the query string.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
:::info
Use the same `commissionRate` in this endpoint as when creating the shift/quote to get an accurate rate information.
:::
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
Query Parameters
- **pairs** `string` *(required)* — btc-mainnet,usdc-bsc,bch,eth
- **affiliateId** `string` *(required)*
- **commissionRate** `string`
### 200
OK
Schema
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **min** `string` *(required)*
- **max** `string` *(required)*
- **rate** `string` *(required)*
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Rate unavailable",
"code": "RATE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Duplicate coin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid coin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid network",
"code": "BAD_USER_INPUT"
}
}
```
# Get Shift Details
Shift
Returns the shift data for single shift. For bulk retrieval, use [`/v2/shifts?ids=shiftId1,shiftId2`](/endpoints/v2/bulkshifts).
For shift that has `multiple` as status, the `deposits` array in the API response holds all deposits associated with a shift.
- **Fixed Shifts**: The array will show multiple deposits, but only the first deposit is settled. Subsequent deposits are refunded.
- **Variable Shifts**: Multiple deposits are listed and processed individually according to the current market rates and conditions.
:::note
It is not desirable for users to make multiple deposits to the same shift, and integrators should avoid encouraging this behavior.
:::
`depositAddress` is unassigned from a shift after 60 days (40 days for EVM token deposit addresses). Once unassigned, the field becomes `null`, and the address may be assigned to other shifts. Persist the value when the shift is created if it needs to be shown later, and never send funds to addresses from expired shifts.
## Request
Path Parameters
- **shiftId** `string` *(required)*
### 200
OK
Fixed Shift Single Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **quoteId** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
- **externalId** `string` — integration’s own ID
- **updatedAt** `string`
- **depositHash** `string`
- **settleHash** `string`
- **depositReceivedAt** `string`
- **rate** `string` *(required)*
- **issue** `string`
Variable Shift Single Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **depositAmount** `string`
- **settleAmount** `string` — required if shift's status is settled
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
- **externalId** `string` — integration's own ID
- **updatedAt** `string`
- **depositHash** `string`
- **settleHash** `string`
- **depositReceivedAt** `string`
- **rate** `string`
- **settleCoinNetworkFee** `string`
Fixed Shift Multiple Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **quoteId** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **deposits** `array of objects` *(required)*
- **depositHash** `string` *(required)*
- **settleHash** `string`
- **depositReceivedAt** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **rate** `string`
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
Variable Shift Multiple Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **deposits** `array of objects` *(required)*
- **depositHash** `string` *(required)*
- **settleHash** `string`
- **depositReceivedAt** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **rate** `string`
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
Settled Fixed Shift
```json
{
"id": "dda3867168da23927b62",
"createdAt": "2022-06-14T11:29:11.661Z",
"depositCoin": "BTC",
"settleCoin": "BCH",
"depositNetwork": "bitcoin",
"settleNetwork": "bitcoincash",
"depositAddress": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"settleAddress": "bitcoincash:qplfzeasde8cedsd4wq5zwnlp2qwtl7j25rf69kwkr",
"depositMin": "0.0013171",
"depositMax": "0.0013171",
"refundAddress": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"type": "fixed",
"quoteId": "459abd73-71cd-40ac-b4b0-58b90386ce53",
"depositAmount": "0.0013171",
"settleAmount": "0.2293151",
"expiresAt": "2022-06-14T11:44:09.386Z",
"status": "settled",
"updatedAt": "2022-06-14T11:31:26.068Z",
"depositHash": "e23491d7125c0ed36182a12b6eddeda0bed466a2239a6bd1f8838fe30dd38a96",
"settleHash": "d1cc670a82903aaf0de38dabde519b0c1e07b123456b3e5cd0f43e9d014cd4a7",
"depositReceivedAt": "2022-06-14T11:29:29.114Z",
"rate": "174.106066357908"
}
```
Settled Variable Shift
```json
{
"id": "f173118220f1461841da",
"createdAt": "2022-06-14T10:58:44.868Z",
"depositCoin": "LTC",
"settleCoin": "BTC",
"depositNetwork": "litecoin",
"settleNetwork": "bitcoin",
"depositAddress": "MRHrYyu9H5dFXvqHcUMfY3h7Nsyt1dhR5T",
"settleAddress": "3213dAuUQB9CFK1s9vUJLSmhTxdHPSCRne",
"depositMin": "0.28164145",
"depositMax": "902.69693964",
"type": "variable",
"depositAmount": "1.34673526",
"settleAmount": "0.00256814",
"expiresAt": "2022-06-21T10:58:44.818Z",
"status": "settled",
"updatedAt": "2022-06-14T11:00:16.437Z",
"depositHash": "f3140b39b1e5ab28332ffc6108bf469907ecf4b339001179d277ac38aa08d732",
"settleHash": "4d079bdb671716563796706e383aa3d9135b123f8f238ae1e39c836fe89f87a6",
"depositReceivedAt": "2022-06-14T10:59:17.182Z",
"rate": "0.001906937522"
}
```
Refund
```json
{
"id": "3907c0c08d9791ed1fc1",
"createdAt": "2024-05-24T23:40:35.726Z",
"depositCoin": "BNB",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x9Ee1119931c1C0C1aCF49c82E8D68532E665e066",
"settleAddress": "0xF189eD5F2102402B5E8BD03936b009030f5732c7",
"depositMin": "0.0167",
"depositMax": "0.0167",
"type": "fixed",
"quoteId": "46a272bb-0234-4429-ac30-135dc9a92477",
"depositAmount": "0.01",
"expiresAt": "2024-05-24T23:55:27.526Z",
"status": "refund",
"averageShiftSeconds": "24.435887",
"updatedAt": "2024-05-24T23:41:44.181Z",
"depositHash": "0x9b56e915677ab1bfb678d9ad6846cd724c538496cb199a4045032745f719a88a",
"depositReceivedAt": "2024-05-24T23:41:32.305Z",
"rate": "586.537938323353",
"issue": "incorrect amount"
}
```
Refunded
```json
{
"id": "6821efcf996558f0053e",
"createdAt": "2023-09-28T06:23:26.609Z",
"depositCoin": "BNB",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
"settleAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"depositMin": "0.01459649",
"depositMax": "0.01459649",
"refundAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"type": "fixed",
"quoteId": "2d2d6cff-2a64-47e4-8add-8cbd368cc894",
"depositAmount": "0.01559649",
"expiresAt": "2023-09-28T06:35:02.326Z",
"status": "refunded",
"averageShiftSeconds": "59.761047",
"updatedAt": "2023-09-28T06:29:32.829Z",
"depositHash": "0x1477d3601be826e033301196d2eb6abdd16a28584805dae8bc1ced07d0444caa",
"settleHash": "0xccf5021fcadd7ca624ae89a2a16ba70c28f39ff3beafddb2dfaa0adcde427d4b",
"depositReceivedAt": "2023-09-28T06:26:14.406Z",
"rate": "205.528863445938"
}
```
Expired Fixed Shift
```json
{
"id": "890f45d6068d5340c1bd",
"createdAt": "2023-10-17T01:06:59.148Z",
"depositCoin": "BUSD",
"settleCoin": "BNB",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
"settleAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"depositMin": "3",
"depositMax": "3",
"type": "fixed",
"quoteId": "227d3cbd-15de-4581-80ac-17241b5410da",
"depositAmount": "3",
"settleAmount": "0.01370241",
"expiresAt": "2023-10-17T01:14:16.692Z",
"status": "expired",
"averageShiftSeconds": "61.12102",
"rate": "0.00456747"
}
```
Expired Variable Shift
```json
{
"id": "dbb127698bb29fb5a8cd",
"createdAt": "2024-01-31T04:07:11.664Z",
"depositCoin": "USDT",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "ethereum",
"depositAddress": "0xc1117a7BC4be7E788F16F600Dd8e223d1ED5525B",
"settleAddress": "0x7Ac93c0198bF5E28894696cF25e9581e46A6550a",
"depositMin": "31.44",
"depositMax": "40000",
"type": "variable",
"expiresAt": "2024-01-31T04:12:23.440Z",
"status": "expired",
"averageShiftSeconds": "45.815665",
"settleCoinNetworkFee": "3.0000"
}
```
Multiple
```json
{
"id": "fa2e733e13d08d323bsd",
"createdAt": "2023-10-17T08:35:58.836Z",
"depositCoin": "ETH",
"settleCoin": "BNB",
"depositNetwork": "ethereum",
"settleNetwork": "bsc",
"depositAddress": "0xf584314e9a924Cf590A62E903466A14E54a81874",
"settleAddress": "0x2b35e5bDd11c1d1F3D7e2D5a91bc3A1641de9a0c",
"depositMin": "0.001892087919",
"depositMax": "8.368070030783",
"type": "variable",
"expiresAt": "2023-10-24T08:35:58.835Z",
"status": "multiple",
"deposits": [
{
"updatedAt": "2023-10-17T08:37:38.018Z",
"depositHash": "0x21aa7c3335d5f8f0ea66830c9dbbec669218e2ebf4a52db73f7ad3cbafe3cd17",
"depositReceivedAt": "2023-10-17T08:37:36.219Z",
"depositAmount": "0.001",
"status": "pending"
},
{
"updatedAt": "2023-10-17T08:40:55.092Z",
"depositHash": "0x9be372c850f482bee08695b217af364eb7a0467b3a4955f3fd99d568da2a9A03",
"settleHash": "0x918b876f19a9c2130a2ba00c7311f460d8997cca387e3d9836d57d6dcb38d4c1",
"depositReceivedAt": "2023-10-17T08:39:41.346Z",
"depositAmount": "0.001",
"settleAmount": "0.00620308",
"rate": "6.20308",
"status": "settled"
}
],
"averageShiftSeconds": "60.882891"
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Order not found",
"code": "NOT_FOUND"
}
}
```
# Bulk Shift Lookup
Bulk shifts
Returns the shift data for every `shiftId` listed in the query string.
`depositAddress` is unassigned from a shift after 60 days (40 days for EVM token deposit addresses). Once unassigned, the field becomes `null`, and the address may be assigned to other shifts. Persist the value when the shift is created if it needs to be shown later, and never send funds to addresses from expired shifts.
## Request
Query Parameters
- **ids** `string` *(required)* — f173118220f1461841da,dda3867168da23927b62
### 200
Ok
Fixed Shift Single Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **quoteId** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
- **externalId** `string` — integration's own ID
- **updatedAt** `string`
- **depositHash** `string`
- **settleHash** `string`
- **depositReceivedAt** `string`
- **rate** `string` *(required)*
Variable Shift Single Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **depositAmount** `string`
- **settleAmount** `string` — required if shift's status is settled
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
- **externalId** `string` — integration's own ID
- **updatedAt** `string`
- **depositHash** `string`
- **settleHash** `string`
- **depositReceivedAt** `string`
- **rate** `string`
- **settleCoinNetworkFee** `string`
Fixed Shift Multiple Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **quoteId** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **deposits** `array of objects` *(required)*
- **depositHash** `string` *(required)*
- **settleHash** `string`
- **depositReceivedAt** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **rate** `string`
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
Variable Shift Multiple Deposit
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **settleAddress** `string` *(required)*
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **deposits** `array of objects` *(required)*
- **depositHash** `string` *(required)*
- **settleHash** `string`
- **depositReceivedAt** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string`
- **rate** `string`
- **status** `string` *(required)*
- **averageShiftSeconds** `string` *(required)*
```json
[
{
"id": "f173118220f1461841da",
"createdAt": "2022-06-14T10:58:44.868Z",
"depositCoin": "LTC",
"settleCoin": "BTC",
"depositNetwork": "litecoin",
"settleNetwork": "bitcoin",
"depositAddress": "MRHrYyu9H5dFXvqHcUMfY3h7Nsyt1dhR5T",
"settleAddress": "3213dAuUQB9CFK1s9vUJLSmhTxdHPSCRne",
"depositMin": "0.28164145",
"depositMax": "902.69693964",
"type": "variable",
"depositAmount": "1.34673526",
"settleAmount": "0.00256814",
"expiresAt": "2022-06-21T10:58:44.818Z",
"status": "settled",
"updatedAt": "2022-06-14T11:00:16.437Z",
"depositHash": "f3140b39b1e5ab28332ffc6108bf469907ecf4b339001179d277ac38aa08d732",
"settleHash": "4d079bdb671716563796706e383aa3d9135b123f8f238ae1e39c836fe89f87a6",
"depositReceivedAt": "2022-06-14T10:59:17.182Z",
"rate": "0.001906937522"
},
{
"id": "dbb127698bb29fb5a8cd",
"createdAt": "2024-01-31T04:07:11.664Z",
"depositCoin": "USDT",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "ethereum",
"depositAddress": "0xc1117a7BC4be7E788F16F600Dd8e223d1ED5525B",
"settleAddress": "0x7Ac93c0198bF5E28894696cF25e9581e46A6550a",
"depositMin": "31.44",
"depositMax": "40000",
"type": "variable",
"expiresAt": "2024-01-31T04:12:23.440Z",
"status": "expired",
"averageShiftSeconds": "45.815665",
"settleCoinNetworkFee": "3.0000"
},
{
"id": "dda3867168da23927b62",
"createdAt": "2022-06-14T11:29:11.661Z",
"depositCoin": "BTC",
"settleCoin": "BCH",
"depositNetwork": "bitcoin",
"settleNetwork": "bitcoincash",
"depositAddress": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"settleAddress": "bitcoincash:qplfzeasde8cedsd4wq5zwnlp2qwtl7j25rf69kwkr",
"depositMin": "0.0013171",
"depositMax": "0.0013171",
"refundAddress": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58",
"type": "fixed",
"quoteId": "459abd73-71cd-40ac-b4b0-58b90386ce53",
"depositAmount": "0.0013171",
"settleAmount": "0.2293151",
"expiresAt": "2022-06-14T11:44:09.386Z",
"status": "settled",
"updatedAt": "2022-06-14T11:31:26.068Z",
"depositHash": "e23491d7125c0ed36182a12b6eddeda0bed466a2239a6bd1f8838fe30dd38a96",
"settleHash": "d1cc670a82903aaf0de38dabde519b0c1e07b123456b3e5cd0f43e9d014cd4a7",
"depositReceivedAt": "2022-06-14T11:29:29.114Z",
"rate": "174.106066357908"
},
{
"id": "6821efcf996558f0053e",
"createdAt": "2023-09-28T06:23:26.609Z",
"depositCoin": "BNB",
"settleCoin": "USDT",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
"settleAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"depositMin": "0.01459649",
"depositMax": "0.01459649",
"refundAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"type": "fixed",
"quoteId": "2d2d6cff-2a64-47e4-8add-8cbd368cc894",
"depositAmount": "0.01559649",
"expiresAt": "2023-09-28T06:35:02.326Z",
"status": "refunded",
"averageShiftSeconds": "59.761047",
"updatedAt": "2023-09-28T06:29:32.829Z",
"depositHash": "0x1477d3601be826e033301196d2eb6abdd16a28584805dae8bc1ced07d0444caa",
"settleHash": "0xccf5021fcadd7ca624ae89a2a16ba70c28f39ff3beafddb2dfaa0adcde427d4b",
"depositReceivedAt": "2023-09-28T06:26:14.406Z",
"rate": "205.528863445938"
},
{
"id": "890f45d6068d5340c1bd",
"createdAt": "2023-10-17T01:06:59.148Z",
"depositCoin": "BUSD",
"settleCoin": "BNB",
"depositNetwork": "bsc",
"settleNetwork": "bsc",
"depositAddress": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
"settleAddress": "0xd1a8ADC8ca3a58ABbbD206Ed803EC1F13384ba3c",
"depositMin": "3",
"depositMax": "3",
"type": "fixed",
"quoteId": "227d3cbd-15de-4581-80ac-17241b5410da",
"depositAmount": "3",
"settleAmount": "0.01370241",
"expiresAt": "2023-10-17T01:14:16.692Z",
"status": "expired",
"averageShiftSeconds": "61.12102",
"rate": "0.00456747"
},
{
"id": "fa2e733e13d08d323bsd",
"createdAt": "2023-10-17T08:35:58.836Z",
"depositCoin": "ETH",
"settleCoin": "BNB",
"depositNetwork": "ethereum",
"settleNetwork": "bsc",
"depositAddress": "0xf584314e9a924Cf590A62E903466A14E54a81874",
"settleAddress": "0x2b35e5bDd11c1d1F3D7e2D5a91bc3A1641de9a0c",
"depositMin": "0.001892087919",
"depositMax": "8.368070030783",
"type": "variable",
"expiresAt": "2023-10-24T08:35:58.835Z",
"status": "multiple",
"deposits": [
{
"updatedAt": "2023-10-17T08:37:38.018Z",
"depositHash": "0x21aa7c3335d5f8f0ea66830c9dbbec669218e2ebf4a52db73f7ad3cbafe3cd17",
"depositReceivedAt": "2023-10-17T08:37:36.219Z",
"depositAmount": "0.001",
"status": "pending"
},
{
"updatedAt": "2023-10-17T08:40:55.092Z",
"depositHash": "0x9be372c850f482bee08695b217af364eb7a0467b3a4955f3fd99d568da2a9A03",
"settleHash": "0x918b876f19a9c2130a2ba00c7311f460d8997cca387e3d9836d57d6dcb38d4c1",
"depositReceivedAt": "2023-10-17T08:39:41.346Z",
"depositAmount": "0.001",
"settleAmount": "0.00620308",
"rate": "6.20308",
"status": "settled"
}
],
"averageShiftSeconds": "60.882891"
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Order not found",
"code": "NOT_FOUND"
}
}
```
# Get Recent Shifts
Recent shifts
Returns the 10 most recent completed shifts. Use query param `limit` to change the number of recent shifts returned. `limit` must be between 1-100.
:::note
To preserve users privacy, shifts involving privacy coins will return `null` for both deposit and settle amount.
:::
### 200
Schema
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleCoin** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **settleAmount** `string` *(required)*
```json
[
{
"createdAt": "2023-10-17T06:48:18.622Z",
"depositCoin": "ETH",
"depositNetwork": "ethereum",
"depositAmount": "0.12612806",
"settleCoin": "BTC",
"settleNetwork": "bitcoin",
"settleAmount": "0.00688094"
},
{
"createdAt": "2023-10-17T06:33:23.326Z",
"depositCoin": "BTC",
"depositNetwork": "bitcoin",
"depositAmount": "0.0004333",
"settleCoin": "ETH",
"settleNetwork": "ethereum",
"settleAmount": "0.00736396"
},
{
"createdAt": "2023-10-17T06:43:35.877Z",
"depositCoin": "BCH",
"depositNetwork": "bitcoincash",
"depositAmount": "1.26662368",
"settleCoin": "BTC",
"settleNetwork": "bitcoin",
"settleAmount": "0.00982187"
},
{
"createdAt": "2023-10-17T06:40:56.819Z",
"depositCoin": "ETH",
"depositNetwork": "ethereum",
"depositAmount": "0.1129051",
"settleCoin": "SHIB",
"settleNetwork": "ethereum",
"settleAmount": "24319792.76339942"
},
{
"createdAt": "2023-10-17T06:29:57.952Z",
"depositCoin": "BTC",
"depositNetwork": "lightning",
"depositAmount": "0.00177454",
"settleCoin": "TRX",
"settleNetwork": "tron",
"settleAmount": "551.217565"
},
{
"createdAt": "2023-10-17T06:30:07.816Z",
"depositCoin": "MATIC",
"depositNetwork": "polygon",
"depositAmount": "18.426196760034415",
"settleCoin": "ETH",
"settleNetwork": "ethereum",
"settleAmount": "0.00592032"
},
{
"createdAt": "2023-10-17T06:25:30.119Z",
"depositCoin": "ETH",
"depositNetwork": "ethereum",
"depositAmount": "0.0056751",
"settleCoin": "USDT",
"settleNetwork": "ethereum",
"settleAmount": "8.072691"
},
{
"createdAt": "2023-10-17T06:25:29.831Z",
"depositCoin": "SOL",
"depositNetwork": "solana",
"depositAmount": "0.32",
"settleCoin": "APT",
"settleNetwork": "aptos",
"settleAmount": "1.48814278"
},
{
"createdAt": "2023-10-17T06:21:52.261Z",
"depositCoin": "BTC",
"depositNetwork": "bitcoin",
"depositAmount": "0.025",
"settleCoin": "BCH",
"settleNetwork": "bitcoincash",
"settleAmount": "3.01195714"
},
{
"createdAt": "2023-10-17T06:16:55.375Z",
"depositCoin": "BTC",
"depositNetwork": "bitcoin",
"depositAmount": "0.0003552",
"settleCoin": "ETH",
"settleNetwork": "ethereum",
"settleAmount": "0.00601536"
}
```
# XAI Token Statistics
XAI stats
Returns the statistics about XAI coin, including it's current USD price.
### 200
OK
Schema
- **totalSupply** `number` *(required)*
- **circulatingSupply** `number` *(required)*
- **numberOfStakers** `number` *(required)*
- **latestAnnualPercentageYield** `string` *(required)*
- **latestDistributedXai** `string` *(required)*
- **totalStaked** `string` *(required)*
- **averageAnnualPercentageYield** `string` *(required)*
- **totalValueLocked** `string` *(required)*
- **totalValueLockedRatio** `string` *(required)*
- **xaiPriceUsd** `string` *(required)*
- **svxaiPriceUsd** `string` *(required)*
- **svxaiPriceXai** `string` *(required)*
```json
{
"totalSupply": 210000000,
"circulatingSupply": 126684969.93,
"numberOfStakers": 0,
"latestAnnualPercentageYield": "11.66",
"latestDistributedXai": "33862.05",
"totalStaked": "112136431.9",
"averageAnnualPercentageYield": "22.95",
"totalValueLocked": "8467726.7618521220990927948892813218",
"totalValueLockedRatio": "1.12973961970448057097",
"xaiPriceUsd": "0.07551271802",
"svxaiPriceUsd": "0.094023361214",
"svxaiPriceXai": "1.245132789276"
}
```
# Get Account Data
Account
Returns the data related to an account. To retrieve it, [sign the request](/api-intro/authentication) or send the legacy account secret in the `x-sideshift-secret` header.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
### 200
OK
Schema
- **id** `string` *(required)*
- **lifetimeStakingRewards** `string` *(required)*
- **unstaking** `string` *(required)*
- **staked** `string` *(required)*
- **available** `string` *(required)*
- **totalBalance** `string` *(required)*
```json
{
"id": "YQMi62XMb",
"lifetimeStakingRewards": "89190.63",
"unstaking": "0",
"staked": "1079394.1646",
"available": "43034.51598382",
"totalBalance": "1122428.68058382"
}
```
### 401
Unauthorized
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Account required. Sign with registered Auth key, or add x-sideshift-secret header",
"code": "SESSION_REQUIRED"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Account not found",
"code": "NOT_FOUND"
}
}
```
# Account Auth Keys
Account auth keys
Returns the auth keys registered to the authenticated account, including disabled ones.
Requires authentication: sign the request (see [Authentication](/api-intro/authentication)) or send the legacy `x-sideshift-secret` header.
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
### 200
List of auth keys
Schema
- **id** `string` *(required)*
- **pubKey** `string` *(required)*
- **type** `string` *(required)*
- **createdAt** `string` *(required)*
- **disabledAt** `string`
```json
[
{
"id": "3f9c1d2e-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
"pubKey": "033658ded9f327661cb5069122c9e0be02339d6dbe824a9d335e465030ba64b2",
"type": "ed25519",
"createdAt": "2026-10-01T09:14:11.874Z"
},
{
"id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
"pubKey": "33364ccbe5fd4099ccaf4ade80858dfe80e61a4fa4c6464ebbb4cf03c4515c8d",
"type": "ed25519",
"createdAt": "2026-06-12T11:02:45.120Z",
"disabledAt": "2026-10-01T09:20:03.511Z"
}
```
### 403
Forbidden - authentication required
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Authentication required: sign the request or send the x-sideshift-secret header",
"code": "FORBIDDEN"
}
}
```
# Create Account
Create account
Creates a new SideShift.ai account.
**Recommended:** generate an Ed25519 keypair offline and send its public key as `pubKey`. The key is registered as the account's credential and the account has no secret. Sign authenticated requests with the secret key, see [Authentication](/api-intro/authentication). The response returns `id` and `pubKey`.
Without a `pubKey`, the account gets a legacy `secret` instead, used via the `x-sideshift-secret` header. The response returns `id` and `secret`.
**Important:** A SideShift.ai account represents your integration, not an individual end user. Use one account for your entire integration and the same `id` (as `affiliateId`) across all shift requests. End users are distinguished by their `shiftId`, not by separate accounts.
The `id` can be used as `affiliateId` in shift creation requests to earn commissions.
To rotate a key, register a new one with [`POST /v2/account/auth-keys`](/endpoints/v2/addaccountauthkey) and disable the old one. You do not need a new account.
Body
- **pubKey** `string`
- **affiliate** `string`
### 201
Account successfully created
Schema
- **id** `string` *(required)*
- **pubKey** `string`
- **secret** `string`
```json
{
"id": "YQMi62XMb",
"pubKey": "033658ded9f327661cb5069122c9e0be02339d6dbe824a9d335e465030ba64b2"
}
```
```json
{
"id": "YQMi62XMb",
"secret": "YOUR_ACCOUNT_SECRET"
}
```
### 400
Bad request - invalid or already registered public key
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Public key already registered",
"code": "BAD_USER_INPUT"
}
}
```
### 429
Rate limit exceeded
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Rate limit exceeded.",
"code": "APPLICATION_ERROR"
}
}
```
### 500
Internal server error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Account creation disabled",
"code": "APPLICATION_ERROR"
}
}
```
# Add Account Auth Key
Add account auth key
Registers another Ed25519 public key for the authenticated account. Use it to rotate keys: register the new key, switch your integration to it, then disable the old key with [`DELETE /v2/account/auth-keys/{id}`](/endpoints/v2/disableaccountauthkey).
To prove you own the new key, sign your **account ID** string with the new key's secret key and send the hex signature as `signature`.
An account can have up to 5 active keys. This endpoint is rate limited to 5 requests per minute.
Requires authentication: sign the request (see [Authentication](/api-intro/authentication)) or send the legacy `x-sideshift-secret` header.
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
Body
required
- **pubKey** `string` *(required)*
- **signature** `string` *(required)*
### 201
Auth key registered
Schema
- **id** `string` *(required)*
- **pubKey** `string` *(required)*
- **type** `string` *(required)*
- **createdAt** `string` *(required)*
- **disabledAt** `string`
```json
{
"id": "3f9c1d2e-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
"pubKey": "033658ded9f327661cb5069122c9e0be02339d6dbe824a9d335e465030ba64b2",
"type": "ed25519",
"createdAt": "2026-10-01T09:14:11.874Z"
}
```
### 400
Bad request - invalid key or signature, key already registered, or active key limit reached
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Invalid signature",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Public key already registered",
"code": "BAD_USER_INPUT"
}
}
```
### 403
Forbidden - authentication required
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Authentication required: sign the request or send the x-sideshift-secret header",
"code": "FORBIDDEN"
}
}
```
### 429
Rate limit exceeded
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Rate limit exceeded.",
"code": "APPLICATION_ERROR"
}
}
```
# Request a Quote
Request quote
For fixed rate shifts, a quote should be requested first.
Some networks only support variable rate shifts. Check `depositVariableOnly` and `settleVariableOnly` on [`/v2/coins`](/endpoints/v2/coins) before requesting a quote.
A quote can be requested for either a `depositAmount` or a `settleAmount`.
When defining non-native tokens like AXS and USDT for `depositCoin` and/or `settleCoin`, the `depositNetwork` and `settleNetwork` fields must also be specified. This also applies to native tokens like ETH that supports multiple networks. `depositCoin` can also be a token contract address for the selected `depositNetwork` when you need to target a specific token implementation.
:::info
When a quote is created with a contract address in `depositCoin`, the response will normalize `depositCoin` back to the canonical asset ticker, such as `USDC`.
:::
`commissionRate` optional parameter can be used to adjust rates for your users. The default commission rate is 0.5%. Rates below the default offer better rates by reducing affiliate commission, while rates above the default are passed on to the user. The maximum commission rate is 2%.
:::info
Use the same `commissionRate` in the `/v2/pair` and `/v2/pairs` endpoints as when creating the shift/quotes to get an accurate rate information. See [Monetization](/api-intro/monetization) for detailed examples of how commission rates affect rates.
:::
If the API requests are sent from the integration’s own server, the `x-user-ip` header must be set to the end-user IP address; otherwise, the requests will be blocked. See [Permissions](/api-intro/permissions).
After the quote request, a fixed rate shift should be created using the \`id\` returned by the `/v2/quotes` endpoint.
A quote expires after **15 minutes**.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
- **x-user-ip** `string` — end-user IP address for integrations API requests
Body
- **depositCoin** `string` *(required)*
- **depositNetwork** `string`
- **settleCoin** `string` *(required)*
- **settleNetwork** `string`
- **depositAmount** `string` *(required)* — if null, settleAmount is required
- **settleAmount** `string` *(required)* — if null, depositAmount is required
- **affiliateId** `string` *(required)*
### 201
OK
Schema
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **expiresAt** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string` *(required)*
- **rate** `string` *(required)*
- **affiliateId** `string`
```json
{
"id": "c1d79240-0117-4867-afed-9cc4605c53aa",
"createdAt": "2023-10-17T03:33:21.230Z",
"depositCoin": "ETH",
"settleCoin": "ETH",
"depositNetwork": "arbitrum",
"settleNetwork": "ethereum",
"expiresAt": "2023-10-17T03:48:21.230Z",
"depositAmount": "0.14364577",
"settleAmount": "0.14078454",
"rate": "0.980081348723",
"affiliateId": "YQMi62XMb"
}
```
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Bad request",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Bad request: Invalid parameters: depositCoin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Method ETH/bitcoin not found",
"code": "METHOD_NOT_FOUND"
}
}
```
```json
{
"error": {
"message": "Invalid \"affiliateId\"",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Commission rate cannot be higher than 0.02",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid parameters: commissionRate: Must be a positive number",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Only variable orders can be created for this deposit method",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Only variable orders can be created for this settle method",
"code": "BAD_USER_INPUT"
}
}
```
### 401
Unauthorized
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Do not use the example affiliateId and x-sideshift-secret header from the documentation. Use your own from https://sideshift.ai/account",
"code": "SESSION_REQUIRED"
}
}
```
### 403
Forbidden
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Access denied. See https://sideshift.ai/access-denied",
"code": "ACCESS_DENIED"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Account not found",
"code": "NOT_FOUND"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Invalid coin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid network",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Amount too low. Settle amount is less than or equals to 0",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Amount too low. Minimum deposit amount: 0.00010663.",
"depositRangeMin": "0.00010663",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Amount too high. Maximum deposit amount: 0.5117083972",
"depositRangeMax": "0.5117083972",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Cannot specify both depositAmount and settleAmount",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Deposit method quote unavailable",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Settle method quote unavailable",
"code": "QUOTE_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Deposit method unavailable",
"code": "SHIFT_UNAVAILABLE"
}
}
```
```json
{
"error": {
"message": "Settle method unavailable",
"code": "SHIFT_UNAVAILABLE"
}
}
```
# Create Fixed-Rate Shift
Create fixed shift
After requesting a quote, use the `quoteId` to create a fixed rate shift with the quote. The `affiliateId` must match the one used to request the quote.
Do not create a fixed shift when the deposit network is in `depositVariableOnly` or the settle network is in `settleVariableOnly` on [`/v2/coins`](/endpoints/v2/coins). Use [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) instead.
For fixed rate shifts, a deposit of exactly the amount of `depositAmount` must be made before the `expiresAt` timestamp, otherwise the deposit will be refunded.
For shifts that return a `depositMemo`, the deposit transaction must include this memo, otherwise the deposit might be lost.
For shifts settling in coins where the network is included in the `networksWithMemo` array in the [`/v2/coins`](/endpoints/v2/coins) endpoint, API users are allowed to specify a `settleMemo` field, for example `"settleMemo": "123343245"`.
Authentication is required: [sign the request](/api-intro/authentication) or send the legacy `x-sideshift-secret` header, found on the [account page](https://sideshift.ai/account) under the account secret.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
`refundAddress` and `refundMemo` are optional. If they aren't defined, the user is prompted to enter a refund address manually on the SideShift.ai order page if the shift needs to be refunded.
If the API requests are sent from the integration's own server, the `x-user-ip` header must be set to the end-user IP address; otherwise, the requests will be blocked. See [Permissions](/api-intro/permissions).
`averageShiftSeconds` represents the average time in seconds it takes for SideShift to process a shift once the user's deposit is **confirmed** on the blockchain.
`externalId` is an optional field that can be used to pass an integration's own ID to the API.
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
- **x-user-ip** `string` — end-user IP address for integrations API requests
Body
- **settleAddress** `string` *(required)*
- **settleMemo** `string`
- **affiliateId** `string` *(required)* — affiliateId used to request the quote
- **quoteId** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **externalId** `string` — integration's own ID
### 201
OK
Schema
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **depositMemo** `string`
- **settleAddress** `string` *(required)*
- **settleMemo** `string`
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **quoteId** `string` *(required)*
- **depositAmount** `string` *(required)*
- **settleAmount** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string`
- **externalId** `string`
- **rate** `string` *(required)*
```json
{
"id": "8c9ba87d02a801a2f254",
"createdAt": "2023-10-17T04:32:00.855Z",
"depositCoin": "ETH",
"settleCoin": "ETH",
"depositNetwork": "arbitrum",
"settleNetwork": "ethereum",
"depositAddress": "0xa20916158958168ff5668bF90C3753EcD333b0A2",
"settleAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"depositMin": "1",
"depositMax": "1",
"refundAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"type": "fixed",
"quoteId": "75cb6e56-a81b-45a9-8ab4-1f95bf92246g",
"depositAmount": "1",
"settleAmount": "0.98088036",
"expiresAt": "2023-10-17T04:36:47.050Z",
"status": "waiting",
"averageShiftSeconds": "44.526343",
"externalId": "integration-1234"
"rate": "0.98088036"
}
```
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Bad request: Invalid parameters: quoteId",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Quote has different affiliateId than input.",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid receiving address",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid refundDestination",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid externalId",
"code": "BAD_USER_INPUT"
}
}
```
### 401
Unauthorized
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Do not use the example affiliateId and x-sideshift-secret header from the documentation. Use your own from https://sideshift.ai/account",
"code": "SESSION_REQUIRED"
}
}
```
### 403
Forbidden
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Access denied. See https://sideshift.ai/access-denied",
"code": "ACCESS_DENIED"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Account not found",
"code": "NOT_FOUND"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Quote has already been accepted. Request a new quote.",
"code": "QUOTE_ALREADY_ACCEPTED"
"orderId": "8c9ba87d02a801a2f254"
}
}
```
```json
{
"error": {
"message": "Internal Server Error",
"code": "UNKNOWN"
}
}
```
# Create Variable-Rate Shift
Create variable shift
For variable rate shifts, the settlement rate is determined when the user's deposit is received.
For shifts that return a `depositMemo`, the deposit transaction must include this memo, otherwise the deposit might be lost.
For shifts settling in coins where the network is included in the `networksWithMemo` array in the [`/v2/coins`](/endpoints/v2/coins), integrations can specify a `settleMemo` field, for example `"settleMemo": "123343245"`.
When defining non-native tokens like AXS and USDT for `depositCoin` and/or `settleCoin`, the `depositNetwork` and `settleNetwork` fields must also be specified. This also applies to native tokens like ETH that supports multiple networks. `depositCoin` can also be a token contract address for the selected `depositNetwork` when you need to target a specific token implementation.
:::info
When a shift is created with a contract address in `depositCoin`, the response will normalize `depositCoin` back to the canonical asset ticker, such as `USDC`.
:::
Authentication is required: [sign the request](/api-intro/authentication) or send the legacy `x-sideshift-secret` header, found on the [account page](https://sideshift.ai/account) under the account secret.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
`refundAddress` and `refundMemo`are optional, if not defined, user will be prompted to enter a refund address manually on the SideShift.ai order page if the shift needs to be refunded.
`commissionRate` optional parameter can be used to adjust rates for your users. The default commission rate is 0.5%. Rates below the default offer better rates by reducing affiliate commission, while rates above the default are passed on to the user. The maximum commission rate is 2%.
:::info
Use the same `commissionRate` in the `/v2/pair` and `/v2/pairs` endpoints as when creating the shift/quotes to get an accurate rate information. See [Monetization](/api-intro/monetization) for detailed examples of how commission rates affect rates.
:::
If the API requests are sent from the integration’s own server, the `x-user-ip` header must be set to the end-user IP address; otherwise, the requests will be blocked. See [Permissions](/api-intro/permissions).
`averageShiftSeconds` represents the average time in seconds it takes for SideShift to process a shift once the user’s deposit is **confirmed** on the blockchain.
`settleCoinNetworkFee` represents the estimated sum of [network fees](/api-intro/network-fees) charged for the shift denominated in settle coin.
`networkFeeUsd` represents the estimated sum of [network fees](/api-intro/network-fees) charged for the shift denominated in USD.
`externalId` is an optional field that can be used to pass an integration's own ID to the API.
## Request
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
- **x-user-ip** `string` — end-user IP address for integrations API requests
Body
- **settleAddress** `string` *(required)*
- **settleMemo** `string`
- **refundAddress** `string`
- **refundMemo** `string`
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string`
- **settleNetwork** `string`
- **affiliateId** `string` *(required)*
- **externalId** `string` — integration's own ID
### 201
OK
Schema
- **id** `string` *(required)*
- **createdAt** `string` *(required)*
- **depositCoin** `string` *(required)*
- **settleCoin** `string` *(required)*
- **depositNetwork** `string` *(required)*
- **settleNetwork** `string` *(required)*
- **depositAddress** `string` *(required)*
- **depositMemo** `string`
- **settleAddress** `string` *(required)*
- **settleMemo** `string`
- **depositMin** `string` *(required)*
- **depositMax** `string` *(required)*
- **refundAddress** `string`
- **refundMemo** `string`
- **type** `string` *(required)*
- **expiresAt** `string` *(required)*
- **status** `string` *(required)*
- **averageShiftSeconds** `string`
- **externalId** `string`
- **settleCoinNetworkFee** `string` *(required)*
- **networkFeeUsd** `string` *(required)*
```json
{
"id": "71449070046fcfee010z",
"createdAt": "2024-01-31T01:04:14.978Z",
"depositCoin": "ETH",
"settleCoin": "USDT",
"depositNetwork": "ethereum",
"settleNetwork": "ethereum",
"depositAddress": "0x44642E63D5a50e872Df2d162d02f9A259b247350",
"settleAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"depositMin": "0.021551429911",
"depositMax": "17.06368164",
"refundAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"type": "variable",
"expiresAt": "2024-02-07T01:04:14.978Z",
"status": "waiting",
"averageShiftSeconds": "45.830392",
"externalId": "integration-1234",
"settleCoinNetworkFee": "4.210057",
"networkFeeUsd": "4.21"
}
```
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Bad request: Invalid parameters: settleAddress",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Unknown affiliateId",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid externalId",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid receiving address",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid refundDestination",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "This refund address belongs to SideShift.ai",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Commission rate cannot be higher than 0.02",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid parameters: commissionRate: Must be a positive number",
"code": "BAD_USER_INPUT"
}
}
```
### 401
Unauthorized
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Do not use the example affiliateId and x-sideshift-secret header from the documentation. Use your own from https://sideshift.ai/account",
"code": "SESSION_REQUIRED"
}
}
```
### 403
Forbidden
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Access denied. See https://sideshift.ai/access-denied",
"code": "ACCESS_DENIED"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Account not found",
"code": "NOT_FOUND"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Invalid coin",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Invalid network",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Memo is not supported for this deposit coin",
"code": "BAD_USER_INPUT"
}
}
```
# Set Refund Address
Set refund address
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
## Request
Path Parameters
- **shiftId** `string` *(required)*
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
Body
- **address** `string` *(required)*
- **memo** `string` — for address that requires memo
### 201
OK
Fixed Shift
{[
{ name: "id", type: "string" },
{ name: "createdAt", type: "string" },
{ name: "depositCoin", type: "string" },
{ name: "settleCoin", type: "string" },
{ name: "depositNetwork", type: "string" },
{ name: "settleNetwork", type: "string" },
{ name: "depositAddress", type: "string" },
{ name: "depositMemo", type: "string", optional: true },
{ name: "settleAddress", type: "string" },
{ name: "settleMemo", type: "string", optional: true },
{ name: "depositMin", type: "string" },
{ name: "depositMax", type: "string" },
{ name: "refundAddress", type: "string" },
{ name: "refundMemo", type: "string", optional: true },
{ name: "type", type: "string" },
{ name: "quoteId", type: "string" },
{ name: "depositAmount", type: "string" },
{ name: "settleAmount", type: "string" },
{ name: "expiresAt", type: "string" },
{ name: "status", type: "string" },
{ name: "averageShiftSeconds", type: "string" },
{ name: "rate", type: "string" },
].map((item) => (
))}
Variable Shift
{[
{ name: "id", type: "string" },
{ name: "createdAt", type: "string" },
{ name: "depositCoin", type: "string" },
{ name: "settleCoin", type: "string" },
{ name: "depositNetwork", type: "string" },
{ name: "settleNetwork", type: "string" },
{ name: "depositAddress", type: "string" },
{ name: "depositMemo", type: "string", optional: true },
{ name: "settleAddress", type: "string" },
{ name: "settleMemo", type: "string", optional: true },
{ name: "depositMin", type: "string" },
{ name: "depositMax", type: "string" },
{ name: "refundAddress", type: "string" },
{ name: "refundMemo", type: "string", optional: true },
{ name: "type", type: "string" },
{ name: "expiresAt", type: "string" },
{ name: "status", type: "string" },
{ name: "averageShiftSeconds", type: "string" },
].map((item) => (
))}
Fixed Shift
```json
{
"id": "f78df8663d4c4d5913b9",
"createdAt": "2023-10-17T05:52:43.947Z",
"depositCoin": "ETH",
"settleCoin": "ETH",
"depositNetwork": "arbitrum",
"settleNetwork": "ethereum",
"depositAddress": "0x5348DaBDBd6Ac9d2e0507447A0D2246Bb7febb0f",
"settleAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"depositMin": "1",
"depositMax": "1",
"refundAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"type": "fixed",
"quoteId": "a954ac89-d861-41f0-a082-751a80b54dff",
"depositAmount": "1",
"settleAmount": "0.98089288",
"expiresAt": "2023-10-17T06:07:33.915Z",
"status": "waiting",
"averageShiftSeconds": "44.526343",
"rate": "0.98089288"
}
```
Variable Shift
```json
{
"id": "6f7d6442bbcea03b3fs6",
"createdAt": "2023-10-17T05:36:46.797Z",
"depositCoin": "BTC",
"settleCoin": "ETH",
"depositNetwork": "bitcoin",
"settleNetwork": "ethereum",
"depositAddress": "37SELkizWCbbRgpDe5ozZDP6TvvA91a6WB",
"settleAddress": "0xde2642b2120fd3011fe9659688f76e9E4676F472",
"depositMin": "0.00010655",
"depositMax": "1.42067752",
"refundAddress": "bc1qe6duc4mztzh9jvjnqcalf65hr9579vel8mv9ya",
"type": "variable",
"expiresAt": "2023-10-24T05:36:46.796Z",
"status": "waiting",
"averageShiftSeconds": "46.880018"
}
```
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Invalid refund address",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Bad request",
"code": "BAD_USER_INPUT"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Account not found",
"code": "NOT_FOUND"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Internal Server Error",
"code": "UNKNOWN"
}
}
```
# Cancel Order
Cancel order
Cancels an existing order after 5 minutes by expiring it.
:::warning
Authenticate by [signing the request](/api-intro/authentication) or with the legacy `x-sideshift-secret` header. Your Ed25519 secret key and your account secret each grant full access to your account. Never share them.
:::
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
Body
required
- **orderId** `string` *(required)*
### 204
Order successfully cancelled
### 400
Bad Request
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Order already expired",
"code": "BAD_USER_INPUT"
}
}
```
```json
{
"error": {
"message": "Orders can only be cancelled after 5 minutes.",
"code": "BAD_USER_INPUT"
}
}
```
### 404
Not Found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Authentication required: sign the request or send the x-sideshift-secret header",
"code": "FORBIDDEN"
}
}
```
### 500
Internal Server Error
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
- **orderId** `string`
- **depositRangeMin** `string`
- **depositRangeMax** `string`
```json
{
"error": {
"message": "Internal Server Error",
"code": "UNKNOWN"
}
}
```
# Disable Account Auth Key
Disable account auth key
Disables an auth key of the authenticated account. Requests signed with a disabled key fail with `Disabled authorisation key`.
You cannot disable the last active key of an account that has no secret, because the account would be locked.
Requires authentication: sign the request (see [Authentication](/api-intro/authentication)) or send the legacy `x-sideshift-secret` header.
Path Parameters
- **id** `string` *(required)* — The auth key id, from GET /v2/account/auth-keys.
Header Parameters
- **x-sideshift-key** `string` — Your Ed25519 public key, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication).
- **x-sideshift-timestamp** `string` — Current Unix time in milliseconds, the same value used in the signed message. Must be within 60 seconds of server time. Required when signing the request.
- **x-sideshift-signature** `string` — Ed25519 signature of `timestamp + METHOD + path + body`, hex encoded. Required when signing the request. See [Authentication](/api-intro/authentication#3-sign-each-request).
- **x-sideshift-secret** `string` — Legacy account secret. Not needed when the request is signed with the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers. See [Authentication](/api-intro/authentication).
### 204
Auth key disabled
### 400
Bad request - the key is the account's only credential
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Cannot disable the only auth key of an account without a secret",
"code": "BAD_USER_INPUT"
}
}
```
### 403
Forbidden - authentication required
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Authentication required: sign the request or send the x-sideshift-secret header",
"code": "FORBIDDEN"
}
}
```
### 404
Active auth key not found
Schema
- **error** `object` *(required)*
- **code** `string` *(required)*
```json
{
"error": {
"message": "Not found",
"code": "NOT_FOUND"
}
}
```
# Fetch facts
Fetch facts, such as assets (currencies), deposit and settle methods
HTTP Status Codes:
2xx Success:
- 200: OK
# Fetch pair
Fetch current rate/price, min deposit, max deposit and the estimated network fees in USD for a pair.
`commissionRate` optional query parameter can be used to offer a better rate for your users by reducing the affiliate commission paid by SideShift.
HTTP Status Codes:
2xx Success:
- 200: OK
# Get permissions
Retrieves the permissions of the caller, indicating what actions they're allowed to take on SideShift.ai
HTTP Status Codes:
2xx Success:
- 200: OK
# Fetch order
Fetch the order data, including the deposits.
`orderId` field is deprecated, use `id` instead.
`estimatedNetworkFeeUsd` represents the estimated amount in USD SideShift.ai will charge users for shifts involving BTC, ETH or ERC20 tokens. These fees will be deducted from the `settleAmount` the user receives. This field is only present in variable orders.
`networkFeePaidUsd` represents the amount in USD SideShift.ai charged the user for network fees. This field is only present in variable orders.
HTTP Status Codes:
2xx Success:
- 200: OK
# XAI stats
Use this endpoint to get statistics about XAI coin, including its current USD price.
HTTP Status Codes:
2xx Success:
- 200: OK
# Recent deposits
Returns the 10 most recent deposits. Use query param `limit` to change the number of recent deposits returned. `limit` must be between 1-100.
:::note
To preserve users privacy, shifts involving privacy coins will return `null` for both deposit and settle amount.
:::
HTTP Status Codes:
Default:
- default
# Account
This endpoint returns data related to an account. In order to get the data, send the account secret in the `x-sideshift-secret` header.
HTTP Status Codes:
Default:
- default
# Fetch bulk pairs
Fetch current rate/price, min deposit, max deposit and the estimated network fees in USD for every possible pair from the supplied `methodIds`.
`commissionRate` optional body parameter can be used to offer a better rate for your users by reducing the affiliate commission paid by SideShift.
HTTP Status Codes:
2xx Success:
- 200: OK
# Request a quote
For fixed rate orders, a quote should be requested first.
A quote can be requested for either a `depositAmount` or a `settleAmount`.
A quote expires after 15 minutes.
After the quote request, a fixed rate order should be requested using the `id` returned by the `/quotes` endpoint
`commissionRate` optional parameter can be used to offer a better rate for your users by reducing the affiliate commission paid by SideShift.
`x-user-ip:` If the API requests are sent from the integrations own server, the `x-user-ip` header must be set to the endusers IP address. Otherwise the requests will be blocked. See "Permissions" above.
HTTP Status Codes:
2xx Success:
- 201: Created
# Create order (fixed)
After requesting a quote, use the `quoteId` to create a fixed rate order with the quote.
For fixed rate orders, a deposit of exactly the amount of `depositAmount` must be made before the `expiresAt` timestamp, otherwise the deposit will be refunded.
For coins that require `memo`, the API response will contain an additional `memo` field under `depositAddress`. The transaction must contain this `memo`, otherwise the deposit might be lost or rejected by the network.
For orders settling in coins that requires `memo`, API users are allowed to specify a `memo` field, for example `"memo": "123343245"`.
`x-sideshift-secret` header is required. It can be obtained from the [account page](https://sideshift.ai/account) under the account secret.
`affiliateId` should be defined to get a commission after the shift is complete. It can be obtained [here](https://sideshift.ai/account). Commissions are paid in SideShift.ai native XAI token, read more about XAI [here](https://help.sideshift.ai/en/collections/1793701-sideshift-token-xai-rewards).
`refundAddress` is optional, if not defined, user will be prompted to enter a refund address manually on the SideShift.ai order page if the order needs to be refunded
`orderId` field is deprecated, use `id` instead.
To create an order for XAI balance as settle method, the request should include the `sessionSecret`, `settleMethod` should be `saibal` and the `settleAddress` should be the `affiliateId`.
`x-user-ip:` If the API requests are sent from the integrations own server, the `x-user-ip` header must be set to the endusers IP address. Otherwise the requests will be blocked.
HTTP Status Codes:
2xx Success:
- 201: Created
# Create order (variable)
For variable rate orders, the settlement rate is determined when the user's payment is received.
For coins that requires `memo`, the API response will contain an additional `memo` field under `depositAddress`. The transaction must contain this `memo`, otherwise the deposit might be lost.
For orders settling in coins that requires `memo`, API users are allowed to specify a `memo` field, for example `"memo": "123343245"`.
`x-sideshift-secret` header is required. It can be obtained from the [account page](https://sideshift.ai/account) under the account secret.
`affiliateId` should be defined to get a commission after the shift is complete. It can be obtained [here](https://sideshift.ai/account). Commissions are paid in SideShift.ai native XAI token, read more about XAI [here](https://help.sideshift.ai/en/collections/1793701-sideshift-token-xai-rewards).
`refundAddress` is optional, if not defined, user will be prompted to enter a refund address manually on the SideShift.ai order page if the order needs to be refunded
`orderId` field is deprecated, use id instead.
`estimatedNetworkFeeUsd` represents the estimated amount in USD SideShift.ai will charge users for shifts involving BTC, ETH or ERC20 tokens. These fees will be deducted from the `settleAmount` the user receives. This field is only present in variable orders.
`networkFeePaidUsd` represents the amount in USD SideShift.ai charged the user for network fees. This field is only present in variable orders.
`commissionRate` optional parameter can be used to offer a better rate for your users by reducing the affiliate commission paid by SideShift. If `commissionRate` is defined, `affiliateId` must be defined as well.
To create an order for XAI balance as settle method, the request should include the `sessionSecret`, `settleMethod` should be `saibal` and the `settleAddress` should be the `affiliateId`.
`x-user-ip`: If the API requests are sent from the integrations own server, the `x-user-ip` header must be set to the endusers IP address. Otherwise the requests will be blocked.
HTTP Status Codes:
2xx Success:
- 200: Order created successfully
4xx Client Errors:
- 400: Invalid request
- 401: Unauthorized
5xx Server Errors:
- 500: Internal server error
# Set refund address
Use this endpoint to add a refund address to an already existing order. Overwriting a refund address for orders that already have one can only be done through support for security reasons.
It is also possible to include a `memo` field for XLM, XRP, LUNA and UST refund addresses.
HTTP Status Codes:
2xx Success:
- 201: Created
# Fetch bulk orders
Fetch the order data for multiple orders, including the deposits.
`orderId` field is deprecated, use `id` instead.
`estimatedNetworkFeeUsd` represents the estimated amount in USD SideShift.ai will charge users for shifts involving BTC, ETH or ERC20 tokens. These fees will be deducted from the `settleAmount` the user receives. This field is only present in variable orders.
`networkFeePaidUsd` represents the amount in USD SideShift.ai charged the user for network fees. This field is only present in variable orders.
HTTP Status Codes:
2xx Success:
- 200: OK
# API Error Codes Reference
| CODE | MESSAGE | STATUS | DESCRIPTION | SOLUTION |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| — | The x-user-ip header must be set to the end-user IP address | 400 Bad Request | Invalid IP address | Use a valid IP address in the `x-user-ip` header. |
| — | `depositAddress` missing | 200 OK | Deposit addresses are unassigned after 60 days (40 days for EVM token deposits), at which point the field is `null` and the address may be reassigned. | Persist the address when the shift is created, treat it as nullable in `/v2/shifts/{shiftId}`, `/v2/shifts`, and `/v2/bulkshifts`, and never send funds to an expired-order address. |
| ACCESS_DENIED | Access denied. See [https://sideshift.ai/access-denied](https://sideshift.ai/access-denied) | 403 Forbidden | IP address being used in the x-user-ip header is not allowed | For a list of prohibited jurisdictions, please check out [https://help.sideshift.ai/en/articles/2874595-why-am-i-blocked-from-using-sideshift-ai](https://help.sideshift.ai/en/articles/2874595-why-am-i-blocked-from-using-sideshift-ai). |
| BAD_USER_INPUT | Invalid receiving address | 400 Bad Request | settleAddress is invalid | Use the correct `settleAddress` that aligns to the `settleCoin`. In case of `BTC` as `settleCoin`, use on-chain addresses only. |
| BAD_USER_INPUT | Invalid refundDestination | 400 Bad Request | refundAddress is invalid | Use a valid `refundAddress` that aligns with the `depositCoin`. In case of `BTC` as `depositCoin`, use on-chain addresses only. |
| BAD_USER_INPUT | This refund address belongs to SideShift.ai | 400 Bad Request | refundAddress being used is the example address or owned by SideShift.ai | Use a valid `refundAddress` that you own. |
| BAD_USER_INPUT | This settle address belongs to SideShift.ai | 400 Bad Request | settleAddress being used is the example address or owned by SideShift.ai | Use a valid `settleAddress` that you own. |
| BAD_USER_INPUT | Unknown affiliateId | 400 Bad Request | Invalid affiliateId was used in variable shift | Use the `affiliateId` from your account found at [https://sideshift.ai/account](https://sideshift.ai/account). |
| BAD_USER_INPUT | Quote has different affiliateId than input | 400 Bad Request | AffiliateId used in fixed shift creation differs from the quote request | Use the same `affiliateId` for fixed shift creation as the one used in the quote request. |
| BAD_USER_INPUT | Quote has already expired. Request a new quote. | 400 Bad Request | quoteId is no longer valid for a fixed shift after expiration time | Request a new quote. |
| BAD_USER_INPUT | Invalid "affiliateId" | 400 Bad Request | Invalid affiliateId was used in the quote request | Use the `affiliateId` from your account found at [https://sideshift.ai/account](https://sideshift.ai/account). |
| BAD_USER_INPUT | depositAmount must be greater than zero | 400 Bad Request | depositAmount is 0 or less | Use a value greater than `0`. |
| BAD_USER_INPUT | Bad request: Invalid parameters: list of invalid parameters | 400 Bad Request | Invalid parameter(s) | Ensure all parameters are correctly formatted and valid |
| BAD_USER_INPUT | You have too many open orders. Cancel some, use the existing ones, or wait. To receive a higher open order limit, message [https://t.me/sideshiftai_devs](https://t.me/sideshiftai_devs) | 403 Forbidden | Executed too many order requests | Cancel some, use the existing ones, or wait. To receive a higher open order limit, message [https://t.me/sideshiftai_devs](https://t.me/sideshiftai_devs). |
| BAD_USER_INPUT | Invalid network | 500 Internal Server Error | Incorrect/missing depositNetwork or settleNetwork | Use/add correct `depositNetwork` or `settleNetwork`. See [`/v2/coins`](/endpoints/v2/coins) for a list of supported cryptocurrencies and their respective networks. |
| BAD_USER_INPUT | Invalid coin | 500 Internal Server Error | Invalid depositCoin or settleCoin | Use a supported coin for `depositCoin` and `settleCoin`. See [`/v2/coins`](/endpoints/v2/coins) for a list of supported cryptocurrencies and their respective networks. |
| BAD_USER_INPUT | Amount too low. Settle amount is less than or equals to 0 | 500 Internal Server Error | settleAmount is less than or equals to 0 | Use a higher value. |
| BAD_USER_INPUT | Memo is not supported for this settle coin | 500 Internal Server Error | settleCoin being used does not support memo | Check if the network for the `settleCoin` is included in the `networksWithMemo` array using [`/v2/coins`](/endpoints/v2/coins). |
| BAD_USER_INPUT | Memo is not supported for this deposit coin | 500 Internal Server Error | depositCoin being used does not support memo | Check if the network for the `depositCoin` is included in the `networksWithMemo` array using [`/v2/coins`](/endpoints/v2/coins). |
| BAD_USER_INPUT | Only variable orders can be created for this deposit method | 400 Bad Request | The deposit network only supports variable rate shifts | Check `depositVariableOnly` on [`/v2/coins`](/endpoints/v2/coins) and create a variable shift via [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) instead of requesting a quote. |
| BAD_USER_INPUT | Only variable orders can be created for this settle method | 400 Bad Request | The settle network only supports variable rate shifts | Check `settleVariableOnly` on [`/v2/coins`](/endpoints/v2/coins) and create a variable shift via [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) instead of requesting a quote. |
| BAD_USER_INPUT | Public key already registered | 400 Bad Request | The `pubKey` sent to `/v2/create-account` or `/v2/account/auth-keys` is already registered to an account | Generate a new keypair. Each public key can only be registered once. |
| BAD_USER_INPUT | Invalid publicKey: length should be 32, encoding hex | 400 Bad Request | `pubKey` is not a 32 byte hex encoded Ed25519 public key | Send the public key as 64 hex characters. See [Authentication](/api-intro/authentication). |
| BAD_USER_INPUT | Auth keys for account exceeded | 400 Bad Request | The account already has 5 active auth keys | Disable an unused key with [`DELETE /v2/account/auth-keys/{id}`](/endpoints/v2/disableaccountauthkey) first. |
| BAD_USER_INPUT | Invalid signature | 400 Bad Request | The `signature` sent to `/v2/account/auth-keys` is not your account ID signed with the new key | Sign your account ID string with the **new** secret key, not the key that signs the request. See [Managing Keys](/api-intro/authentication#managing-keys). |
| BAD_USER_INPUT | Invalid signature: length should be 64, encoding hex | 400 Bad Request | The `signature` sent to `/v2/account/auth-keys` is not a 64 byte hex encoded Ed25519 signature | Send the signature as 128 hex characters. |
| FORBIDDEN | Authentication required: sign the request or send the x-sideshift-secret header | 403 Forbidden | The endpoint requires an authenticated account and the request had no credentials | Sign the request, or send the legacy `x-sideshift-secret` header. See [Authentication](/api-intro/authentication). |
| INVALID_SIGNATURE | Missing authorisation headers | 401 Unauthorized | `x-sideshift-signature` was sent without `x-sideshift-key` or `x-sideshift-timestamp` | Send all three signature headers. |
| INVALID_SIGNATURE | Invalid or badly formatted timestamp | 401 Unauthorized | `x-sideshift-timestamp` is not a whole number of up to 13 digits (for example it has a decimal point, letters or spaces) | Send the Unix time in milliseconds as digits only, e.g. `Date.now().toString()`. |
| INVALID_SIGNATURE | Timestamp outside of valid 60s range | 401 Unauthorized | `x-sideshift-timestamp` is more than 60 seconds from server time, or was sent in seconds instead of milliseconds | Use milliseconds (`Date.now()`), not seconds. Sync your clock, or use the returned `serverTime` to correct your offset. Sign again on every retry. |
| INVALID_SIGNATURE | Invalid authorisation key | 401 Unauthorized | `x-sideshift-key` is not a 32 byte hex encoded public key | Send your public key as 64 hex characters. |
| INVALID_SIGNATURE | Invalid authorisation signature | 401 Unauthorized | The signature is malformed or does not match the signed message | Sign `timestamp + METHOD + path + body` with the exact body you send, and include `/api` and the query string in `path`. See [Authentication](/api-intro/authentication). |
| INVALID_SIGNATURE | Unknown authorisation key | 401 Unauthorized | `x-sideshift-key` is not registered to any account | Register the key with [`/v2/create-account`](/endpoints/v2/createaccount) or [`/v2/account/auth-keys`](/endpoints/v2/addaccountauthkey). |
| INVALID_SIGNATURE | Disabled authorisation key | 401 Unauthorized | `x-sideshift-key` was disabled | Sign with an active key. List your keys with [`/v2/account/auth-keys`](/endpoints/v2/accountauthkeys). |
| METHOD_NOT_FOUND | Method XX/XX not found | 400 Bad Request | Either the values for depositCoin and depositNetwork or settleCoin and settleNetwork do not belong to a supported method | Ensure that the coin supports the network being used, and vice versa. See [`/v2/coins`](/endpoints/v2/coins) for a list of supported cryptocurrencies and their respective networks. |
| NOT_FOUND | Account not found | 404 Not Found | x-sideshift-secret is invalid | Use your account's private key as the `x-sideshift-secret` from [https://sideshift.ai/account](https://sideshift.ai/account). |
| NOT_FOUND | Order not found | 404 Not Found | Invalid shiftId query param being used in /shift or /bulk shifts endpoint | Use a valid `shiftId(s)` as query param. |
| QUOTE_UNAVAILABLE | Amount too low. Minimum deposit amount: X | 500 Internal Server Error | depositAmount is too low | Use a higher value. See [`/v2/pair`](/endpoints/v2/pair) for the minimum deposit value. |
| QUOTE_UNAVAILABLE | Amount too high. Maximum deposit amount: X | 500 Internal Server Error | depositAmount is too high | Use a lower value. See [`/v2/pair`](/endpoints/v2/pair) for the maximum deposit value. |
| QUOTE_UNAVAILABLE | Deposit method quote unavailable | 500 Internal Server Error | Could not get a swap/route quote for the deposit side (liquidity, routing, or aggregator issue) | Try a different deposit coin/network pair, or retry later. |
| QUOTE_UNAVAILABLE | Settle method quote unavailable | 500 Internal Server Error | Could not get a swap/route quote for the settle side (liquidity, routing, or aggregator issue) | Try a different settle coin/network pair, or retry later. |
| SESSION_REQUIRED | Do not use the example affiliateId and x-sideshift-secret header from the documentation. Use your own from [https://sideshift.ai/account](https://sideshift.ai/account) | 401 Unauthorized | Example affiliateId or x-sideshift-secret was used | Use your account's actual `affiliateId` and `x-sideshift-secret` from [https://sideshift.ai/account](https://sideshift.ai/account). |
| SESSION_REQUIRED | Account required. Sign with registered Auth key, or add x-sideshift-secret header | 401 Unauthorized | [`/v2/account`](/endpoints/v2/account) was called without credentials | Sign the request with a registered auth key, or send the legacy `x-sideshift-secret` header. See [Authentication](/api-intro/authentication). |
| SHIFT_UNAVAILABLE | Deposit and settle method must be different | 500 Internal Server Error | depositCoin and depositNetwork values are similar to settleCoin and settleNetwork | Ensure that methods being used are different. |
| SHIFT_UNAVAILABLE | Deposit range unavailable | 500 Internal Server Error | The deposit range for this pair is temporarily unavailable | Try a different pair, or retry later. |
| SHIFT_UNAVAILABLE | Deposit method unavailable | 500 Internal Server Error | The deposit method is disabled, paused, or offline | Try a different deposit coin/network pair, or retry later. |
| SHIFT_UNAVAILABLE | Settle method unavailable | 500 Internal Server Error | The settle method is disabled, paused, or offline | Try a different settle coin/network pair, or retry later. |
| UNKNOWN | Internal Server Error | 500 Internal Server Error | The quoteId being used in creating fixed shift is invalid | Use a valid `quoteId` |
# Frequently Asked Questions
| Question | Answer |
| --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Do I need to create a SideShift.ai account for each of my users? | No. A single account represents your integration. Use the same `affiliateId` and credentials (your signing key, or the legacy `x-sideshift-secret`) for all shift requests across all of your users. End users are distinguished by their `shiftId`, not by separate accounts. To forward the end user's IP for compliance, use the `x-user-ip` header. |
| Do you issue API keys? | No. You generate your own Ed25519 keypair offline and register the public key with [`POST /v2/create-account`](/endpoints/v2/createaccount). Then sign each request with the secret key. SideShift only stores the public key. See [Authentication](/api-intro/authentication). |
| How do I rotate credentials? | Generate a new keypair, register it with [`POST /v2/account/auth-keys`](/endpoints/v2/addaccountauthkey), switch your integration to it, then disable the old key with [`DELETE /v2/account/auth-keys/{id}`](/endpoints/v2/disableaccountauthkey). You keep the same account and `affiliateId`. See [Managing Keys](/api-intro/authentication#managing-keys). |
| How do I create a fixed rate shift? | To create a fixed rate shift, first request a quote using the [`/v2/quotes`](/endpoints/v2/requestquote) endpoint. Then, use the `quoteId` returned by the endpoint to create a fixed rate shift using the [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) endpoint. |
| How do I create a variable rate shift? | To create a variable rate shift, use the [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoint with the required parameters, such as `settleAddress`, `affiliateId`, `depositCoin`, and `settleCoin`. |
| What is the difference between fixed rate and variable rate shifts? | Fixed rate shifts have a locked-in exchange rate for 15 minutes, while variable rate shifts determine their exchange rate when the user's deposit is received and have a 7-day expiration. |
| How should fixed rate shifts be used compared to variable shifts? | We recommend using fixed rate only when users cannot change the amount they send and for when the `settleAmount` must be exact. In situations where there is flexibility, and to reduce errors where users might send the wrong amount, we recommend opting for variable rate shifts. |
| What's the recommended integration, fixed or variable shifts? | Fixed rate shifts are the preferred option when you need users to specify the amount they send or receive before creating a shift via the API. Fixed rate shifts expire in 15 minutes, while variable rate ones expire in 7 days. |
| Would the exchange fail if we don't send the expected amount in a fixed rate conversion? | Yes, if you don’t send the exact expected amount to a fixed order, it will need to be refunded. We recommend that you set the refund address when creating a new shift just in case the deposit needs to be refunded. Wallet app integrations are advised to set the refund address to the address the users are sending the deposit coin from as this makes the refund process much smoother. |
| What are the minimum and maximum deposit ranges? | The minimum deposit range has a default value and is determined after incorporating network fees while the maximum deposit range is set by SideShift.ai and varies from coin to coin. Both ranges are denominated in USD. |
| How do I handle coins or tokens with memos? | For shifts that return a `depositMemo`, the deposit transaction must include this memo, otherwise, the deposit might be lost. For shifts settling in coins where the network is included in the `networksWithMemo` array in the [`/v2/coins`](/endpoints/v2/coins) endpoint, API users are allowed to specify a `settleMemo` field. Additionally, shifts can include optional `refundAddress` and `refundMemo`, if not defined, the user will be prompted to enter a refund address manually on the SideShift.ai order page if the shift needs to be refunded. |
| Why is `depositAddress` missing on older shifts? | `depositAddress` is unassigned from a shift after 60 days (40 days for EVM token deposit addresses). Once unassigned, the field becomes `null`, and the address may be assigned to other shifts. Persist the value when the shift is created if it needs to be shown later, and never send funds to addresses from expired shifts.
| How do I know if a coin or token is not available in other supported networks for either depositCoin or settleCoin? | The API will return an array of networks for `depositOffline`, `settleOffline`, `fixedOnly`, `depositVariableOnly`, and `settleVariableOnly` (`variableOnly` is the deprecated union of the last two). So, for example, if ethereum is currently offline for deposit and settle, the response will include `ethereum` in the `depositOffline` and `settleOffline` arrays. If a network is listed in `depositVariableOnly` or `settleVariableOnly`, request a variable shift instead of a quote / fixed shift. |
| How do I set a refund address? | To set a refund address, use the [`/v2/shifts/:shiftId/set-refund-address`](/endpoints/v2/setrefundaddress) endpoint with the required address parameter. It can also be set when creating a shift. |
| Is the shift/order ID sensitive? | Yes. The order page is reachable by ID alone, so anyone with the ID can open it and, if no `refundAddress` was set when the shift was created, choose where a refund is sent or cancel the order. Do not expose shift IDs publicly or share them with anyone other than the user the shift belongs to, and, if possible, set `refundAddress` at creation. |
| What are the reasons for refunds? | Refunds are made for various reasons, such as the user sending an incorrect amount for a fixed rate shift, the shift expiring, the user sending below the minimum amount, or above the maximum amount for a variable shift, among others. |
| If a user chooses the wrong network, do you offer refunds? If so, what are the conditions for a refund? | We will recover and refund the user for any incorrect coin and/or network deposit that we have access to the address on the network user sent. This is usually done without any fee and within 3 days. If the network fees to recover are more than the deposit value, we will not recover. |
| What happens if an amount is sent outside of the range or after the shift expires? | In both cases, shifts might be processed or refunded after human review. |
| What flow is recommended if users use a fixed rate shift and pay the incorrect balance and how will they manage to retrieve them? | For fixed orders, we recommend that integrations pre-populate the amount field in their application’s UI and prevent users from changing it. We also recommend defining the `refundAddress` in the create order request so refunds can happen automatically if anything goes wrong. Wallet app integrations should set the refund address to the address the user is sending from to make the refund process smoother. |
| What does the "multiple" status mean? | Multiple status means that a user made multiple deposits or on some occasion for EVM/Tron tokens, multiple attempts are made to sweep the user's deposit from the deposit address. For this case, there is a deposits array in the API response with details about each deposit. |
| Why is the same deposit detected multiple times? | For EVM/Tron token deposits, the sweeper transaction sometimes isn’t broadcast to the network, which triggers another attempt to sweep funds from the deposit address. As a result, the same deposit can be detected multiple times. |
| Can shifts be rejected even if they haven't expired? | There are several different reasons a variable or fixed rate shift might be rejected. Fixed rate shifts are less prone to rejection for wallets, and variable rate shifts are less prone to errors if the user can specify the amount they send. Rejected deposits will be reviewed by our operations team and either processed or refunded. |
| How do you distinguish users if there's an issue with their shifts? | For handling different users and payment disputes, users are authenticated based on the `shiftId`, not their account. |
| How can users contact support and resolve disputes if they encounter issues with their shifts? | For any disputes, users can contact support directly via email and live chat. Integrations can add a link to their app to [https://sideshift.ai/orders/SHIFT_ID?openSupport=true](https://sideshift.ai/orders/SHIFT_ID?openSupport=true) for a seamless support experience. SideShift.ai authenticates users based on the `shiftId`, not their account. |
| How can I test the transaction flow in our staging environment? | We have no testing environment for the API. You can start by using small amounts in the live API. |
| Is there an option for redirect or QR data available for clients? | The REST API returns the address (plus memo for coins that require it) where the user needs to send their deposit coin. You can use this to display a QR code on your site. If you want to redirect the user to SideShift, you can create a shift and redirect them to [https://sideshift.ai/orders/](https://sideshift.ai/orders/). |
| How do I check if a user is allowed to use SideShift.ai? | Use the [`/v2/permissions`](/endpoints/v2/permissions) endpoint to determine if the user is allowed to use SideShift.ai. |
| Can SideShift.ai share their IP's for production whitelist? | No. Our servers are using dynamic IP addresses, which change every time we restart them. |
| How do you guarantee liquidity for all the coins? | SideShift has automatic rebalancing of coin inventory balances held for user shifting. Shift orders are automatically created for liquidity providers to deposit any coin needed in exchange for a coin SideShift has a larger balance of. These shift orders are offered with above-market exchange rate to the liquidity provider so they profit from performing the coin swap. SideShift also has automatic "external trading" of some coins whereas user deposits are instantly sold on various DeFi pools and user settlements made directly from DeFi pools using smart contracts. |
| What slippage values can I expect for shifts? | The exchange rate displayed to the user for the selected coin pair is the exact rate they receive. Any fees are already included and depend on the coin pair and current market conditions, such as liquidity. The rate is the same for both fixed and variable orders; fixed orders lock in for 15 minutes for the deposit, while variable orders apply the live rate whenever the user makes a deposit. |
| What is the average shift completion speed? | The shift time is based on blockchain confirmation. The user deposit must have at least one blockchain confirmation (or two confirmations for Litecoin, Dash, and Doge) for shift to be processed and the settle coin payment sent to user in the blockchain. |
| How can I receive a commission? | SideShift.ai pays commissions to the affiliate whose `affiliateId` param is sent in the request. Make sure to create both quote and shift with the same `affiliateId`. Commissions are in SideShift.ai's native XAI token which can be withdrawn from your SideShift.ai account. We can also automatically convert it to your chosen coin when a certain threshold is reached and send it to your designated wallet address. There's no minimum or network commissions. |
| How can I withdraw my portion of the fees? Are there any minimum and network commissions? | Any fees are already included in the exchange rate displayed to the user. These fees are dynamic; however, it is necessary to remain highly competitive on rates and offer the lowest rates for many major coin pairs compared to other swap services. The default commission paid to integrators is 0.5% of the shift value. Commission rates can be adjusted from 0% to 2% using the `commissionRate` parameter, with rates above the default passed on to the user. |
| What are the minimum and maximum commission rates I can set? | Commission rates can be set from 0% to a maximum of 2%. The default commission rate is 0.5%. Rates below the default offer better rates for users by reducing affiliate commission, while rates above the default are passed on to the user. Use the `commissionRate` parameter in quote and shift creation endpoints to adjust rates. |
| What level of support can we expect from your team? | Support is available 24/7 and generally replies within minutes. Integrations can either sync the support team with their in-house team to resolve any issues that arise or forward users directly to support via help@sideshift.ai. Integrations can also enhance the user experience by providing a direct link to the SideShift.ai support chat. For seamless support, it’s recommended to include a link that initiates a chat session with a pre-filled shift ID, such as: https://sideshift.ai/orders/SHIFT_ID?openSupport=true. |
| How many blockchains and cryptocurrencies does your API support? | Currently 42 blockchains and 200+ cryptocurrencies are supported. |
| Do you support webhooks? | No — webhooks aren’t available. Poll the API instead using [`/v2/shifts/{shiftId}`](/endpoints/v2/shift). |
# Network Fee Structure
- **Sending fee**: This fee is associated with sending the `settleCoin` to your selected wallet address. It applies to BTC, ETH, EVM tokens, TRC20 tokens, ATOM, KAVA, TIA, and SEI.
- **Address fee**: This fee is required for the creation of a unique SideShift.ai deposit address for every Shift. It applies to EVM token deposits. However, currently, contracts are being reused, and no fee is being charged for this.
- **Receiving fee**: This fee is applicable to all ETH, EVM tokens, and TRC20 deposits that require a sweep transaction from the unique deposit address to process the shift.
Please note that these fees are estimated, and the actual fees may vary depending on the network conditions at the time of the transaction.
# API Rate Limits
The REST API has rate limits in place to ensure fair usage and protect the system from abuse. Rate limits are enforced per IP address. The following operations have specific rate limits:
- **Creating a Shift:** Clients can create up to 5 shifts per minute. This concerns [`/v2/shifts/fixed`](/endpoints/v2/createfixedshift) and [`/v2/shifts/variable`](/endpoints/v2/createvariableshift) endpoints.
- **Creating a Quote**: Clients can create up to 20 quotes per minute. This concerns the [`/v2/quotes`](/endpoints/v2/requestquote) endpoint.
If a client exceeds these limits, the server will respond with a status code of `429` and a message of `Rate limit exceeded`. Please ensure your application respects these rate limits to avoid disruptions in service.
:::info
If you've created 5 consecutive variable rate shifts, you'll need to wait for one to expire before creating another. Alternatively, you can manually cancel the shifts from the order page or call the [`/v2/cancel-order`](/endpoints/v2/cancelorder) endpoint.
:::
# Changelog
## [1.0.11] - 2026-10-23
### Added
- Signed request authentication. Generate an Ed25519 keypair offline, then sign each request and send the `x-sideshift-key`, `x-sideshift-timestamp` and `x-sideshift-signature` headers instead of `x-sideshift-secret`. See [Authentication](/api-intro/authentication).
- `POST /v2/create-account` accepts an optional `pubKey` in the request body. The key is registered as the account's credential, and the response returns `id` and `pubKey` instead of `secret`.
- New `GET /v2/account/auth-keys`, `POST /v2/account/auth-keys` and `DELETE /v2/account/auth-keys/{id}` endpoints to list, add and disable auth keys. Rotating a key no longer requires creating a new account.
- New `INVALID_SIGNATURE` error code (`401`) for signature authentication failures.
### Changed
- The `x-sideshift-secret` header is now the legacy authentication method. It works during a migration period. Existing integrations should register a key and switch to signed requests. See [Migrate to Signed Requests](/api-intro/authentication#migrate-to-signed-requests).
## [1.0.10] - 2026-08-26
### Added
- Introduced `depositVariableOnly` and `settleVariableOnly` on the `/v2/coins` endpoint. These fields list networks that only support variable rate shifts as a deposit or settle, using the same shape as `fixedOnly`: `false` when no network applies, otherwise an array of networks.
### Deprecated
- Marked `variableOnly` as deprecated on the `/v2/coins` endpoint. It remains the union of `depositVariableOnly` and `settleVariableOnly`. Use the split fields instead so a network that is variable only on one side is not treated as variable only on both.
## [1.0.9] - 2026-07-01
### Deprecated
- SideShift Pay and its checkout endpoints (`POST /v2/checkout` and `GET /v2/checkout/{checkoutId}`) are deprecated and their documentation has been removed. Existing integrations should migrate to the SideShift API shift endpoints directly.
## [1.0.8] - 2026-04-09
### Added
- New `POST /create-account` endpoint to programmatically create a SideShift.ai account and receive the account `id` and `secret`.
## [1.0.7] - 2026-04-03
### Deprecated
- Legacy Widget Embed is deprecated. New integrations should use the SideShift API directly. Existing widget embeds remain operational, but the embed generator is no longer available.
### Migration Path
1. Generate quotes and orders via the SideShift API.
2. Build your own integration UI and event tracking on top of API responses.
3. Use the integrations page for reference implementation patterns.
## [1.0.6] - 2026-03-31
### Added
- Added `checkoutId` to SideShift Pay webhook payloads so webhook events can be correlated directly to the originating checkout.
## [1.0.5] - 2026-01-20
### Added
- Documented error codes in v2 error responses and troubleshooting.
## [1.0.4] - 2025-08-14
### Added
- Added optional `commissionRate` parameter to `/v2/pair` and `/v2/pairs` endpoints with 0% to 2% range support.
## [1.0.3] - 2025-06-11
### Added
- New `/v2/cancel-order` endpoint to cancel an existing order by expiring it.
## [1.0.2] - 2025-05-20
### Added
- Required `affiliateId` and `x-sideshift-secret` parameters for `/pair` and `/pairs` endpoints.
## [1.0.1] - 2025-02-24
### Added
- Introduced `networksWithMemo` in the `/v2/coins` endpoint.
### Deprecated
- Marked `hasMemo` as deprecated in the `/v2/coins` endpoint.
## [1.0.0] - 2025-02-21
- First version of changelog added. For changes prior to this version, please reach out to [Developer Chat](https://t.me/joinchat/UuTn4HeK-2EUG1zZ).