Developer Getting Started Guide
Conceptual model, core workflow, and a practical end-to-end walkthrough. For exhaustive parameter documentation use the Swagger reference.
Introduction
AML HQ is a compliance platform for Anti-Money Laundering (AML) and Know Your Customer (KYC) workflows. The API lets you programmatically manage every part of that workflow: creating and maintaining client records, running identity verification, screening for politically exposed persons (PEPs) and sanctions, requesting official company registry data, and building risk assessments.
Base URLs
Use the correct base URL for your region. All paths in this guide are relative to that base.
Swagger Reference Documentation
This guide covers the conceptual model and core workflow. For exhaustive endpoint and model reference, use the interactive Swagger documentation:
| Environment | Swagger URL |
|---|---|
| Production - UK | https://api.amlhq.co.uk/swagger |
| Production - IE / Other | https://api.amlhq.com/swagger |
| Test | https://apitest.amlhq.com/swagger |
Core Concepts and Data Model
Before making any API calls, understand the key entities and how they relate to each other.
Account
Your organisation's top-level container. Has users, a subscription type, and a credit balance.
User
Authenticates and acts within the account. Roles control access: AccountOwner, ManageClient, ManagePolicies.
Client
The subject of due diligence - a company or individual your firm engages with. Has risk level, due diligence level, and parties.
Client Party
A person or entity associated with a Client - director, UBO, PSC (Person with Significant Control), shareholder. Compliance checks are attached here.
IDV Session
Identity verification of a person. Creates a secure URL shared with the subject who completes it online.
PEP / Sanction Check
Screens a name against PEP lists, sanctions databases, and optionally adverse media. Returns match results and a score.
Assessment
Structured risk questionnaire based on a template. Produces a risk score and level that can propagate to the Client.
Understanding Credits
Some operations consume account credits. Check your balance with GET /user/remainingcredits. Use cost endpoints to estimate before bulk operations:
- PEP / Sanction checks - GET /pepsanctionchecks/cost
- IDV Sessions - GET /idvsessions/getcost/{type}
- Address Verifications - GET /addressverifications/cost
Authentication
The AML HQ API supports two authentication methods. Both grant the same access - choose based on your integration needs.
Method 1 - JWT Bearer Token
Exchange username and password for a time-limited token. Best for user-facing integrations.
Scheme: jwt_auth (http, Bearer)
Header: Authorization: Bearer {token}
Method 2 - API Key
Two permanent headers for server-to-server integrations. No token exchange required.
Schemes: api_key_auth + username_header
Headers: X-Api-Key + X-Username
Method 1: JWT Bearer Token
Authenticate with username and password to receive a JWT token. Swagger scheme name: jwt_auth (http, Bearer).
POST /user/authenticate
Content-Type: application/json
{
"username": "your.username",
"password": "YourPassword1"
}{
"token": "eyJhbGci...",
"tokenExpiryDate": "2025-12-31T23:59:59Z",
"twoFactorRequired": false,
"userDetails": { ... }
}Authorization: Bearer eyJhbGci...Two-Factor Authentication
If 2FA is enabled, the first call returns twoFactorRequired: true and sends a code. Re-call with the code included:
{ "username": "your.username", "password": "YourPassword1",
"twoFactorCode": "123456" }tokenExpiryDate. Detect 401 responses and re-authenticate to get a fresh token.Method 2: API Key Authentication
Designed for server-to-server and programmatic integrations. Send two permanent headers on every request. No POST /user/authenticate call is needed. Swagger schemes: api_key_auth (X-Api-Key) and username_header (X-Username).
| Header | Swagger Scheme | Description |
|---|---|---|
X-Api-Key | api_key_auth (apiKey) | Your account API key - obtained by contacting AML HQ. Permanent credential - treat like a password. |
X-Username | username_header (apiKey) | The username to act on behalf of. Must be a valid active user in your account. |
GET /clients/search
X-Api-Key: your-api-key-here
X-Username: api.service@yourfirm.comX-Username value. Rotate it immediately if it is ever compromised.Requesting an API Key
There are two ways to obtain an API key:
- Contact AML HQ directly - reach out to the team and we will provision a key for your account.
- Via the API - if you already have a valid JWT Bearer token, you can retrieve your account API keys programmatically:
GET /account/apikeys/{keynumber}
Authorization: Bearer eyJhbGci...
// Returns the API key for the given key number on your account
// Use the returned key as the X-Api-Key header value going forwardSee the Swagger documentation for full details on the Account API Keys endpoints.
Core API Workflow
The natural progression for a client onboarding scenario. Each step builds on the previous one - IDs returned become inputs to subsequent calls.
Essential Endpoints at a Glance
| Method | Endpoint | Purpose | Swagger |
|---|---|---|---|
| POST | /user/authenticate | Get a JWT token | Ref |
| GET | /referencedata | Fetch all valid enum values in one call | Ref |
| POST | /clients | Create a client record | Ref |
| GET | /clients/{id} | Retrieve a client | Ref |
| POST | /clients/{id}/parties | Add a party to a client | Ref |
| POST | /pepsanctionchecks | Run a PEP / sanctions screen | Ref |
| POST | /idvsessions | Start an identity verification session | Ref |
| POST | /addressverifications | Request address verification (UK) | Ref |
| POST | /assessments | Create a risk assessment | Ref |
| PUT | /assessments/{id}/answers | Submit assessment answers | Ref |
| POST | /assessments/{id}/complete | Mark assessment complete | Ref |
| GET | /user/remainingcredits | Check credit balance | Ref |
Working with Clients
A Client is the foundation - create it first. Identify whether the client is a company (isCorporate: true) or individual (isCorporate: false). Full model: POST /clients in Swagger.
POST /clients
Authorization: Bearer {token} // or X-Api-Key + X-Username headers
{
"name": "Acme Consulting Ltd",
"isCorporate": true,
"jurisdiction": "IE",
"companyNumber": "123456",
"engagementType": "BusinessAdvisory",
"dueDiligenceLevel": "Standard",
"skipCompanyLookup": false
}
// Response - id: 2001 - keep thisKey Client Fields
| Field | Type | Notes |
|---|---|---|
isCorporate | boolean | true for companies, false for individuals |
jurisdiction | string | ISO country code, e.g. IE, GB, US. See /referencedata/jurisdictions |
companyNumber | string | Company registration number if isCorporate is true |
engagementType | string | See /referencedata/clientengagementtypes |
dueDiligenceLevel | string | Simplified, Standard, or Enhanced. See /referencedata/duediligencelevels |
userRef | string | Your own internal reference for this client (optional) |
nextReviewDate | date | When next periodic review is due (optional) |
skipCompanyLookup | boolean | If true, AML HQ will not automatically retrieve data from the official company register (CRO, Companies House, etc.) and Client Parties such as Directors and PSCs will not be auto-added. Defaults to false. |
skipCompanyLookup
When skipCompanyLookup is set to true, AML HQ will not automatically retrieve information from the official company register (CRO for Ireland, Companies House for the UK, or equivalent). This means:
- The company's registered details will not be auto-populated on the Client record.
- Client Parties such as Directors and PSCs (Persons with Significant Control) will not be automatically retrieved and added to the file.
Use skipCompanyLookup: false (the default) to let AML HQ pull official register data automatically on creation. Use true when you are supplying your own data, the company is not yet registered, or the jurisdiction is not supported for automatic lookup.
Duplicate Check
Check before creating: GET /clients/checkforduplicateclient
GET /clients/checkforduplicateclient?name=Acme+Consulting&jurisdiction=IEClient Parties
Client Parties are the individuals and entities associated with a Client - directors, UBOs, shareholders, authorised signatories. Compliance checks are attached at the party level. See Client controller in Swagger.
POST /clients/{clientId}/parties
{
"name": "Jane Smith",
"clientPartyType": "BeneficialOwner",
"email": "jane.smith@example.com",
"dateofBirth": "1980-05-15",
"nationality": "IE",
"percentageHolding": "35%",
"levelOfInterest": "DIRECT"
}
// Response - id: 4001Valid clientPartyType values from GET /referencedata/clientpartytypes - includes Director, BeneficialOwner, Shareholder, AuthorisedSignatory, UltimateBeneficialOwner.
Linking Checks to Parties
| Method | Endpoint | Purpose | Swagger |
|---|---|---|---|
| POST | /clients/parties/{id}/idvsessions/{idvId} | Link an IDV session to a party | Ref |
| POST | /clients/parties/{id}/pepsanctionchecks/{pepId} | Link a PEP / sanction check | Ref |
| POST | /clients/parties/{id}/addressverifications/{avId} | Link an address verification | Ref |
Compliance Checks
Three types of compliance check: PEP/Sanctions, IDV Sessions, and Address Verification. All follow the same pattern: create - await completion - review and update status.
Screen a person or company against PEP lists, sanctions databases, adverse media, and other watchlists. Results are returned synchronously.
POST /pepsanctionchecks
{
"name": "Jane Smith",
"isCompanyCheck": false,
"yearOfBirth": 1980,
"country": "IE",
"includeOtherChecks": true
}Key Result Fields
| Field | Type | Meaning |
|---|---|---|
isPep | boolean | PEP match found |
isSanctioned | boolean | Sanctions list match found |
hasOtherFlag | boolean | Adverse media or other flag triggered |
highestMatchScore | decimal | Confidence of best match (0-100) |
status | string | pending - review - complete. See statuses |
Flow: create session - share sessionUrl with the person - person completes online - you review and approve or reject.
POST /idvsessions
{
"idvSessionType": "Standard",
"name": "Jane Smith",
"email": "jane.smith@example.com",
"captureAddress": true,
"sendEmailLink": true
}
// Response - sessionUrl: share this link with the personSession Lifecycle
PUT /idvsessions/{id}
{ "status": "Completed", "result": "Pass",
"resultComment": "Documents verified" }Currently available for UK addresses only. Verifies a person or company is associated with a given address.
POST /addressverifications
{ "name": "Jane Smith",
"address": "10 High Street, London, SW1A 1AA" }Match types: GET /referencedata/addressverificationmatchtypes
Risk Assessments
Structured risk questionnaires based on templates. Produces a risk score and level (Low / Moderate / High) that can propagate to the Client. See Assessment controller in Swagger.
GET /assessments/templates // account templates
GET /assessments/templates/system // system templatesPOST /assessments
{ "templateId": 42, "clientId": 2001,
"subject": "Acme Consulting Ltd",
"propagateToClient": true }
// - assessmentId: 7001GET /assessments/{id}/questions
PUT /assessments/{id}/answers
{ "answers": [{ "questionId": 1, "answer": "Yes" }, ...] }POST /assessments/{id}/complete
// - riskScore: 24, riskLevel: "Low"
// Client updated if propagateToClient was truetemplateId and supply riskScore, riskLevel, and dueDiligenceLevel directly.End-to-End Example
Onboarding Acme Consulting Ltd, screening its beneficial owner, and completing a risk assessment. Follow each step in sequence.
// Option A - JWT
POST /user/authenticate
{ "username": "api.user@yourfirm.com", "password": "P@ssw0rd1" }
// - token: "eyJhbGci..."
// Option B - API Key (no auth call needed)
X-Api-Key: your-api-key
X-Username: api.user@yourfirm.comPOST /clients
{ "name": "Acme Consulting Ltd", "isCorporate": true,
"jurisdiction": "IE", "companyNumber": "654321",
"engagementType": "BusinessAdvisory",
"dueDiligenceLevel": "Standard" }
// - id: 2001POST /clients/2001/parties
{ "name": "Jane Smith", "clientPartyType": "BeneficialOwner",
"email": "jane.smith@acme.ie", "dateofBirth": "1980-05-15",
"percentageHolding": "35%", "levelOfInterest": "DIRECT" }
// - partyId: 4001POST /pepsanctionchecks
{ "name": "Jane Smith", "isCompanyCheck": false,
"yearOfBirth": 1980, "country": "IE" }
// - id: 5001, isPep: false, isSanctioned: false
POST /clients/parties/4001/pepsanctionchecks/5001POST /idvsessions
{ "idvSessionType": "Standard", "name": "Jane Smith",
"email": "jane.smith@acme.ie", "sendEmailLink": true }
// - idvId: 6001, sessionUrl shared with Jane - awaits completion
PUT /idvsessions/6001 { "result": "Pass" }
POST /clients/parties/4001/idvsessions/6001POST /assessments
{ "templateId": 42, "clientId": 2001, "propagateToClient": true }
// - assessmentId: 7001
GET /assessments/7001/questions
PUT /assessments/7001/answers { "answers": [...] }
POST /assessments/7001/complete
// - riskScore: 24, riskLevel: "Low" - client 2001 updatedReference Data
Many fields use controlled vocabulary - string codes that must match an approved list. Fetch once at startup and cache; values change infrequently. Full controller: ReferenceData in Swagger.
GET /referencedata // all reference data in one payload| Endpoint | Returns | Swagger |
|---|---|---|
/referencedata/clientpartytypes | Director, BeneficialOwner, ... | Ref |
/referencedata/duediligencelevels | Simplified, Standard, Enhanced | Ref |
/referencedata/clientengagementtypes | Engagement type values | Ref |
/referencedata/idvsessiontypes | Standard, Advanced | Ref |
/referencedata/assessmentrisklevels | Low, Moderate, High | Ref |
/referencedata/jurisdictions | Supported countries with ISO codes | Ref |
/referencedata/countrycodes | Full ISO country code list | Ref |
Webhooks and Async Patterns
Data Requests and IDV Sessions are processed asynchronously. AML HQ can POST a notification to your system when processing completes.
Configuring a Webhook URL
Supply a webhookUrl at account level via PUT /account, or per-request. The per-request URL overrides the account default.
{
"id": 9001,
"eventDate": "2025-06-01T10:30:00Z",
"eventType": "DataRequestCompleted",
"dataRequestId": 300,
"status": "Sent"
}Partner Accounts
This section is relevant to partner integrations only. If your account has the Partner role, you can programmatically create new AML HQ accounts on behalf of your clients. A single API call creates both the account and the initial admin user, and returns an API key ready for immediate use.
isPartner: true on their profile. Use the same JWT Bearer or API Key authentication as all other endpoints.POST /partner/accounts
Creates a new account and its first admin user in a single call. The response includes the new user's full account details and the account's API Key 1, which can be used immediately to make API calls on behalf of the new account.
POST /partner/accounts
Authorization: Bearer {your-partner-jwt-token}
{
// Required
"name": "Smith and Associates Ltd",
"username": "admin@smithassociates.ie",
"userFullname": "Jane Smith",
"userEmail": "admin@smithassociates.ie",
"userPassword": "Secure1Password",
// Optional
"accountType": "Accountancy",
"countryCode": "IE",
"billingAddress": "1 Main Street, Dublin 2",
"billingEmail": "billing@smithassociates.ie",
"taxId": "IE1234567A",
"phoneNumber": "+353 1 234 5678",
"jobTitle": "Managing Partner",
"autoCreateTasks": false,
"emailNotificationsEnabled": true,
"externalEmailNotificationsEnabled": true
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The name of the new account. |
username | string | Yes | The login username for the initial admin user. Typically an email address. |
userFullname | string | Yes | The full name of the initial admin user. |
userEmail | string | Yes | Email address for the initial admin user. |
userPassword | string | Yes | Password for the initial admin user. Min 8 characters, at least 1 uppercase, 1 lowercase, and 1 digit. |
accountType | string | No | Type of account. See reference data for valid values. Defaults to Other. |
countryCode | string | No | ISO 2-digit country code for tax and regulatory purposes. Defaults to IE. |
billingAddress | string | No | Billing address for the account. |
billingEmail | string | No | Billing email - receipts will be sent here if provided. |
taxId | string | No | VAT or sales tax number for the account. |
phoneNumber | string | No | Contact number for the initial admin user. |
jobTitle | string | No | Job title for the initial admin user. |
autoCreateTasks | boolean | No | If true, the system auto-creates tasks for IDV sessions, PEP/sanction checks, and annual reviews. Defaults to false. |
emailNotificationsEnabled | boolean | No | Enables internal processing email notifications for the admin user. Defaults to false. |
externalEmailNotificationsEnabled | boolean | No | Enables external notification emails, e.g. IDV invitation links sent to end subjects. Defaults to false. |
Response (HTTP 200)
Returns two key pieces of data: the full user profile for the new admin user, and the account's API Key 1.
{
"userAccountDetails": {
"username": "admin@smithassociates.ie",
"fullname": "Jane Smith",
"accountId": 1042,
"accountName": "Smith and Associates Ltd",
"accountType": "Accountancy",
"isAccountOwner": true,
"remainingCredits": 0,
// ... full UserModel fields
},
"apiKey": "abc123-your-new-account-api-key"
}| Field | Description |
|---|---|
userAccountDetails | Full UserModel for the newly created admin user, including accountId, accountName, subscription details, and feature flags. |
apiKey | API Key 1 for the new account - ready to use immediately as the X-Api-Key header value. No separate provisioning step required. |
apiKey in the response can be used straight away. Pass it as X-Api-Key with the new account username as X-Username to start making API calls on behalf of the new account.Error Responses
A 400 response indicates a validation error - for example, a username that already exists, a password that does not meet the complexity requirements, or a missing required field.
{ "message": "Username already exists." }Next Steps
Recommended Order
- Read this guide fully to understand the conceptual model.
- Call GET /referencedata to discover valid field values for your account.
- Run through the end-to-end example against the test environment at https://apitest.amlhq.com.
- Consult the Swagger documentation for full parameter details on any specific endpoint.
- If you need an API key for server-to-server integrations, contact AML HQ to request one for your account.
Swagger Reference
| Environment | Swagger URL |
|---|---|
| Production - UK | https://api.amlhq.co.uk/swagger |
| Production - IE / Other | https://api.amlhq.com/swagger |
| Test | https://apitest.amlhq.com/swagger |
Error Handling
| Status | Meaning |
|---|---|
200 | Success |
400 | Validation error - body contains ResponseMessageModel with a message field |
401 | Token expired or invalid (re-authenticate). API key or username incorrect. |
404 | Resource does not exist in your account |
{ "message": "Client not found or you do not have access." }Getting an API Key
Contact the AML HQ team to request an API key for your account. See also Authentication in the Swagger docs.