👀 PairScan

API-документация PairScan

Полный справочник REST API PairScan — аутентификация, эндпоинты, лимиты, форматы ответов и примеры кода на curl и Python.

Обновлено:

PairScan предоставляет REST API для программного доступа к тем же данным, что ты видишь на сайте: результаты ежедневного скрининга, детальные метрики по парам, бэктесты, графики и события депега. API создан для торговых ботов, бэктест-пайплайнов и собственных дашбордов.

Быстрый старт

# 1. Получи ключ на странице Настройки → API-доступ (нужен тариф Personal+)
# 2. Сделай первый запрос:
curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/screen/latest

Аутентификация

Все запросы требуют API-ключа в заголовке Authorization:

Authorization: Bearer rr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Ключ генерируется на странице Настройки → API-доступ. Доступно с тарифа Personal. У каждого пользователя один ключ; перевыпуск немедленно отзывает предыдущий.

Храни ключ как пароль. Он даёт доступ к данным твоего аккаунта и расходует твою квоту. Если ключ скомпрометирован — перевыпусти его на странице настроек.

Базовый URL

https://pairscan.io/api/v1

Лимиты (rate limits)

Тариф Запросов в день
Personal 200
Pro 2000

Считаются только вычислительные эндпоинты — те, что запускают бэктест в реальном времени (/pair/{a}/{b} и /pair/{a}/{b}/chart.png). Эндпоинты, отдающие закэшированные данные (/screen/latest, /pairs, /watchlist) и метаданные (/me), не расходуют квоту.

Лимит сбрасывается в 00:00 UTC. При превышении эндпоинт возвращает 429 Too Many Requests с заголовком Retry-After. Текущий остаток квоты всегда виден через GET /me.

Коды ответов

Код Значение
200 Успех (тело — JSON, либо PNG для графиков)
400 Неверный формат тикера или параметра
401 Ключ отсутствует, неверен или отозван
403 Твой тариф ниже требуемого для этого эндпоинта
404 Пара не найдена или данных ещё нет
409 Идёт другой расчёт — повтори через секунду
429 Дневная квота исчерпана

Тело ответа при ошибке — простой текст с описанием. Тело успешного ответа — JSON (кроме графиков — image/png).


Эндпоинты

GET /me

Информация о твоём аккаунте и текущем состоянии квоты. Не расходует квоту.

Тариф: Personal+

curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/me

Ответ:

{
  "email": "[email protected]",
  "tier": "personal",
  "tier_expires_at": "2026-07-14T00:00:00+00:00",
  "is_lifetime": false,
  "quota": {
    "limit_per_day": 200,
    "used_today": 12,
    "remaining_today": 188,
    "resets_at": "2026-06-14T24:00:00Z (00:00 UTC)"
  }
}

GET /screen/latest

Последний полный скрининг — все выжившие пары с метриками и бэктестом. Отдаётся из кэша (обновляется кроном каждые 6 часов). Не расходует квоту.

Тариф: Personal+

curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/screen/latest

Ответ:

{
  "generated_at": "2026-06-14T12:00:00+00:00",
  "n_pairs_screened": 333,
  "n_survivors": 30,
  "survivors": [
    {
      "sector": "memes_majors",
      "pair": ["BONK", "FLOKI"],
      "score": 0.61,
      "metrics": {
        "position": 0.07,
        "zone": "bottom",
        "hurst": 0.32,
        "adf_pvalue": 0.0079,
        "range_width_pct": 43.2,
        "touches_low": 4,
        "touches_high": 3,
        "z_score": -1.54,
        "r_current": -1.75
      },
      "backtest": {
        "A": {"growth_pct": 62.9, "n_trades": 1, "max_drawdown_pct": 14.9},
        "B": {"growth_pct": -4.1, "n_trades": 1, "max_drawdown_pct": 3.9}
      }
    }
  ]
}

Поле survivors содержит полную структуру каждой пары как она записана в скрине. Зоны: bottom (низ диапазона — сигнал к покупке A за счёт B), top (верх), mid (середина).


GET /pairs

Компактный список выживших пар из последнего скрина — только ключевые поля. Используй для быстрого обзора кандидатов, затем запрашивай /pair/{a}/{b} для деталей. Не расходует квоту.

Тариф: Personal+

curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/pairs

Ответ:

{
  "generated_at": "2026-06-14T12:00:00+00:00",
  "count": 30,
  "pairs": [
    {
      "pair": "BONK/FLOKI",
      "a": "BONK",
      "b": "FLOKI",
      "sector": "memes_majors",
      "zone": "bottom",
      "position": 0.07,
      "score": 0.61
    }
  ]
}

GET /pair/{a}/{b}

Полный живой снимок одной пары — метрики, сигнал, оба бэктеста (со стороны A и со стороны B), статус депега каждой ноги. Запускает тот же движок, что и страница пары на сайте. Расходует 1 запрос квоты.

Тариф: Personal+

Параметры запроса:

Параметр Значения По умолчанию Описание
bt 90, 180, 360 360 Окно бэктеста в днях
curl -H "Authorization: Bearer rr_твой_ключ" \
  "https://pairscan.io/api/v1/pair/SOL/XRP?bt=360"

Ответ:

