Перейти к содержимому
← ARGUSПродукт

Справочник API

REST-контракт программной проверки, опубликованный до запуска сервиса, чтобы вы могли изучить его прежде, чем писать под него код.

API ARGUS возвращает тот же вердикт, который отображает сайт: актуальный результат проверки по санкционным спискам, разбор экспозиции и сигналы, стоящие за оценкой, — одним объектом JSON на адрес. Он рассчитан на момент до движения средств: проверьте адрес во время платежа, действуйте по ответу и сохраните объект как аудиторскую запись.

Спецификация — сервис ещё не запущен

Эта страница — опубликованный контракт, а не работающий сервис. Базовый URL пока не обслуживает запросы, и ключи не выдаются. Она открыта уже сейчас, чтобы интеграторы могли изучить структуры до появления эндпоинтов: если что-то здесь вам не подойдёт, мы хотим услышать именно об этом. Запросите ранний доступ, и мы свяжемся с вами, когда ключи станут доступны.

Базовый URL и аутентификация

Все эндпоинты обслуживаются по HTTPS с единого базового URL и версионируются в пути. Каждый запрос обязан нести API-ключ в виде Bearer-токена; эндпоинтов без аутентификации нет.

Базовый URL
https://api.argus.example
Заголовки запроса
Authorization: Bearer <your key>
Accept: application/json

Ключи — это секреты. Отправляйте их с сервера, никогда из браузера: ключ, попавший на клиент, становится публичным в момент загрузки страницы.

Проверка адреса

GET/v1/screen/{address}

Проверяет один адрес и возвращает полный вердикт. Единственный вход — путевой параметр address: адрес EVM (0x плюс 40 шестнадцатеричных символов) или адрес TRON (T плюс 33 символа base58). Сеть выводится из формы записи: адрес EVM — это одна и та же строка во всех EVM-сетях, поэтому одна проверка покрывает их все.

Запрос — curl
curl https://api.argus.example/v1/screen/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t \
  -H "Authorization: Bearer $ARGUS_API_KEY"
Запрос — TypeScript
const address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";

const res = await fetch(`https://api.argus.example/v1/screen/${address}`, {
  headers: { Authorization: `Bearer ${process.env.ARGUS_API_KEY}` },
});

if (!res.ok) throw new Error(`Screening failed: ${res.status}`);

const verdict: ScreenResult = await res.json();

if (verdict.sanctions.hit !== null) {
  // Designated. Decisive on its own — decline before funds move.
}
Структура ответа
type Band = "clear" | "caution" | "high" | "severe";

interface SanctionsHit {
  name: string;        // the designated person or entity
  uid: number | null;  // OFAC's SDN entry id
  type: string;        // "Individual" | "Entity"
  asset: string;       // ticker OFAC recorded the address under
  programs: string[];  // e.g. ["DPRK3", "CYBER2"]
}

interface ScreenResult {
  address: string;
  network: "evm" | "tron";

  score: number | null;  // 0–100; null when no score is justified
  band: Band | null;     // clear <30 · caution <55 · high <75 · severe

  sanctions: {
    hit: SanctionsHit | null;  // null = screened and not found,
                               // never "not screened"
    publishDate: string;       // OFAC's own date, MM/DD/YYYY
    addressCount: number;      // addresses in the screened snapshot
    sourceUrl: string;
  };

  exposure: {
    label: string;  // source category, e.g. "Mixer"
    share: number;  // percentage of inbound value
    band: Band | "unknown";
  }[];

  signals: {
    title: string;
    detail: string;
    band: Band | "unknown";
  }[];

  // true while exposure and signals carry sample figures pending the
  // graph indexer; the sanctions block is live regardless
  exposureIsIllustrative: boolean;
}
Ответ — 200
{
  "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "network": "tron",
  "score": null,
  "band": null,
  "sanctions": {
    "hit": null,
    "publishDate": "08/20/2026",
    "addressCount": 961,
    "sourceUrl": "https://ofac.treasury.gov/sanctions-list-service"
  },
  "exposure": [
    { "label": "Major exchange", "share": 61.4, "band": "clear" },
    { "label": "Unattributed", "share": 12.6, "band": "unknown" }
  ],
  "signals": [
    {
      "title": "Majority of inbound value from a regulated venue",
      "detail": "61.4% · withdrawal pattern consistent with retail",
      "band": "clear"
    }
  ],
  "exposureIsIllustrative": true
}

Почему score может быть null. Составная оценка требует слоёв экспозиции, поведения и атрибуции, а они пока не запущены. Выдумать число всё равно означало бы сделать то единственное, чего инструменту проверки делать нельзя, — противоречить самому себе: "hit": null в блоке санкций рядом с придуманным "score": 94 читается как генератор случайных чисел и стоит больше доверия, чем когда-либо стоило бы пустое поле. Поэтому оценка присутствует только тогда, когда её оправдывает работающий слой: прямое внесение в список OFAC возвращает 100 и "severe", а контрагент под санкциями, найденный на расстоянии одного перехода, возвращает высокую оценку с наблюдением в signals. В остальных случаях и score, и band равны null, и ваша интеграция должна трактовать это как «оценка не выставлена», а не как «низкий риск».

