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
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
- Create a key in the bot; make sure the account has checks or USDT.
POST /v1/aml/checkwith an address β act onverdict.level:green,yellow,red.- Keep
report_id:GET /v1/aml/report/{report_id}returns the same report later, free of charge. - 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
| Field | Type | Description |
|---|---|---|
address | string | Wallet address (see the network table below). |
network | string | Optional 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. |
txid | string | Transaction 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
| Field | Meaning |
|---|---|
report_id | Id of the stored report; use it with GET /v1/aml/report/{report_id}. |
charged.source | count (from the package), usdt (from the balance), cached or free (not charged). charged.usdt is the amount taken from the balance. |
balance | Account balance after the request: USDT and remaining package checks. |
cached | The report was served from the one-hour cache. |
network | Network code the address was checked on. null for transaction checks. |
verdict.level | The field to act on: green, yellow, red or unknown (providers gave no score). |
verdict.label | Human-readable text for showing to a person (Russian, with an emoji). Do not parse it β use level. |
verdict.elliptic_risk_score | 0β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_score | 0β1. null for transaction checks. |
verdict.sanctions | true when sanction-related exposure was found in the address's counterparties. |
providers | Which providers answered. An account with Elliptic disabled always has elliptic:false. |
entity | The 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
| Code | Network | Code | Network |
|---|---|---|---|
trx | TRON | btc | Bitcoin |
eth | Ethereum | ltc | Litecoin |
bsc | BNB Smart Chain | bch | Bitcoin Cash |
matic | Polygon | doge | Dogecoin |
arb | Arbitrum | dash | Dash |
op | Optimism | xrp | XRP Ledger |
base | Base | sol | Solana |
avax | Avalanche C-Chain | ton | TON |
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.
| HTTP | code | Meaning |
|---|---|---|
| 400 | bad_json, bad_address, bad_txid | Invalid request |
| 400 | bad_network, ambiguous_network | Pass a valid network; candidates (and active) are included |
| 401 | unauthorized | Missing, invalid or revoked key |
| 402 | insufficient_funds | No checks left and not enough USDT β top up in the bot |
| 403 | txid_unavailable | Transaction checks need Elliptic enabled on the account; check the address instead |
| 404 | not_found | Unknown endpoint or report |
| 409 | busy | Another check of this account is running β retry in a few seconds |
| 410 | gone | The report file is no longer available |
| 413 | body_too_large | Request body over 64 KB |
| 429 | rate_limited | Per-key or per-IP limit exceeded; wait a minute |
| 502 | provider_error | Providers failed; nothing was charged β retry later |
| 503 | maintenance, unavailable | Service paused / temporary outage β nothing was charged, retry later |
Notes
Support: the Telegram bot, section π¬ Support.