Finance OS / API

AML Screening API

Compliance-as-a-Service: проверяйте риск любого блокчейн-адреса одним HTTP-запросом и получайте готовый обезличенный отчёт - в JSON и PDF. Движок скоринга, правила и источники данных работают на нашей стороне; вам остаётся вызвать API и применить готовый вердикт. Одна проверка возвращает единый risk_score (0-100), уровень risk_level, готовую рекомендацию recommendation, набор сигналов, факторы риска и агрегаты по сетям.

Обезличенный скоринг
Итоговый вердикт - собственный скоринг Finance OS. Факторы, сигналы и коды в ответе - это наша модель оценки; внутренние источники данных наружу не раскрываются и не влияют на структуру интеграции. Полагайтесь на стабильные поля (risk_score, risk_level, recommendation, signals.*), а не на конкретный состав factors[] - он может пополняться.

Как это работает

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

Латентность и нагрузка
На «холодном» адресе оценка выполняется по многим источникам и может занимать несколько секунд. Задавайте щедрый таймаут HTTP-клиента и вызывайте проверку вне «горячего» пути (фоновый воркер/очередь), а не в обработчике, ожидающем мгновенного ответа. Частота вызовов ограничена (лимиты раздела), поэтому держите собственный троттлинг и экспоненциальный backoff на 429.

Аутентификация и окружения

Все запросы авторизуются секретным ключом в заголовке Authorization: Bearer sk_live_... (боевой контур) или sk_test_... (sandbox). Окружение выбирается по префиксу ключа - отдельного заголовка нет. Подробнее - в разделе Authentication.

Sandbox = детерминированный синтетический отчёт
Ключи sk_test_* работают в окружении sandbox и не тарифицируются: отчёт вычисляется детерминированно по самому адресу - один и тот же адрес всегда даёт один и тот же risk_score. Удобно для написания и прогонки тестов. Реальный on-chain-скоринг выполняется только под sk_live_*.
Подключение доступа
Доступ к AML API включается администратором после подключения: выдаётся пара ключей sk_test_ / sk_live_ и активируется сервис aml. До активации любой вызов вернёт 403 B2B_ACCESS_REQUIRED. За подключением обращайтесь на admin@fin-os.io.

Тарификация

Боевая проверка платная: стоимость одного вызова списывается с вашего мастер-счёта в момент запроса. Базовая цена - 0.2 USDT за проверку; для вашей учётной записи она может быть изменена по договору, поэтому действующее значение всегда смотрите в витрине тарифа (GET /api/v1/merchant/service-pricing).

Что влияет на списание

Действующая цена aml.check_price optional
Актуальное значение отдаёт GET /api/v1/merchant/service-pricing. Индивидуальная цена по договору перекрывает базовую.
Освобождение aml.exempt optional
Учётная запись может быть освобождена от оплаты - тогда проверки бесплатны, а price в ответе равен null.
Итоговый признак aml.charged optional
Отвечает на вопрос «спишутся ли деньги за следующий боевой вызов». Опирайтесь на него, а не на цену.
Песочница sk_test_ optional
Бесплатно всегда: с мастер-счёта ничего не списывается, price равен null.
Проверки платформы optional
Обязательный скрининг поступлений и адресов вывода платформа выполняет за свой счёт - в ваш счёт эти проверки не попадают.
Это расход, а не товар optional
Цена проверки - ваши издержки на комплаенс. Надбавки у AML-проверок нет: перепродать вызов дороже, чем он стоит вам, платформа не позволяет. Зарабатываете вы на выводах клиентов.
Пустой мастер-счёт = 402
Если средств на мастер-счёте не хватает, проверка не выполняется и приходит 402 service_balance_insufficient с точной нехваткой в полях currency, required, available. Держите остаток и подпишитесь на вебхук merchant.balance.low, чтобы узнавать о снижении заранее.
Платите за результат
Списание происходит до оценки, но если вердикт не получен (сбой оценки или записи), сумма возвращается автоматически строкой возврата в леджере мастер-счёта. Повторное чтение сохранённого отчёта и выгрузка PDF бесплатны. Заголовок Idempotency-Key делает безопасным ретрай по таймауту: повтор с тем же ключом возвращает ту же проверку и не списывает деньги второй раз.

Эндпоинты раздела

Коды ошибок и конверт - Error Codes →.

Лимиты частоты

Запросов в минуту

Чтение: список проверок, карточка, PDF-отчёт 120 optional
Общая корзина читающих вызовов раздела.
Проверка адреса (<code>POST /api/v1/aml/checks</code>) 60 optional
Своя корзина: каждый боевой вызов платный.

При превышении приходит 429 rate_limited с заголовком Retry-After: спите указанное число секунд, затем повторяйте с экспоненциальной задержкой. Корзина AML не пересекается с корзинами кошельков и мастер-счёта.

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

Проверьте адрес в sandbox (ключ sk_test_) и примите решение по единому вердикту recommendation. Панель справа - тот же вызов на cURL, JavaScript, PHP и Python.

Примеры кода

# Проверить адрес (sandbox - по префиксу sk_test_)
curl -X POST https://fin-os.io/api/v1/aml/checks \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{"address": "TXYZ1234567890abcdefGHIJKLmnop", "network": "tron"}'
const FINOS = 'https://fin-os.io/api/v1';
const KEY   = process.env.FINOS_SECRET_KEY; // sk_test_ (sandbox) или sk_live_ (live)

async function checkAddress(address, network) {
  const res = await fetch(`${FINOS}/aml/checks`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ address, network }),
  });
  const { data } = await res.json();
  console.log(data.risk_level, data.risk_score, data.report.recommendation);
  return data;
}

checkAddress('TXYZ1234567890abcdefGHIJKLmnop', 'tron');
use Illuminate\Support\Facades\Http;

$key  = config('services.finos.secret_key'); // sk_test_ или sk_live_
$data = Http::withToken($key)
    ->post('https://fin-os.io/api/v1/aml/checks', [
        'address' => 'TXYZ1234567890abcdefGHIJKLmnop',
        'network' => 'tron',
    ])
    ->json('data');

if (in_array($data['report']['recommendation'], ['reject', 'block'], true)) {
    // задержать операцию / отправить на ручной комплаенс
}
import requests, os

FINOS = 'https://fin-os.io/api/v1'
KEY   = os.environ['FINOS_SECRET_KEY']  # sk_test_ (sandbox) или sk_live_ (live)
H     = {'Authorization': f'Bearer {KEY}'}

r = requests.post(f'{FINOS}/aml/checks', headers=H,
                  json={'address': 'TXYZ1234567890abcdefGHIJKLmnop', 'network': 'tron'})
r.raise_for_status()
data = r.json()['data']
print(data['risk_level'], data['risk_score'], data['report']['recommendation'])