Та же честность относится к sanctions.hit: null: это значит, что адрес проверили по снимку и не нашли, а publishDate рядом сообщает, по какому именно снимку. Внесение в список после этой даты здесь не отразится. Пока exposureIsIllustrative равно true, массивы экспозиции и сигналов содержат демонстрационные данные и не должны влиять на решения.

Пакетная проверка

POST/v1/screen/batch

Проверяет до 100 адресов за один запрос. Сети можно смешивать. Результаты возвращаются в порядке входных данных, а запись, не прошедшая валидацию, возвращается объектом ошибки на своём месте, а не обрушивает весь пакет: одна опечатка не должна обнулять 99 вердиктов рядом с ней.

Запрос — curl
curl -X POST https://api.argus.example/v1/screen/batch \
  -H "Authorization: Bearer $ARGUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "addresses": [
      "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
      "0xdAC17F958D2ee523a2206206994597C13D831ec7"
    ]
  }'
Ответ — 200
{
  "results": [
    { "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "…": "…" },
    {
      "error": {
        "code": "invalid_address",
        "message": "TRON address failed base58check."
      }
    }
  ]
}

Каждый адрес в пакете тарифицируется как один вызов. Пакеты более чем на 100 записей отклоняются с 400 invalid_request, а не усекаются молча.

Ошибки

Ошибки возвращаются в JSON со стабильным машиночитаемым кодом; сообщение предназначено для людей и может меняться.

Тело ошибки
{
  "error": {
    "code": "invalid_address",
    "message": "TRON address failed base58check — likely a typo."
  }
}
400invalid_address

Адрес не проходит валидацию. EVM должен соответствовать 0x плюс 40 шестнадцатеричных символов. TRON должен быть в base58 и проходить полную контрольную сумму base58check: собственное поле ввода на сайте проверяет только форму, поэтому опечатка в адресе TRON может выглядеть правдоподобно вплоть до контрольной суммы; API отклоняет её здесь, а не проверяет чужой адрес.

400invalid_request

Тело не является корректным JSON, поле addresses пусто или в пакете более 100 записей.

401unauthorized

API-ключ отсутствует, повреждён или отозван.

404not_found

Нет такого маршрута или версии. Никогда не используется для корректного адреса без истории: адрес, который никогда не совершал транзакций, — это обычный ответ 200, а не ошибка.

429rate_limited

Превышен лимит на ключ. Заголовок Retry-After сообщает, когда повторить попытку.

5xxupstream_unavailable

Источник данных сети недоступен или превысил тайм-аут. Проверка по санкционным спискам идёт по локальному снимку, поэтому деградирует последней. Повтор с нарастающей задержкой безопасен: чтения при проверке идемпотентны.

Лимиты запросов и тарификация

Доступ к API входит в тариф API на странице тарифов: $0.04 за вызов, объёмные цены от 50 000 вызовов, безлимитная пакетная проверка. Лимиты ниже — часть этой спецификации: опубликованы для изучения, как и всё остальное здесь, и будут подтверждены на запуске.

Постоянная частота10 запросов/с на ключ
Всплеск50 запросов
Размер пакета100 адресов на запрос
Тарификация1 вызов на проверенный адрес
Цена$0.04 за вызов · объёмные цены от 50 000 вызовов

Превышение лимита возвращает 429 rate_limited с заголовком Retry-After. Лимиты применяются к ключу, а не к IP.

Вебхуки

Проверка адреса один раз говорит вам о том моменте. Дальше список меняется: OFAC публикует новые внесения, и адрес, который в прошлом месяце был чист, сегодня может оказаться в списке. Вебхуки закрывают этот разрыв: когда адрес, ранее проверенный вашим ключом, появляется в более новой публикации SDN, ARGUS отправляет событие sanctions.designation на настроенный вами эндпоинт.

Полезная нагрузка вебхука
{
  "id": "evt_9f2c81d4",
  "type": "sanctions.designation",
  "createdAt": "2026-09-02T14:11:08Z",
  "data": {
    "address": "T111111111111111111111111111111111",
    "network": "tron",
    "firstScreenedAt": "2026-08-23T09:30:00Z",
    "hit": {
      "name": "EXAMPLE DESIGNATED ENTITY",
      "uid": 99999,
      "type": "Entity",
      "asset": "TRX",
      "programs": ["CYBER2"]
    },
    "listPublishDate": "09/01/2026"
  }
}

Доставки подписываются заголовком с подписью HMAC-SHA256, чтобы вы могли убедиться, что полезная нагрузка пришла от нас, и повторяются с нарастающей задержкой в течение 24 часов, пока ваш эндпоинт не вернёт 2xx. Адрес и сущность выше — заглушки: адрес не проходит base58check, а такой сущности не существует.

Ранний доступ

Ключи пока не выдаются. Если вы хотите строить интеграцию с этим API — или уже видите в нём проблему, — напишите об этом через страницу контактов в разделе «API и партнёрства». Интеграторы, изучившие спецификацию сейчас, получат ключи первыми, а изменения до запуска не стоят ничего.