Skip to content

GET /apiv2/screening/history

Your screening history, newest first, with cursor pagination.

This is the version 2 contract. It replaces GET /apiv2/aml/history, which keeps working.

Endpoint URL

GET https://netts.io/apiv2/screening/history

Request Headers

HeaderRequiredDescription
X-API-KEYYesYour API key from the Netts dashboard

Query Parameters

All filters are optional. Without any of them you get your whole history.

ParameterTypeDefaultDescription
addressstringExact address, 10–128 characters
networkstringNetwork ticker
providerstringelliptic or bitok
statusstringpending, processing, completed, skipped, failed
fromstringOnly checks created at or after this moment, RFC 3339
tostringOnly checks created at or before this moment, RFC 3339
cursorstringWhere to continue from. Take it from next_cursor
limitinteger50Items per page, 1 to 200

In version 1 address and network were both required, so there was no way to ask "what have I checked lately".

Checks with status skipped are included. Version 1 hides them. A skipped check is a real order — the address had no blockchain activity, so it was never sent to the provider and never charged — and it belongs in the history.

Example Requests

cURL

bash
curl "https://netts.io/apiv2/screening/history?limit=50" \
  -H "X-API-KEY: your_api_key"

Python — walk the whole history

python
import requests

headers = {"X-API-KEY": "your_api_key"}
params = {"limit": 200, "provider": "elliptic"}

while True:
    page = requests.get("https://netts.io/apiv2/screening/history",
                        headers=headers, params=params).json()
    for item in page["items"]:
        print(item["order"]["client_order_id"],
              item["order"]["status"],
              item["risk"]["level"],
              item["sanctions"]["verdict"])

    if not page["next_cursor"]:
        break
    params = {"limit": 200, "provider": "elliptic", "cursor": page["next_cursor"]}

Keep the filters identical while paging. Changing one while carrying the same cursor is an error, not a silent switch to a different set.

Response

json
{
  "schema_version": 2,
  "items": [
    {
      "order": {
        "client_order_id": "A6F3221BAAE093A",
        "status": "completed",
        "api_version": "v2",
        "cache_hit": false,
        "created_at": "2026-09-13T08:24:19.838584Z",
        "started_at": "2026-09-13T08:24:20.998619Z",
        "completed_at": "2026-09-13T08:24:25.179967Z"
      },
      "request": {
        "address": "YOUR_ADDRESS_HERE",
        "network": "trx",
        "provider": "elliptic"
      },
      "check": {
        "provider": "elliptic",
        "provider_check_id": "1cc2fd64-1483-4ce3-946f-23a614f41a12",
        "checked_at": "2026-09-13T08:24:22.372000Z",
        "status": "completed",
        "provider_status": "complete"
      },
      "risk": {
        "score": "0.12428176721891304",
        "scale": { "min": 0, "max": 10 },
        "level": "low",
        "level_source": "computed",
        "provider_level": null,
        "policy": "netts-risk-v1",
        "by_direction": { "source": "0.12428176721891304", "destination": null }
      },
      "sanctions": { "verdict": "linked" }
    }
  ],
  "next_cursor": "eyJmIjp7InN0YXR1cyI6ImNvbXBsZXRlZCJ9LCJpIjoxMzQyNywidCI6...",
  "limit": 1
}
FieldTypeDescription
itemsarrayThe page, newest first
next_cursorstring | nullPass it back to get the next page. null means you have reached the end
limitintegerThe limit that was applied

The short form of an item

The order, request, check and risk blocks are identical to the ones in the full response of GET /apiv2/screening/{client_order_id}, field for field, so the same parser handles both.

What is left out: provider_data, exposure[], rules[], entities[], wallet, billing, precheck, and the full sanctions block. A single Elliptic result is around 150 KB, and a page of fifty would be seven megabytes. Fetch a single check when you need the detail.

sanctions.verdict

The sanctions analysis compressed to one word.

ValueMeaning
listedThe address itself is on a sanctions list
linkedA sanctions link was found, but the address is not itself listed
noneThe analysis ran and found nothing
nullThere is no result to analyse yet

The difference between listed and linked is the point of the field — see Sanctions in an AML result.

Pagination

Version 1 pages by number: ?page=2, 100 per page. The order is by creation time, newest first, so while you walk from page 1 to page 2 new checks arrive and push everything down. Records you already saw reappear, records you have not seen slide past you. With a busy account this is not a corner case.

A cursor points at a place in the set rather than at its ordinal number, so new checks arriving during the walk do not disturb it.

  • the order is created_at DESC, id DESC. Both fields are in the cursor, because created_at is not unique — two checks created in the same microsecond would otherwise loop or skip;
  • the cursor is opaque. Its contents are an implementation detail; pass it back exactly as you received it;
  • the filters are part of the cursor. Changing one while reusing the cursor returns 400, not a silent switch to a different set — otherwise you would believe you had read a set you never read;
  • next_cursor: null means the end. There is no total count: counting the whole set on every page costs more than it tells you.

Errors

RFC 9457, application/problem+json. The full code list is on the POST page.

CodeHTTPWhen
4001400limit outside 1…200, an unknown network, provider or status, a from/to that is not RFC 3339, a malformed cursor, or a cursor issued for different filters
4010 / 4011401No API key, or a key or IP that is not accepted
json
{
  "type": "https://doc.netts.io/api/v2/errors/validation-failed",
  "title": "Request validation failed",
  "status": 400,
  "detail": "Cursor was issued for a different set of filters",
  "instance": "/apiv2/screening/history",
  "code": 4001
}

Rate Limits

Shared with every other AML path: 5 requests per second, 150 per minute. With limit=200 a full history of ten thousand checks is fifty requests.