{
  "pair": "SOL/XRP",
  "base_a": "SOL",
  "base_b": "XRP",
  "asset_class_a": "crypto",
  "asset_class_b": "crypto",
  "generated_at": "2026-06-14T16:54:21+00:00",
  "passes_filter": true,
  "filter_reason": "",
  "metrics": {
    "position": 0.17,
    "zone": "bottom",
    "z_score": -0.86,
    "hurst": 0.42,
    "adf_pvalue": 0.0138,
    "trend_slope": 0.148,
    "range_width": null,
    "touches_low": 3,
    "touches_high": 3,
    "volume_a": 99534445.06,
    "volume_b": 42057718.32,
    "p5": 4.029,
    "p95": 4.404,
    "p15": null,
    "p85": null,
    "r_current": 4.054
  },
  "backtest": {
    "history_days": 360,
    "A": {"base_leg": "SOL", "growth_pct": 0.0, "n_trades": 0, "max_drawdown_pct": 0.0, "buy_hold": null},
    "B": {"base_leg": "XRP", "growth_pct": -14.6, "n_trades": 1, "max_drawdown_pct": 29.7, "buy_hold": null}
  },
  "peg": {
    "A": null,
    "B": null
  }
}

Поле peg ненулевое только для токенизированных активов (xStocks, токенизированные металлы/казначейские облигации). Для нативной крипты — null.


GET /pair/{a}/{b}/chart.png

PNG-график лог-отношения пары с процентильными полосами и отметками сделок. Тот же рендер, что на странице пары. Расходует 1 запрос квоты.

Тариф: Personal+

Параметры запроса: те же, что у /pair/{a}/{b} (bt).

curl -H "Authorization: Bearer rr_твой_ключ" \
  "https://pairscan.io/api/v1/pair/SOL/XRP/chart.png?bt=360" \
  -o sol_xrp.png

Возвращает image/png. Кэш на клиенте — 15 минут.


GET /watchlist

Список пар из твоего watchlist'а с текущим состоянием уведомлений. Чтение из БД — не расходует квоту. Удобно, чтобы бот зеркалил те же сигналы, что приходят по email/Telegram.

Тариф: Personal+

curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/watchlist

Ответ:

{
  "count": 2,
  "items": [
    {
      "pair": "SOL/XRP",
      "a": "SOL",
      "b": "XRP",
      "notify_approach": false,
      "notify_in_zone": true,
      "last_notified_state": "in_bottom",
      "created_at": "2026-06-01T10:00:00+00:00"
    }
  ]
}

GET /peg-events

Текущие активные события устойчивого депега. Тот же детектор, что управляет email-алертами: любой токенизированный тикер, который непрерывно нездоров ≥12ч при ≥6 замерах. Не расходует квоту.

Тариф: Pro

curl -H "Authorization: Bearer rr_твой_ключ" \
  https://pairscan.io/api/v1/peg-events

Ответ:

{
  "events": [
    {
      "ticker": "XAUT",
      "asset_class": "tokenized_metal",
      "first_unhealthy": "2026-06-13T08:00:00+00:00",
      "last_unhealthy": "2026-06-14T16:00:00+00:00",
      "hours_unhealthy": 32,
      "median_drift_pct": -1.8,
      "sample_count": 33,
      "reference_source": "chainlink+yfinance"
    }
  ],
  "checked_at": "2026-06-14T16:55:00+00:00"
}

Пустой массив events означает, что активных депегов нет.


Полный пример: Python

Минимальный клиент на requests, который находит пары в нижней зоне и подтягивает по ним детали:

import requests

API = "https://pairscan.io/api/v1"
KEY = "rr_твой_ключ"
HEADERS = {"Authorization": f"Bearer {KEY}"}

# 1. Берём компактный список пар (не расходует квоту)
pairs = requests.get(f"{API}/pairs", headers=HEADERS).json()

# 2. Фильтруем по нижней зоне — кандидаты на накопление
bottom = [p for p in pairs["pairs"] if p["zone"] == "bottom"]
print(f"Найдено {len(bottom)} пар в нижней зоне")

# 3. По каждой берём полный снимок (расходует по 1 запросу)
for p in bottom[:5]:
    detail = requests.get(
        f"{API}/pair/{p['a']}/{p['b']}",
        headers=HEADERS,
        params={"bt": 360},
    ).json()
    m = detail["metrics"]
    bt = detail["backtest"]["A"]
    print(
        f"{detail['pair']}: position={m['position']:.2f} "
        f"hurst={m['hurst']:.2f} adf={m['adf_pvalue']:.4f} "
        f"бэктест={bt['growth_pct']:.1f}% ({bt['n_trades']} сделок)"
    )

# 4. Проверяем остаток квоты
me = requests.get(f"{API}/me", headers=HEADERS).json()
print(f"Квота: {me['quota']['used_today']}/{me['quota']['limit_per_day']}")

Глоссарий метрик

Поле Что значит
position Положение текущего отношения в историческом диапазоне (0 = дно, 1 = потолок). < 0 или > 1 означает выход за исторические границы
zone bottom (< 0.2), top (> 0.8), mid (между)
hurst Экспонента Хёрста. < 0.5 = mean-reverting (возврат к среднему), > 0.5 = трендовость
adf_pvalue p-value теста Дики-Фуллера на стационарность. < 0.05 = статистически значимо стационарно
z_score На сколько стандартных отклонений текущее отношение отклонилось от среднего
range_width_pct Ширина исторического диапазона в процентах
touches_low / touches_high Сколько раз отношение касалось нижней / верхней границы
r_current Текущее значение лог-отношения
growth_pct Прирост количества монет за окно бэктеста (накопление, не USD)
n_trades Количество сделок в бэктесте
max_drawdown_pct Максимальная просадка в процессе

Подробное объяснение методологии, фильтров и бэктеста — на странице Методология.


API находится в активной разработке. Структура ответов может дополняться новыми полями (существующие поля стабильны). Это не финансовый совет — это аналитический инструмент.