Get started › Overview

Overview

Screen people, companies and transactions against sanctions, PEP, watchlist and adverse-media data — from your own software or from the console.

AMLPRO is a screening platform. You send a name; it comes back with the records that match, the lists they came from, and a report you can keep. It covers sanctions and PEP screening, watchlist and enforcement checks, corporate registry data and adverse media, with matching rules you configure yourself.

For compliance teams, AMLPRO takes the guesswork out of a name check and leaves an audit trail behind every decision. For engineers, it is a signed REST API that answers in under a second and bills per search from a prepaid balance — no SDK, no session, no login step.

This documentation covers the whole platform: what the pieces are, how a screening runs, how to shape matching with the workflow builder, how billing and access work, and how to call the API.

To get up and running:

  1. Sign in to the console — every new account starts on the free starter package.
  2. Create an API credential and copy the secret key; it is shown once.
  3. Sign your first request and call POST /ir-find.
  4. Build a workflow so the results match your risk appetite.
  5. Top up the balance and go live.
Tip

Read How a screening runs before anything else. Those six steps explain most of what you will see coming back from the API.

The two ways in

There are two ways to reach the same screening engine, over the same data.

Screening API

Called by your own software. Takes a name, returns the records that match it, charges the account and writes the log. Every request is signed.

Console

Used by your compliance team. Search by hand, build workflows, read usage logs, hold API credentials, manage the plan, the balance and the team.

Both run the same six steps, charge the same rates and write to the same usage log, so a search run by hand and a search run from your code are indistinguishable afterwards except for who ran it.

One call does six things, in this order.

1Signature

The key names the credential; the HMAC proves you hold its secret.

2Entitlement

Credential active, account active, IP allowed, permission held, entity type sold by the plan.

3Candidates

Every record whose name, alias or transliteration is close enough to the one you sent. The only stage that decides what the search can see.

4Workflow

Your own rules walk each candidate and keep it or drop it.

5Charge

The plan's price for that entity type, taken from the prepaid balance.

6Log

The result, the name, the cost, who ran it, and a five-minute signed link to the PDF.

Workflow builder

A workflow is your own answer to which of these matches are really mine. It is a small graph: a chain of steps, each outcome wired to the next step or to one of two endings. Every candidate enters at the name step and walks until it reaches an ending.

Name always first Date of birth narrow Passport confirm Include in results Exclude from results no match match settles it
One workflow per entity type, per company. A person workflow has no effect on a company search.

The kinds of step

KindWhat it is for
nameThe match itself. Always first, and cannot be removed.
narrowCompares an attribute of the subject you sent against the record.
confirmAn exact identifier. A hit settles identity; a miss does nothing.
scoreToo sparse or messy to decide on, but useful for ordering.
scopeA property of the record rather than of your subject, so it needs no input.

What a step can test

The steps available depend on what is being screened.

Individual

StepKindWhat it does
Namename Names, aliases and transliterations close to the one you send.
Date of birthnarrow Same birth year. Compared by year, not by exact date, so send whatever you hold.
Countrynarrow One step over citizenship, nationality and where the person has held office.
Genderscore Demotes a record whose recorded gender differs. Never excludes.
Place of birthscore Nudges up similar-sounding places. The source mixes city, district and country, in local script.
Passport numberconfirm An exact document-number match that settles identity outright.
National IDconfirm An exact national identity-number match.

Company and organization

StepKindWhat it does
Namename Registered name, trading names and former names.
Country of registrationnarrow Where it was incorporated, not where it operates.
Date of incorporationnarrow Same year. Compared by year, not by exact date.
Registration or tax numberconfirm Registration, tax, INN/OGRN or LEI. Not every number is unique to one company.
Owner or director riskscope Keeps companies whose owner or director is sanctioned, even when the company is not.

Adverse media takes the name step only.

Three rules, all of them fail-open

