Prof Energy AML API

REST API for AML risk checks of crypto wallets and incoming transactions. Base URL: https://api.profenergy.io/v1 (shared with the energy rental API). All requests and responses are JSON, all times are UTC (ISO 8601).

Authentication

API access is granted per account by an administrator: ask for it in the Telegram bot (πŸ’¬ Support). Once approved, the πŸ”‘ API section appears in βš™οΈ Settings, where you create a key with βž• New key. The key is shown once. Checks are paid from the same account as in the bot: from the check package if there is one, otherwise from the USDT balance (πŸ’° Top up). Revoked keys and keys of accounts whose access was withdrawn are rejected with 401.

Authorization: Bearer pe_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-Api-Key: pe_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Limits: 60 requests per minute per key and 60 per minute per IP; 10 POST /aml/check per minute per key β€” every request counts, including rejected ones; one check at a time per account (a second concurrent check gets 409 busy); 5 active keys per account. Exceeding a limit returns HTTP 429 rate_limited β€” wait a minute and retry.

Quick start

  1. Create a key in the bot; make sure the account has checks or USDT.
  2. POST /v1/aml/check with an address β€” act on verdict.level: green, yellow, red.
  3. Keep report_id: GET /v1/aml/report/{report_id} returns the same report later, free of charge.
  4. Handle errors by error.code: 429 β€” wait a minute; 402 β€” top up; 502 β€” providers failed, nothing charged, retry later.

Charging and levels

One check per request: from the account's check package if it has one (charged.source = "count"), otherwise from the USDT balance at the single-check price ("usdt"). Nothing is charged when the providers fail (HTTP 502). A repeated check of the same address by the same account within one hour returns the cached report and is not charged ("cached"). If Elliptic fails but Crystal answers, the partial report is delivered free ("free"). GET /v1/balance shows the balance: {"ok":true,"usdt":190.47,"checks":43}.

Access levels are set per key. basic returns the verdict, the scores and the entity behind the address. pro additionally returns the full provider data: counterparties with shares, sanction names, the raw Crystal object. Ask support to switch a key to pro.

Endpoints

POST/v1/aml/check

FieldTypeDescription
addressstringWallet address (see the network table below).
networkstringOptional network code. Required when the address format matches several networks and more than one of them has activity for it β€” the error ambiguous_network lists candidates and active.
txidstringTransaction hash (64 hex) for an incoming-transaction check. Requires address β€” your receiving address in that transaction. Available on accounts with Elliptic enabled, otherwise 403 txid_unavailable.
curl -X POST https://api.profenergy.io/v1/aml/check \
  -H "Authorization: Bearer pe_…" -H "Content-Type: application/json" \
  -d '{"address":"TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9"}'

{"ok":true,"report_id":"rpt_06a35d041c7fc38840e45de3a95d323e",
 "charged":{"source":"count","usdt":0},"balance":{"usdt":188.43,"checks":42},
 "level":"basic","cached":false,"type":"address","address":"TMuA6YqfCeX8EhbfYEg5y7S4DqzSJireY9","network":"trx",
 "verdict":{"level":"red","label":"πŸ”΄ высокий риск Β· санкции","elliptic_risk_score":null,"crystal_risk_score":0.1,
            "sanctions":true,"elliptic_risk_score_reason":"licensed_entity"},
 "providers":{"elliptic":true,"crystal":true},
 "entity":{"name":"Binance","category":"Exchange","licensed_vasp":true}}

Response fields

FieldMeaning
report_idId of the stored report; use it with GET /v1/aml/report/{report_id}.
charged.sourcecount (from the package), usdt (from the balance), cached or free (not charged). charged.usdt is the amount taken from the balance.
balanceAccount balance after the request: USDT and remaining package checks.
cachedThe report was served from the one-hour cache.
networkNetwork code the address was checked on. null for transaction checks.
verdict.levelThe field to act on: green, yellow, red or unknown (providers gave no score).
verdict.labelHuman-readable text for showing to a person (Russian, with an emoji). Do not parse it β€” use level.
verdict.elliptic_risk_score0–10. null when Elliptic does not score the address; then elliptic_risk_score_reason says why β€” licensed_entity means the address belongs to a licensed exchange/VASP, which Elliptic does not score by design.
verdict.crystal_risk_score0–1. null for transaction checks.
verdict.sanctionstrue when sanction-related exposure was found in the address's counterparties.
providersWhich providers answered. An account with Elliptic disabled always has elliptic:false.
entityThe service the address belongs to, if known: name, category (Exchange, Bridge, …), licensed_vasp. null for private wallets.

With pro the response also contains verdict.sanction_hits (count) and verdict.sanction_names (list of matched sanction entries, e.g. "… - OFAC SDN - 14 Aug 2025"), an elliptic object β€” risk_score, sanctions, sanction_names, entity, and source_items / dest_items: incoming / outgoing counterparties as {"name","category","usd","pct","hops"} sorted by share β€” and a crystal object with the raw Crystal Intelligence response (alert_grade, alert_list, counterparty, flagged, …).

Transaction checks

With txid the report describes the incoming transaction rather than the address: type is txid, network, crystal_risk_score and entity are null, sanctions is not evaluated (always false), and verdict.level is derived from elliptic_risk_score: below 3 β€” green, 3–7 β€” yellow, 7 and above β€” red.

GET/v1/aml/report/{report_id}

Returns a previously generated report of this account in the same shape plus created_at; not charged. The level (basic / pro) of the key making the request applies. Reports are kept for at least 30 days.

GET/v1/balance

{"ok":true,"usdt":190.47,"checks":43} β€” USDT balance and remaining package checks.

Supported networks

CodeNetworkCodeNetwork
trxTRONbtcBitcoin
ethEthereumltcLitecoin
bscBNB Smart ChainbchBitcoin Cash
maticPolygondogeDogecoin
arbArbitrumdashDash
opOptimismxrpXRP Ledger
baseBasesolSolana
avaxAvalanche C-ChaintonTON

A 0x… address matches all EVM networks; if it has activity on more than one, pass network explicitly.

Errors

Every error is JSON with ok:false and an error.code to branch on; error.message is for logs.

HTTPcodeMeaning
400bad_json, bad_address, bad_txidInvalid request
400bad_network, ambiguous_networkPass a valid network; candidates (and active) are included
401unauthorizedMissing, invalid or revoked key
402insufficient_fundsNo checks left and not enough USDT β€” top up in the bot
403txid_unavailableTransaction checks need Elliptic enabled on the account; check the address instead
404not_foundUnknown endpoint or report
409busyAnother check of this account is running β€” retry in a few seconds
410goneThe report file is no longer available
413body_too_largeRequest body over 64 KB
429rate_limitedPer-key or per-IP limit exceeded; wait a minute
502provider_errorProviders failed; nothing was charged β€” retry later
503maintenance, unavailableService paused / temporary outage β€” nothing was charged, retry later

Notes

Support: the Telegram bot, section πŸ’¬ Support.