Документация
Partner Exchange API
REST JSON API для встраивания обмена криптовалют в ваш сайт, бот или сервис: каталог валют → котировка → создание обмена → отслеживание статуса.
Базовый URL
https://snapex.pro/api/v1/partner
1. Обзор
Partner Exchange API позволяет проводить обмены криптовалют из вашего приложения обычными HTTP-запросами. Вы отправляете JSON — API возвращает курс, депозитный адрес и статус обмена. Этот раздел объясняет общую схему; дальше каждый шаг разобран отдельно.
Как устроен обмен
Любой обмен проходит по одной и той же схеме из четырёх шагов:
- Каталог (GET /assets). Вы узнаёте, какие валюты доступны и в каких пределах можно менять. Из каталога берутся короткие коды валют — usdt, btc, eth, xmr и т.д.
- Котировка (POST /quotes). Вы спрашиваете: «сколько получит клиент, если отправит 20 USDT в BTC?» API отвечает курсом и точными суммами. Котировка ни к чему не обязывает и действует 2 минуты.
- Создание обмена (POST /exchanges). Вы подтверждаете котировку — API создаёт заявку и возвращает депозитный адрес, на который клиент должен перевести средства.
- Статус (GET /exchanges/{quote_id}). Вы периодически опрашиваете API и узнаёте, дошёл ли депозит и отправлены ли средства клиенту.
Что нужно для начала работы
- Аккаунт в кабинете партнёра.
- Одобренная заявка на доступ к API (подаётся в кабинете, рассматривается администратором).
- API-ключ вида spx_… — выпускается в кабинете после одобрения. Ключ показывается только один раз при выпуске или перевыпуске: сразу сохраните его в надёжном месте.
Методы
| Метод | Путь | Успешный HTTP-код | Назначение |
|---|---|---|---|
| GET | /assets | 200 | Каталог валют и лимитов |
| POST | /quotes | 201 | Котировка (расчёт курса и сумм) |
| POST | /exchanges | 201 | Создание обмена, получение депозитного адреса |
| GET | /exchanges/{quote_id} | 200 | Текущий статус котировки или обмена |
Формат данных
- Все запросы и ответы — JSON в кодировке UTF-8.
- Все денежные суммы передаются строками: "20", "0.000312". Разделитель дробной части — точка. Строки используются намеренно: числа с плавающей точкой теряют точность на криптовалютных суммах.
- Даты — в формате ISO-8601 с часовым поясом, например 2026-07-27T13:02:00+00:00.
Заголовки каждого запроса
X-API-Key: spx_ваш_ключ
Content-Type: application/json (только для POST)
Accept: application/json
Ключевые правила
- Котировка действует 2 минуты (поле expires_at) — создать обмен нужно до истечения этого срока.
- Не более 1 запроса с одного IP-адреса раз в 7 секунд по всем методам; при превышении — HTTP 429 (подробнее в разделе «Ошибки и лимиты»).
- Повторный вызов создания обмена с теми же параметрами безопасен: дубль не создастся, вернётся тот же обмен.
2. Аутентификация
Каждый запрос к API должен содержать заголовок X-API-Key с вашим ключом. Никаких токенов, подписей и сессий — только этот заголовок.
GET https://snapex.pro/api/v1/partner/assets
X-API-Key: spx_ваш_ключ
Accept: application/json
Где взять ключ
Кабинет партнёра → вкладка «API» → «Выпустить ключ». Ключ начинается с spx_ и показывается один раз. При перевыпуске старый ключ немедленно перестаёт действовать.
Ошибки аутентификации
| HTTP | error | Причина | Что делать |
|---|---|---|---|
| 401 | unauthorized | Заголовок X-API-Key отсутствует или ключ неверный | Проверьте, что заголовок передаётся и ключ скопирован целиком |
| 403 | api_access_pending | Заявка на доступ ещё на рассмотрении | Дождитесь одобрения администратором |
| 403 | api_not_approved | Доступ к API не одобрен | Свяжитесь с поддержкой |
3. Каталог валют — GET /assets
Справочник доступных валют и лимитов на сумму отправки. С него начинается интеграция: отсюда берутся коды валют для котировок и границы допустимых сумм. Успешный ответ — HTTP 200.
API принимает только короткие коды из поля code этого каталога (usdt, btc, eth, xmr и т.д.). Внутренние идентификаторы блокчейнов передавать нельзя. Каталог меняется редко — его можно кешировать на своей стороне на 5–10 минут.
Пример запроса
GET https://snapex.pro/api/v1/partner/assets
X-API-Key: spx_ваш_ключ
Accept: application/json
Пример ответа
{
"assets": [
{
"code": "usdt",
"network": "TRON",
"symbol": "USDT",
"name": "USDT TRON",
"min_amount": "10",
"max_amount": "5000",
"min_usd": "10",
"max_usd": "5000"
},
{
"code": "btc",
"network": "Bitcoin",
"symbol": "BTC",
"name": "BTC",
"min_amount": "0.000085",
"max_amount": "0.0425",
"min_usd": "10",
"max_usd": "5000"
}
]
}
Поля ответа
| Поле | Описание |
|---|---|
| assets[].code | Короткий код валюты. Именно его вы передаёте в from_asset_id и to_asset_id |
| assets[].network | Блокчейн-сеть (TRON, Bitcoin, Ethereum и т.д.) |
| assets[].symbol | Тикер валюты (USDT, BTC…) |
| assets[].name | Человекочитаемое название |
| assets[].min_amount / max_amount | Минимальная и максимальная сумма отправки в единицах валюты (пересчитаны из USD-лимитов по текущему курсу) |
| assets[].min_usd / max_usd | Те же лимиты в долларах США |
Лимиты в USD по типу маршрута
Лимиты зависят от того, участвует ли в обмене Monero (XMR). Проверяется сумма отправки клиента в долларовом эквиваленте.
| Маршрут | Мин. USD | Макс. USD |
|---|---|---|
| Обычный обмен (TOKEN ↔ TOKEN) | $10 | $7000 |
| Отправка XMR (XMR → TOKEN) | $10 | $1000 |
| Получение XMR (TOKEN → XMR) | $10 | $1000 |
Актуальный каталог
Таблица ниже — те же данные, что возвращает GET /assets, для быстрой сверки.
| Код в API | Сеть | Валюта | Мин. отправка | Макс. отправка | Мин. USD | Макс. USD |
|---|---|---|---|---|---|---|
aave |
APTOS | AAVE | 0.05911913 | 41.38338753 | $10 | $7000 |
btc_aptos |
APTOS | BTC | 0.00012054 | 0.08437395 | $10 | $7000 |
doge |
APTOS | DOGE | 116.24257501 | 81369.80250387 | $10 | $7000 |
eth |
APTOS | ETH | 0.00398663 | 2.79063463 | $10 | $7000 |
link |
APTOS | LINK | 0.76569679 | 535.98774885 | $10 | $7000 |
sol |
APTOS | SOL | 0.0909091 | 63.63636364 | $10 | $7000 |
uni |
APTOS | UNI | 1.30890053 | 916.23036649 | $10 | $7000 |
xrp |
APTOS | XRP | 7.142858 | 5000 | $10 | $7000 |
zec |
APTOS | ZEC | 0.00815222 | 5.70655275 | $10 | $7000 |
avax |
Avalanche | AVAX | 0.96432016 | 675.024108 | $10 | $7000 |
cfi |
Base | CFI | 15268.57422054 | 10688001.9543775 | $10 | $7000 |
btc |
Bitcoin | BTC | 0.00012054 | 0.08437395 | $10 | $7000 |
aster |
BNB Chain | ASTER | 14.01243183 | 9808.70228066 | $10 | $7000 |
aurora |
BNB Chain | AURORA | 163.17206495 | 114220.44545974 | $10 | $7000 |
bnb |
BNB Chain | BNB | 0.01335595 | 9.34916459 | $10 | $7000 |
usdc |
HYPERCORE | USDC | 10.00325106 | 7002.27573962 | $10 | $7000 |
mon |
Monad | MON | 395.30801017 | 276715.60711602 | $10 | $7000 |
xmr |
Monero | XMR | 0.0191703 | 1.91702909 | $10 | $1000 |
op |
Optimism | OP | 70.13065341 | 49091.45738511 | $10 | $7000 |
usdt0 |
Optimism | USDT0 | 10.00953 | 7006.67035 | $10 | $7000 |
pol |
Polygon | POL | 97.83969944 | 68487.78960551 | $10 | $7000 |
rhea |
Solana | RHEA | 119.41011404 | 83587.07982566 | $10 | $7000 |
strk |
Solana | STRK | 86.68891683 | 60682.24177539 | $10 | $7000 |
zec_solana |
Solana | ZEC | 0.00815222 | 5.70655275 | $10 | $7000 |
xlm |
Stellar | XLM | 50.9325755 | 35652.8028196 | $10 | $7000 |
gram |
TON | GRAM | 6.84931507 | 4794.52054795 | $10 | $7000 |
usdt |
TRON | USDT | 10.008568 | 7005.997134 | $10 | $7000 |
okb |
X Layer | OKB | 0.07948494 | 55.63945632 | $10 | $7000 |
4. Котировка — POST /quotes
Рассчитывает курс и точные суммы обмена. Ничего не создаёт и ни к чему не обязывает: депозитный адрес не выделяется, средства не резервируются. Успешный ответ — HTTP 201. Котировка действует 2 минуты.
Два режима: side=send и side=receive
Параметр side определяет, какая из двух сумм фиксируется:
side=send — «клиент отправляет ровно X, сколько он получит?» Сумма amount указывается в валюте отправки (from).
side=receive — «клиент хочет получить ровно Y, сколько ему нужно отправить?» Сумма amount указывается в валюте получения (to).
| Режим | amount — в какой валюте | amount_usd |
|---|---|---|
| side=send | В валюте from_asset_id (сколько отправляет клиент) | Разрешён: сумма отправки в долларах вместо amount |
| side=receive | В валюте to_asset_id (сколько получает клиент) | Запрещён — только amount |
Передавайте либо amount, либо amount_usd — что-то одно. Оба сразу — ошибка 422.
Пример запроса
POST https://snapex.pro/api/v1/partner/quotes
Content-Type: application/json
X-API-Key: spx_ваш_ключ
{
"from_asset_id": "usdt",
"to_asset_id": "btc",
"side": "send",
"amount": "20",
"recipient_address": "bc1qexampleaddress"
}
Параметры запроса
| Поле | Обязательно | Описание |
|---|---|---|
| from_asset_id | Да | Код валюты, которую отдаёт клиент (из каталога GET /assets) |
| to_asset_id | Да | Код валюты, которую получает клиент. Должен отличаться от from_asset_id |
| side | Да | send или receive — см. таблицу выше |
| amount | Да, если нет amount_usd | Сумма строкой, например "20" или "0.0005". При send — в валюте from, при receive — в валюте to |
| amount_usd | Нет | Только при side=send: сумма отправки в долларах, например "100". Взаимоисключим с amount |
| recipient_address | Да | Адрес кошелька клиента в сети валюты получения (to). Нужен уже на этапе котировки — по нему проверяется корректность маршрута. Допустим синоним recipient |
Пример ответа
{
"quote_id": "pq_abc123",
"status": "quoted",
"side": "send",
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_network": "TRON",
"to_network": "Bitcoin",
"request_amount": "20",
"send_amount": "20",
"receive_amount": "0.000312",
"amount_in_usd": "20",
"amount_out_usd": "19.85",
"expires_at": "2026-07-27T13:02:00+00:00"
}
Поля ответа
| Поле | Описание |
|---|---|
| quote_id | Идентификатор котировки (pq_…). Понадобится для создания обмена и проверки статуса |
| status | quoted — котировка активна, обмен ещё не создан |
| side | Режим фиксации суммы из запроса |
| from_symbol / to_symbol | Тикеры валют отдачи и получения |
| from_network / to_network | Сети валют |
| request_amount | Сумма из вашего запроса |
| send_amount | Сколько клиент должен отправить |
| receive_amount | Сколько клиент получит |
| amount_in_usd / amount_out_usd | Долларовая оценка сумм отправки и получения |
| request_amount_usd | Присутствует, только если в запросе был amount_usd |
| expires_at | Момент истечения котировки (ISO-8601). После него создать обмен по этому quote_id нельзя |
5. Создание обмена — POST /exchanges
Превращает котировку в реальный обмен: создаётся заявка и возвращается депозитный адрес для перевода клиента. Вызывайте до истечения котировки (2 минуты). Успешный ответ — HTTP 201.
Пример запроса
POST https://snapex.pro/api/v1/partner/exchanges
Content-Type: application/json
X-API-Key: spx_ваш_ключ
{
"quote_id": "pq_abc123",
"recipient_address": "bc1qexampleaddress"
}
Параметры запроса
| Поле | Обязательно | Описание |
|---|---|---|
| quote_id | Да | Идентификатор из ответа POST /quotes |
| recipient_address | Да | Адрес выплаты клиенту. Обычно тот же, что был в котировке. Допустим синоним recipient |
Что происходит при вызове
- API находит вашу котировку и проверяет, что она не истекла.
- Курс перепроверяется по рынку. Если за прошедшее время он ухудшился более чем на 2% относительно котировки — обмен не создаётся, возвращается 422 (просто запросите новую котировку).
- Создаётся заявка и выделяется депозитный адрес.
- В ответе приходит блок deposit — адрес и сумма, которую клиент должен перевести.
Пример ответа
{
"quote_id": "pq_abc123",
"status": "awaiting_deposit",
"side": "send",
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_network": "TRON",
"to_network": "Bitcoin",
"request_amount": "20",
"send_amount": "20",
"receive_amount": "0.000312",
"amount_in_usd": "20",
"amount_out_usd": "19.85",
"expires_at": "2026-07-27T13:02:00+00:00",
"deposit": {
"asset": "USDT",
"amount": "20",
"address": "TXyz…",
"amount_usd": "20"
},
"exchange": {
"public_id": "ex_…",
"status": "awaiting_deposit",
"recipient_address": "bc1qexampleaddress"
}
}
Новые поля по сравнению с котировкой
| Поле | Описание |
|---|---|
| status | Обычно awaiting_deposit — ждём перевод клиента. Значение quoting означает, что депозитный адрес ещё формируется: опросите статус чуть позже |
| deposit.asset | Валюта, которую должен перевести клиент |
| deposit.amount | Точная сумма перевода |
| deposit.address | Депозитный адрес — покажите его клиенту |
| deposit.amount_usd | Долларовый эквивалент (если доступен) |
| exchange.public_id | Публичный идентификатор обмена |
| exchange.status | Статус заявки (совпадает с верхнеуровневым status) |
| exchange.recipient_address | Адрес выплаты клиенту |
Повторные вызовы (идемпотентность)
Если соединение оборвалось и вы не получили ответ — просто повторите запрос с теми же quote_id и recipient_address. Дубль не создастся: API вернёт уже существующий обмен. Изменить recipient_address после создания нельзя — при попытке вернётся 422.
Возможные ошибки
- 409 quote_expired — котировка истекла (прошло больше 2 минут). Запросите новую через POST /quotes.
- 422 validation_error — невалидные параметры; попытка изменить recipient_address при повторе; либо курс сдвинулся более чем на 2% — запросите новую котировку.
- 404 not_found — quote_id не существует или принадлежит другому партнёру.
- 503 upstream_unavailable — временный сбой у поставщика ликвидности. Повторите позже с той же котировкой (если не истекла) или новой.
6. Статус — GET /exchanges/{quote_id}
Возвращает текущее состояние котировки или обмена. Формат ответа полностью совпадает с ответом создания обмена. Успешный ответ — HTTP 200. Опрашивайте не чаще раза в 7 секунд.
Пример запроса
GET https://snapex.pro/api/v1/partner/exchanges/pq_abc123
X-API-Key: spx_ваш_ключ
Accept: application/json
Значения поля status
| Значение | Что означает | Что делать |
|---|---|---|
| quoted | Есть только котировка, обмен не создан | Создать обмен до expires_at или запросить новую котировку |
| quoting | Обмен создаётся, депозитный адрес формируется | Опросить статус ещё раз через несколько секунд |
| awaiting_deposit | Ждём перевод клиента на депозитный адрес | Показать клиенту адрес и сумму из блока deposit |
| processing | Депозит получен, обмен выполняется | Ждать, продолжая опрос |
| completed | Обмен завершён, средства отправлены клиенту | Финальный статус — опрос можно прекратить |
| error | Обмен завершился ошибкой | Финальный статус. Свяжитесь с поддержкой, указав exchange.public_id |
| cancelled | Обмен отменён | Финальный статус |
| expired | Котировка истекла, обмен не был создан | Финальный статус. Запросить новую котировку |
Финальные статусы: completed, error, cancelled, expired. После них состояние не меняется — дальнейший опрос не нужен.
При status=completed в блоке exchange может появиться поле partner_api_earning_usd — ваш заработок по этой сделке в долларах.
Пример ответа
{
"quote_id": "pq_abc123",
"status": "completed",
"side": "send",
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_network": "TRON",
"to_network": "Bitcoin",
"request_amount": "20",
"send_amount": "20",
"receive_amount": "0.000312",
"amount_in_usd": "20",
"amount_out_usd": "19.85",
"expires_at": "2026-07-27T13:02:00+00:00",
"deposit": {
"asset": "USDT",
"amount": "20",
"address": "TXyz…",
"amount_usd": "20"
},
"exchange": {
"public_id": "ex_…",
"status": "completed",
"recipient_address": "bc1qexampleaddress",
"partner_api_earning_usd": "0.20"
}
}
7. Ошибки и лимиты
Все ошибки возвращаются в едином JSON-формате. Код HTTP-ответа дублирует смысл поля error — можно ориентироваться на любой из них.
{
"ok": false,
"error": "validation_error",
"message": "Человекочитаемое пояснение на английском"
}
Справочник ошибок
| HTTP | error | Причина | Что делать |
|---|---|---|---|
| 401 | unauthorized | Отсутствует или неверный X-API-Key | Проверить заголовок и ключ |
| 403 | api_access_pending | Заявка на доступ на рассмотрении | Дождаться одобрения |
| 403 | api_not_approved | Доступ к API не одобрен | Связаться с поддержкой |
| 404 | not_found | Неизвестный или чужой quote_id | Проверить идентификатор |
| 409 | quote_expired | Котировка старше 2 минут | Запросить новую котировку |
| 422 | validation_error | Невалидные параметры, нарушение лимитов или сдвиг курса > 2% | Прочитать message, исправить запрос или взять новую котировку |
| 429 | rate_limited | Превышена частота запросов | Подождать и повторить |
| 503 | upstream_unavailable | Временный сбой поставщика ликвидности | Повторить позже |
Лимиты частоты запросов
| Область | Лимит |
|---|---|
| Все методы, на один IP-адрес | 1 запрос в 7 секунд |
| POST /quotes, на партнёра | 15 запросов в минуту |
| POST /exchanges, на партнёра | 10 запросов в минуту |
| GET /assets и GET /exchanges/{quote_id}, на партнёра | 120 запросов в минуту |
8. Пример: обмен от начала до конца
Полный сценарий: клиент отдаёт 20 USDT (сеть TRON) и получает BTC на свой биткоин-адрес. Замените YOUR_KEY на ваш API-ключ.
Шаг 1. Запросить котировку
curl -sS -X POST 'https://snapex.pro/api/v1/partner/quotes' \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"from_asset_id": "usdt",
"to_asset_id": "btc",
"side": "send",
"amount": "20",
"recipient_address": "bc1qexample"
}'
В ответе придёт quote_id (pq_…) и суммы. Покажите клиенту receive_amount — столько BTC он получит. У вас 2 минуты на следующий шаг.
Шаг 2. Создать обмен
curl -sS -X POST 'https://snapex.pro/api/v1/partner/exchanges' \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"quote_id": "pq_ИЗ_ШАГА_1",
"recipient_address": "bc1qexample"
}'
В ответе появится блок deposit с адресом и суммой. Покажите клиенту deposit.address и deposit.amount — он должен перевести ровно эту сумму на этот адрес.
Шаг 3. Отслеживать статус
curl -sS 'https://snapex.pro/api/v1/partner/exchanges/pq_ИЗ_ШАГА_1' \
-H 'X-API-Key: YOUR_KEY' \
-H 'Accept: application/json'
Повторяйте запрос с паузой 7–10 секунд. Когда клиент переведёт средства, статус сменится на processing, а затем на completed — средства отправлены клиенту. Финальные статусы: completed, error, cancelled, expired.
Тот же сценарий на Python
import time
import requests
API = "https://snapex.pro/api/v1/partner"
HEADERS = {
"X-API-Key": "YOUR_KEY",
"Content-Type": "application/json",
"Accept": "application/json",
}
# Шаг 1. Котировка: клиент отправляет 20 USDT, получает BTC
quote = requests.post(f"{API}/quotes", headers=HEADERS, json={
"from_asset_id": "usdt",
"to_asset_id": "btc",
"side": "send",
"amount": "20",
"recipient_address": "bc1qexample",
}).json()
print("Клиент получит:", quote["receive_amount"], quote["to_symbol"])
# Шаг 2. Создание обмена (в течение 2 минут после котировки)
exchange = requests.post(f"{API}/exchanges", headers=HEADERS, json={
"quote_id": quote["quote_id"],
"recipient_address": "bc1qexample",
}).json()
deposit = exchange["deposit"]
print("Клиент должен перевести:", deposit["amount"], deposit["asset"])
print("На адрес:", deposit["address"])
# Шаг 3. Опрос статуса до финального
while True:
time.sleep(10) # не чаще 1 запроса в 7 секунд
state = requests.get(
f"{API}/exchanges/{quote['quote_id']}", headers=HEADERS
).json()
print("Статус:", state["status"])
if state["status"] in ("completed", "error", "cancelled", "expired"):
break
Частые ошибки новичков
- Сумма передана числом, а не строкой. Правильно: "amount": "20", а не "amount": 20.
- При side=receive сумма указана в валюте отправки. При receive amount — это сумма в валюте получения (to).
- Обмен создаётся спустя больше 2 минут после котировки — придёт 409 quote_expired. Запрашивайте котировку непосредственно перед созданием.
- Запросы отправляются чаще раза в 7 секунд — придёт 429. Добавьте паузу между запросами.