Before you begin
You need an access token and your partner id. See Authentication and first request.
The X-Partner-Id header is required on every call below
and is checked against the OAuth principal. A mismatch returns
403. Any channelPartnerId in a request
body is ignored. It is derived from the header on the server.
Choosing a path
Three different questions, three different starting points. Pick the one that matches what you are trying to establish.
| You have | Start with | Why |
|---|---|---|
| A business with an ABN or ACN | Business lookup (KYB) | Confirm the business against ASIC and ABR records, then use the returned owners to create a verification request. The request skips manual structure review. |
| One or more individuals, and no business | This guide (KYC) | Create a verification request directly for one or more individuals. No business lookup or ownership review is required. |
| A trust, or ownership the registers do not hold | Trust deed analysis | Extract the trustees, beneficiaries, appointors and other controlling parties from the deed. Then create a verification request and confirm the structure. |
A business lookup answers two separable questions: does this company exist on ASIC, and who owns it. You can buy them apart. See choosing the depth.
Confirming the structure
A request built from a KYB lookup is already authoritative and moves
to READY_TO_SEND. A request you assembled yourself sits
in UBO_REVIEW until you confirm it, either with
structureConfirmed: true at create or afterwards:
PUT /v1/verifications/{id}/structure-confirmation
{ "confirmed": true }
You cannot mint links from UBO_REVIEW. This is the step
people miss on the trust path.
Party roles
role on an individual takes any value in the
VerificationRole
list. It covers offices (DIRECTOR,
OFFICER, SENIOR_MANAGING_OFFICIAL,
AUTHORISED_REP), ownership (UBO,
INDIVIDUAL_OWNER, PARTNER_MEMBER,
MEMBER) and the trust roles (TRUSTEE,
APPOINTOR, BENEFICIARY,
SETTLOR, PROTECTOR_GUARDIAN,
OTHER_CONTROLLER).
The trust roles are the same values
Deed Analysis returns, so a party
read off a deed can be added here unchanged. An unrecognised role is
stored as OTHER rather than rejected, so send a listed
value if you want it back. Use roleDescription for free
text.
Verification mode
mode |
What it is for |
|---|---|
AUSTRAC_CDD |
Customer due diligence on the individuals associated with an entity. This is the AML/CTF path, and the only mode the entity report renders for. |
TPB_POI |
Tax Practitioners Board proof of identity. |
1. Create the verification request
Start with a mode; it is the only required field. Do
not send firstName, lastName,
email or phone. Personal information is
collected from the customer through their verification link and
these fields return 400 if supplied here.
POST /v1/verifications
X-Partner-Id: YOUR_PARTNER_ID
Content-Type: application/json
{ "mode": "AUSTRAC_CDD" }
The fields you can send:
| Field | What it does |
|---|---|
mode |
AUSTRAC_CDD or TPB_POI. |
lookupRequestId |
Binds the request to a completed
KYB lookup. Admiin
creates one individual per discovered owner and the request
goes straight to READY_TO_SEND. The lookup must
be yours and COMPLETED, or you get
403 / 409. Automatic binding is
for FULL and UBO_ONLY lookups.
ASIC_ONLY returns
400 VALIDATION_ERROR; create deliberate manual
director parties instead.
|
individuals[] |
Optional. With a lookupRequestId, supply
idvEntityId values here to bind only a subset
of the owners; omit it to bind them all.
|
entityName |
Display only. On a lookup-bound request it defaults to the
completed lookup's entity name when omitted.
It does not trigger a KYB lookup. Use
lookupRequestId for that.
|
contactId |
Bills this verification to one of your contacts instead of your partner account. See Customer billing. |
structureConfirmed |
Confirms a hand-built party list at create. See confirming the structure. |
Binding a FULL or UBO_ONLY lookup is the
usual path:
{
"mode": "AUSTRAC_CDD",
"lookupRequestId": "3f0c…",
"entityName": "Acme Pty Ltd"
}
Supply your own externalId per individual if you need
one. That id, and the id Admiin returns, are how you stitch a result
back to your own record. There are no names to match on.
2. Mint the verification links
POST /v1/verifications/{id}/links
X-Partner-Id: YOUR_PARTNER_ID
Content-Type: application/json
{}
An empty body mints a link for every individual on the request. Pass
individualIds to mint for a subset only.
{
"individuals": [
{
"id": "iv_8c21…",
"externalId": "your-key-42",
"verificationUrl": "https://…"
}
]
}
This mints a fresh URL for every individual on the request, or for
the subset you list in individualIds, and returns them
in the response body. Status moves from DRAFT to
VERIFICATIONS_SENT.
Capture the URLs from this response. They are
returned here and nowhere else: never by webhook, never by
GET /v1/verifications/{id}, and never in a queryable
form. Only an HMAC-SHA-256 digest of the token is stored at rest.
3. Read the result
Terminal individual webhooks tell you when a person finishes:
verification.individual.passed, failed or
manual_review. See
Webhooks for signature validation and
retries.
GET /v1/verifications/{id}
X-Partner-Id: YOUR_PARTNER_ID
Use this to confirm terminal status after the webhook fan-out has run, or to poll if your receiver is briefly offline. It returns the itemised outcome for every individual on the request.
A lookup-bound response includes lookupRequestId on
create, get and list. Join each verification individual back to the
business lookup ownership graph by idvEntityId. The
lookup proves that the register identified the party; only a later
individual status of PASSED or
MANUALLY_PASSED means the identity was verified.
Rendering the result panel
GET /v1/verifications/{id} returns the data needed to
present verification results. How you display it is up to your
application.
| Field | Meaning |
|---|---|
riskLevel |
Overall risk level. |
completedAt |
When the verification completed. |
issueList |
Issues requiring attention. |
checkResults |
Per-check name, type, result, code and optional message. |
Treat checkResults[].checkType, result and
code as provider-defined strings and handle unknown
values. Request and individual status values are the
closed enums defined in the API reference.
Fetching evidence
The deep evidence behind a result is not in webhooks. Poll for it after you receive a terminal individual webhook. Two endpoints return it for an individual you own:
GET /v1/verifications/{id}/individuals/{individualId}/document-details
GET /v1/verifications/{id}/individuals/{individualId}/aml-matches
document-details returns the uploaded ID documents,
OCR-extracted fields, the applicant's claimed identity and the
biometric selfie comparison. Images are included by default; pass
?includeScans=false for OCR and metadata only.
aml-matches returns the matched-entity detail behind a
PEP, sanction, watchlist or adverse-media hit, plus KYC fraud-check
matches, in a single round-trip.
Both live-fetch from the screening service on each call and persist
nothing. Both always return 200 with a
status discriminator rather than a hard error, so
branch on status:
status |
Meaning |
|---|---|
OK |
Fetched successfully. The arrays may still be empty. |
NOT_AVAILABLE |
Nothing to fetch yet. The verification has not started, or the individual has no provider entity. |
UPSTREAM_UNAVAILABLE |
The screening service was temporarily unavailable, or the detail kill switch is on. Retry later. |
When a screening hit needs a decision recorded against it, see Reviewing AML matches.
For branded PDF records, see Verification reports.
Personal information
Evidence responses contain personal information, including document images, OCR fields and AML matched-entity detail.
Handle and store them in line with your own privacy policy, your data-handling obligations and the partner agreement.