curl --request GET \
--url https://api.range.org/v2/risk/history \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/risk/history"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.range.org/v2/risk/history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v2/risk/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/risk/history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.range.org/v2/risk/history")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/risk/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"items": [
{
"screen_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28",
"address_active_on": [
"ethereum",
"polygon"
],
"total_incoming_usd": 1842300.45,
"total_outgoing_usd": 1798450.12,
"malicious_incoming_usd": 184500,
"malicious_outgoing_usd": 92300,
"severity": "high",
"attribution": {
"triggered": [
{
"signal": "sanctions_ofac",
"severity": "severe",
"result": true
}
]
},
"exposure": {
"triggered": [
{
"signal": "compliance-risk",
"mode": "percentage",
"result": true,
"percentage": "42.30%",
"summary": "42.30% of counterparty volume is compliance-risk, crossing the 5% (high) threshold."
}
]
},
"behaviour": {
"detected": [
{
"behaviour": "smurfing",
"severity": "high",
"confidence": 0.78,
"ignored": true
}
]
},
"timestamp": "2026-05-04T14:30:00Z",
"severity_override": {
"type": "range_whitelist",
"original_severity": "severe",
"criterion": "uncontrollable_infrastructure",
"reason": "Cross-chain router; inbound flows are permissionless",
"whitelisted_at": "2026-10-22T10:00:00.000Z"
},
"evidence": {},
"success": true
}
],
"metadata": {
"limit": 10,
"offset": 0,
"total": 1234,
"filtered_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd28",
"filtered_severity": [
"severe",
"high"
],
"applied_sort": "newest",
"filtered_from": "2026-05-01T00:00:00.000Z",
"filtered_to": "2026-05-31T23:59:59.000Z"
}
}List Screening History
List stored workspace assessments with pagination, address, severity, and date filters, including failed screens when requested.
curl --request GET \
--url https://api.range.org/v2/risk/history \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/risk/history"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.range.org/v2/risk/history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v2/risk/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/risk/history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.range.org/v2/risk/history")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/risk/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"items": [
{
"screen_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28",
"address_active_on": [
"ethereum",
"polygon"
],
"total_incoming_usd": 1842300.45,
"total_outgoing_usd": 1798450.12,
"malicious_incoming_usd": 184500,
"malicious_outgoing_usd": 92300,
"severity": "high",
"attribution": {
"triggered": [
{
"signal": "sanctions_ofac",
"severity": "severe",
"result": true
}
]
},
"exposure": {
"triggered": [
{
"signal": "compliance-risk",
"mode": "percentage",
"result": true,
"percentage": "42.30%",
"summary": "42.30% of counterparty volume is compliance-risk, crossing the 5% (high) threshold."
}
]
},
"behaviour": {
"detected": [
{
"behaviour": "smurfing",
"severity": "high",
"confidence": 0.78,
"ignored": true
}
]
},
"timestamp": "2026-05-04T14:30:00Z",
"severity_override": {
"type": "range_whitelist",
"original_severity": "severe",
"criterion": "uncontrollable_infrastructure",
"reason": "Cross-chain router; inbound flows are permissionless",
"whitelisted_at": "2026-10-22T10:00:00.000Z"
},
"evidence": {},
"success": true
}
],
"metadata": {
"limit": 10,
"offset": 0,
"total": 1234,
"filtered_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd28",
"filtered_severity": [
"severe",
"high"
],
"applied_sort": "newest",
"filtered_from": "2026-05-01T00:00:00.000Z",
"filtered_to": "2026-05-31T23:59:59.000Z"
}
}Authorizations
Authorization method required to allow user to access the api endpoints.
Query Parameters
Number of records to skip. Defaults to 0.
Page size, 1-100 inclusive. Defaults to 10.
Return only screens requested for this address. metadata.total reflects the filtered count. The value is normalised exactly as GET /v2/risk/address normalises it, so equivalent forms of the same address match the same records — note this can change the address by more than case (EVM addresses are lowercased; a Stellar muxed M… account folds to its base G… account), and the records returned echo the normalised form. Passing the parameter with an empty value is a client error, not an unfiltered request.
Page ordering. newest (default) is the assessment timestamp descending — the field returned on each item. severity orders worst-first, by severity rank rather than alphabetically, with newest as the tiebreak within a band; a screen with no recorded severity ranks alongside none, at the bottom. Both orders carry an internal tiebreak so paging is deterministic. metadata.applied_sort echoes the order used. An unrecognised value is a client error rather than a silent fallback to the default.
newest, severity Only return screens queried at or after this ISO 8601 date-time (inclusive). A bare date (2026-05-01) or a date-time with no Z/offset (2026-05-01T00:00:00) is interpreted as UTC, not the server's local time; a value carrying Z or an explicit offset is honoured as given. metadata.filtered_from echoes the applied bound. An unparseable value is a client error, not an unfiltered request.
Only return screens queried at or before this ISO 8601 date-time (inclusive). Parsed as UTC the same way as from, except a bare date (2026-05-31) expands to the inclusive end of that UTC day (23:59:59.999Z) rather than its start. metadata.filtered_to echoes the applied bound. An unparseable value is a client error, not an unfiltered request.
When true (or 1), also include screens that failed (success: false) and set success on every item in the response. Defaults to false, which is this endpoint's original behaviour: only successful screens, and no success field on items. A failed item always reports severity: 'none' (no assessment ran), so combining this with ?severity= excludes every failed screen — metadata->>'severity' is NULL for those rows, not 'none', and the severity filter only matches recorded values.
Return only screens whose overall severity is one of these. Comma-separated for more than one (severity=high,severe) or repeated (severity=high&severity=severe), case-insensitive, and duplicates are collapsed. This is set membership, not a threshold — severity=high returns high and nothing else, so a caller after "everything that needs review" must name each severity it wants (severity=severe,high). metadata.total reflects the filtered count and metadata.filtered_severity echoes the applied set. An unrecognised value is a client error, as is passing the parameter with an empty value — neither is treated as an unfiltered request. Note that a stored screen with no recorded severity matches no value at all, so the filter is not a partition of the workspace's history.
severe, high, medium, low, none Was this page helpful?