In screening, a missed match costs more than an extra one. Every rule resolves toward keeping the record.

  • A step you sent no value for cannot be evaluated, so it is skipped. Sending no date of birth narrows nothing.
  • A step whose field the record does not carry follows your no-value rule, which can only be carry on or include.
  • An outcome wired to nothing keeps the record.

Every decision is recorded per candidate, so a record that survived because three steps were skipped is distinguishable from one that passed three checks.

Plans and balance

Screening is billed in money from a prepaid balance, per search, at the price the plan sets for that entity type.

Terms, not a subscription counter

Each period an account holds a package is its own term, with its own credit and its own rates. An account runs one package at a time; buying another ends the one running, and unspent credit tied to that term is forfeited while money never tied to it — opening balances, payments — stays with the customer. Prepaid credit is the exception: what is left on a prepaid plan moves to the balance when the plan changes, and is spent after the new plan's own credit, at the new plan's rates. Where terms overlap, the oldest one with credit left prices the next search.

What a plan sells

There are four services. A plan prices each one separately, and they are the same four you ask for as schema on a search.

ServiceAsk for it asScreens
IndividualPerson A named person, against sanctions, PEP, watchlist and enforcement listings.
CompanyCompany A registered company.
OrganizationOrganization An organization that is not registered as a company.
Adverse mediaAdverse Media Negative news coverage.

Each of the four is set to one of three things on the plan:

SettingMeaning
IncludedCovered by the price of the package.
Add-onUsable, charged per search at the rate beside it.
Not availableNot sold. Refused with 403.

A service is sold if any package you are running sells it, so a second package bought to add a service takes effect straight away.

Unlimited plans

A plan can sell the period instead of the searches. On one of those the fee buys the month and a search costs nothing: the balance is not read and not written, so there is no balance to run out and no 402 to hit. It still screens only what the plan sells, so an unlimited plan can be Individual-only, and a service set to not available is still refused.

The free starter

Every new account is put on a free package: Individual screening only, worth exactly 100 screenings a month, renewed monthly until the account buys something. It is granted, never sold, and has no subscription to cancel.

Volume pricing

One price list for the platform, shown on every customer's Packages page as a slider: at each monthly call volume, the price a month, the calls it includes and the rate per call. It sells nothing — its button opens a support ticket naming the volume chosen. What a search costs is still the plan's per-search price.

Roles and access

A company has one owner and any number of members. The owner always has every permission and cannot be locked out. A member gets a role.

CanAdminComplianceDeveloperViewer
Search and build workflowsYesYesYesNo
Read usage logs and sourcesYesYesYesYes
Hold API credentialsYesNoYesNo
See packages, balance, paymentsYesNoNoNo
Manage the team and rolesYesNoNoNo
Change the company logoYesNoNoNo
Edit company detailsNoNoNoNo

The last row is not an oversight. The company's legal details are the account holder's own record, so they stay the owner's whatever role a member holds. The logo is not: it is the mark on their invoices and at the top of their console, and the person who runs the account day to day is usually an Admin. A company can also define its own roles from the same set of permissions.

Every refusal is enforced at the route

Not only in the menu. Hiding a link is not a permission — a member who types the URL of a page their role does not allow is refused by the server.

Authentication

Every request carries three headers. There is no session, no bearer token and no login step.

Your base URL comes with your key

Every sample below uses https://api.example.com as a stand-in. The real host is shown beside the credential when you create one in Dev Credentials, together with the app key and the secret — substitute it there and the samples run as written.

HeaderValue
ikeyYour app key. Identifies the credential.
inonceThe current Unix timestamp, in seconds, as a string.
isignatureBase64 of an HMAC-SHA256, computed as below.

The signature

Concatenate three values in this order, remove every space, and sign what is left with your secret key.

Algorithm
// concatenate, then delete all spaces
payload   = <subject> + inonce + ikey

// sign with the secret key, then base64
signature = base64( HMAC-SHA256( secret_key, payload ) )

