FreezeRadar Developers · v1
Asynchronous freeze-risk intelligence API
Business customers can submit wallet and transaction screenings, poll a result, and receive signed completion events. Results are explainable risk signals — not legal advice, AML certification, an ownership assertion, or an instruction to block a payment.
Authentication
Use a Business API key in the Authorization Bearer header. Create and revoke keys from the Developer Console.
Async workflow
Create a screening, retain its id, then poll the result URL or wait for a signed webhook.
Signed delivery
Every webhook includes an event id, Unix timestamp and HMAC-SHA256 signature.
Getting started
Overview
The FreezeRadar Business API mirrors the same freeze-risk analysis used in the app. Every screening is asynchronous: a create call returns immediately with a job id, and the result becomes available once analysis finishes — via polling or a signed webhook event.
Authentication
Send Authorization: Bearer <API_KEY> over HTTPS on every request. Keys are account-owned and shown only once when created. Store them in a server-side secret manager; never place them in browser code, mobile apps, or public repositories.
Invalid, revoked, or absent keys return 401 UNAUTHORIZED. Business feature or quota restrictions return a safe error without internal provider details.
{
"ok": false,
"error": {
"code": "UNAUTHORIZED",
"message": "A valid Business API key is required."
}
}Base URL & versioning
All endpoints below are relative to https://freezeradar.com/api/v1. The current version is v1; breaking changes will ship under a new version prefix rather than mutating this one.
API reference
Create an address screening
/api/v1/address-screeningsAccepts the same address, chain, optional asset list, and optional scan mode as the FreezeRadar app. Returns immediately with an id and QUEUED status.
| Parameter | Type | Description |
|---|---|---|
addressrequired | string | Wallet address to screen. |
chainrequired | ethereum | tron | bsc | polygon | solana | base | arbitrum | optimism | avalanche | Chain the address belongs to. |
assetsoptional | (USDT | USDC | PAXG | XAUt)[] | Restrict analysis to specific freezeable assets. Defaults to full coverage. |
scanModeoptional | STANDARD | DEEP | DEEP performs a more thorough, slower analysis. Defaults to STANDARD. |
curl -X POST https://freezeradar.com/api/v1/address-screenings \
-H "Authorization: Bearer fr_live_…" \
-H "Content-Type: application/json" \
-d '{
"address": "0x…",
"chain": "ethereum",
"assets": ["USDT"],
"scanMode": "STANDARD"
}'{
"ok": true,
"data": {
"id": "scan_job_id",
"status": "QUEUED",
"resultUrl": "/api/v1/screenings/scan_job_id"
}
}Create a transaction screening
/api/v1/transaction-screeningsScreens a specific on-chain transaction. Coverage is returned only where the underlying chain provider can prove a supported freezeable-asset transfer.
| Parameter | Type | Description |
|---|---|---|
chainrequired | ethereum | tron | bsc | polygon | solana | base | arbitrum | optimism | avalanche | Chain the transaction belongs to. |
transactionHashrequired | string | The transaction hash to analyze. |
policyIdoptional | string | Apply an existing risk policy's thresholds to the verdict. |
curl -X POST https://freezeradar.com/api/v1/transaction-screenings \
-H "Authorization: Bearer fr_live_…" \
-H "Content-Type: application/json" \
-d '{
"chain": "ethereum",
"transactionHash": "0x…",
"policyId": "cl…"
}'{
"ok": true,
"data": {
"id": "screening_id",
"status": "QUEUED",
"resultUrl": "/api/v1/screenings/screening_id"
}
}A transaction that is valid but has no supported asset coverage, or cannot be assessed for that chain, returns 422 and releases its reserved quota.
Get a screening result
/api/v1/screenings/{id}Returns the latest job state for either screening type. Possible statuses are QUEUED, RUNNING, COMPLETED, and FAILED. Do not treat QUEUED or RUNNING as a final result.
curl https://freezeradar.com/api/v1/screenings/scan_job_id \
-H "Authorization: Bearer fr_live_…"{
"ok": true,
"data": {
"id": "scan_job_id",
"status": "COMPLETED",
"resultUrl": "/scan/wallet_scan_id",
"walletScanId": "wallet_scan_id",
"errorMessage": null,
"scan": {
"id": "wallet_scan_id",
"overallRisk": 62,
"riskCategory": "MEDIUM",
"confidenceScore": 0.81,
"accessMode": "SUMMARY",
"scanMode": "STANDARD",
"analyzedAt": "2026-08-05T02:10:00.000Z"
}
}
}{
"ok": true,
"data": {
"id": "screening_id",
"status": "COMPLETED",
"verdict": "CLEAR",
"riskCategory": "LOW",
"overallRisk": 12,
"chain": "ethereum",
"transactionHash": "0x…",
"resultUrl": "/api/v1/screenings/screening_id",
"completedAt": "2026-08-05T02:10:00.000Z",
"errorMessage": null,
"result": { "findings": [], "transferCoverage": "…", "policyVersion": null }
}
}Transaction results include verdict (CLEAR / REVIEW / BLOCK), riskCategory, findings, transfer coverage, and the policy version when one was used. Responses never include raw evidence blobs.
Webhooks
Events
Select events in the Business Developer Console. Payloads are JSON and include id, type, createdAt, and data.
| Event | Fires when |
|---|---|
screening.completed | A transaction screening has a final result. |
freeze-state.changed | A priority issuer monitor observed a direct state change. |
risk.alert.created | A related priority-monitor alert was created. |
Verifying signatures
Every delivery includes these headers. The signature is sha256= plus an HMAC-SHA256 of the timestamp, a dot, and the raw request body, using the webhook secret shown at creation.
| Header | Description |
|---|---|
x-freezeradar-event | The event type, e.g. screening.completed. |
x-freezeradar-timestamp | Unix timestamp the delivery was signed at. |
x-freezeradar-signature | sha256=<hmac> over `${timestamp}.${rawBody}`. |
import { createHmac, timingSafeEqual } from "node:crypto";
const signed = `${timestamp}.${rawBody}`;
const expected =
"sha256=" +
createHmac("sha256", webhookSecret).update(signed).digest("hex");
if (!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
throw new Error("Invalid FreezeRadar signature");
}Verify the signature against the raw body before parsing. Deduplicate on event id. Reject stale timestamps according to your replay window. Return any 2xx response to acknowledge delivery; non-2xx responses are retried with bounded backoff.
Reference
Errors & rate limits
| Status | Meaning |
|---|---|
| 400 | Invalid request shape or invalid chain/address/hash. |
| 401 | Missing, invalid, or revoked API key. |
| 403 | Business entitlement is unavailable (including after plan downgrade), or an account limit is reached. |
| 404 | Screening id does not belong to the authenticated account. |
| 422 | Transaction is valid but has no supported asset coverage, or cannot be assessed for that chain. |
| 429 | Rate limit exceeded — 60/min and 600/hour per API key. Respect Retry-After. |
| 503 | Rate limiting temporarily unavailable; the Business API fails closed until Redis recovers. |
| 5xx | A temporary safe failure. Retry with exponential backoff. |
Usage is account-scoped. Keys remain hashed at rest but are rejected on use unless the account still has an active Business entitlement. A transaction screening that cannot start because it is invalid, unsupported, or provider-unavailable releases its reserved transaction quota. Bridge-trace and graph-explorer entitlements are plan flags for product gating; they are not exposed as separate public /api/v1 endpoints yet.
Integration checklist
Before you ship
Keep keys and webhook secrets server-side.
Poll until a final status or verify signed webhooks.
Store evidence and coverage alongside your own decision.
Use a human review path for high-risk or incomplete results.
Do not represent FreezeRadar output as a legal determination or automatic freeze prediction.
Need higher limits or a custom policy?
Reach out and we'll help you scope a Business plan for your volume.