<subject> is whatever the call is about:

CallSubject to sign
POST /ir-findthe full_name you are screening
POST /ir-downloadthe log_id of the screening
GET /download-log/<token>an empty string
The space rule matters

Jane Doe signs as JaneDoe. Sign the name you are sending with its spaces removed — not a trimmed, lowercased or otherwise normalised version of it. A mismatch here is the most common cause of a refused call: 400 on /ir-find and /ir-download, 401 on the download link.

Signing code

The same request in four languages. Switching the tab switches every sample on the page.

import base64, hashlib, hmac, time, requests

APP_KEY    = "your-app-key"
SECRET_KEY = "your-secret-key"
BASE       = "https://api.example.com"

def sign(subject: str, ikey: str, secret: str, inonce: str) -> str:
    payload = f"{subject}{inonce}{ikey}".replace(" ", "")
    digest  = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).digest()
    return base64.b64encode(digest).decode()

name   = "Jane Doe"
inonce = str(int(time.time()))

response = requests.post(
    f"{BASE}/ir-find",
    headers={
        "ikey":         APP_KEY,
        "inonce":       inonce,
        "isignature":   sign(name, APP_KEY, SECRET_KEY, inonce),
        "Content-Type": "application/json",
    },
    json={
        "full_name":     name,
        "schema":        "Person",
        "percent_limit": 80,
        "result_limit":  10,
    },
    timeout=90,
)

print(response.status_code, response.json()["records_found"])
Sign on your server, never in a browser

The secret key is shown once, when the credential is created, and cannot be read back afterwards. Anything holding it can screen at your expense.

Credential permissions

Each credential carries its own permissions and, optionally, its own IP allowlist. A call outside them is refused even with a valid signature. These are the names you tick when you create a credential in the console.

PermissionAllows
Name Screening Screen a name and get the matching records back — POST /ir-find
Report Download The PDF for a screening that has already run, by its reference — POST /ir-download
Report Download Link The PDF from the time-limited link a screening hands back — GET /download-log/<token>

Run a screening

POSThttps://api.example.com/ir-find

Requires Name Screening. Accepts JSON or form-encoded fields. Sign the full_name.

Body params

full_namestringrequired

The name to screen. This is also the signature subject.

schemastringoptionalPerson

Which of the four services to screen: Person, Company, Organization, Adverse Media, or all for every one. Comma-separate to combine them — Person, Adverse Media. Omit it and only Person is screened. A value that is not one of these is refused with 400 rather than quietly screened as a person.

Case does not matter, and Individual, Org, Organisation and ADM are accepted as aliases. The field itself is also read from entity_type, entity_types, type, search_type or entity.

percent_limitintegeroptional80

Minimum match score, 0–100. Lower it to see more candidates.

result_limitintegeroptional10

Maximum records returned, 1–1000.

return_typestringoptionalfull

full for records, count for the totals only.

external_idstringoptional

Your own reference. Stored on the log and returned unchanged.

Workflow inputs

Optional. Each is what a workflow step compares against; send nothing and that step is skipped.

FieldAlso read from
dobdate_of_birth, birth_date
countrynationality, citizenship
gendersex
birth_placeplace_of_birth
passportpassport_number
national_idid_number
jurisdictioncountry_of_registration
incorporation_dateincorporated
identifierregistration_number, tax_number, lei
The download link is short-lived

download_url is signed and expires five minutes after the search. Call it straight away, or use /ir-download later — that one works at any time, from the log_id.

Download a report by reference

POSThttps://api.example.com/ir-download

Requires Report Download. Answers with application/pdf.

ir_download_logstringrequired

The log_id returned by the screening. Sign this same value as the subject — not the name.

Works at any time after the screening, for as long as the log is retained. This is the call to use for a report you fetch on a schedule, or re-fetch months later for an audit.

GEThttps://api.example.com/download-log/<token>

Requires Report Download Link. Uses the download_url a screening returned, which expires five minutes after the search.

tokenpath segmentrequired

Already present in download_url. Use that URL as returned.

isignatureheaderrequired

Sign an empty subject: the payload is inonce + ikey with the spaces removed.

The link is not a credential

It carries no authority on its own; the same three headers are still required. A URL that authenticated by itself would hand a full screening report to anything it was forwarded to — a mail thread, a log aggregator, a proxy that records paths.

The record shape

Results arrive under result.AML and result.adverse_media. One record looks like this — the values are made up, the shape is not.

One record
{
  "entity": {
    "schema":  "Person",
    "name":    "Jane Doe",
    "sources": [
      "US OFAC Specially Designated Nationals (SDN) List",
      "US Trade Consolidated Screening List (CSL)",
      "US SAM Procurement Exclusions"
    ]
  },
  "properties":     { "name": ["DOE, Jane", "Jane Doe"] },
  "topics":         ["sanction", "debarment", "export.control"],
  "person_details": { "first_name": "Jane", "last_name": "DOE" },
  "relationships": {
    "sanctions": [
      {
        "sanctioned_entity_name": "Jane Doe",
        "authority":              "Office of Foreign Assets Control",
        "program":                "EXAMPLE-01",
        "provisions":             "Block | EXAMPLE-01",
        "listing_date":           "Mon, 05 Feb 2024 00:00:00 GMT",
        "country":                "us",
        "source_url":             "https://www.treasury.gov/…"
      }
    ]
  },
  "similarity_percentage": "100.00",
  "matched_name": { "value": "Jane Doe", "type": "name" },
  "category": "AML"
}
FieldWhat it is
entity.nameThe record's own name.
entity.sourcesThe lists the record was found on, by name.
matched_nameWhich of the record's names your query matched, and where it came from — name, alias or weakAlias.
similarity_percentageThe match score, as a string to two decimal places.
topicsWhy the record is listed: sanction, debarment, role.pep, crime.
relationshipsSanctions, directorships, ownerships, family, associates, positions. Present only when the record carries them.
categoryAML or ADM.

Internal identifiers are stripped from every response — each sits beside something readable that means the same thing. Empty fields are removed rather than returned as nulls, so the absence of a key means the record does not carry it.

Status codes

A refusal from /ir-find answers with status: "failed" and a description that says what to do about it. The download routes are older and answer some refusals with status: "error" and message instead, so read both keys if you are handling all three endpoints in one place.

CodeMeansWhat to do
200 The search ran and was charged. Read records_found; zero is a valid, billed answer.
400 A field is missing or out of range, the signature did not verify, the timestamp is stale, the account is inactive, or the calling IP is not on the credential's allow-list. Read description; it names the field, or the address that was refused. A signature failure says no more than that, by design — check the space rule and that the timestamp is current.
401 Only from GET /download-log: its signature did not verify, or one of the three headers is missing. That call signs an empty string — the token is in the URL, not in the payload. /ir-find refuses a bad signature with 400 instead.
402 Not enough balance for this search, or no plan on the account at all. Top up. The body carries required, balance, currency and a breakdown of what was being charged, so a client can say what is short without parsing the sentence.
403 The plan does not sell this entity type, or the credential was not issued with the permission this call needs. Read description; it names what was refused. An IP that is not on the allow-list is a 400, not this.
429 More than 120 requests a minute on one credential. Wait the retry_after seconds in the body, then carry on.
500 Something failed on our side. Retry; if it persists, quote the log_id if you have one.
A refusal is never a silent empty result

An account that cannot screen a Company is told so, rather than answered with an empty list that reads as "no matches". Treat an empty result on a 200 as a real, billed clean search.

Every screening is logged with what was searched, what matched, which list it came from, what it cost and who ran it. That record is what makes an answer defensible six months later — and it is why a screening log is never deleted.