Verification

Create a verification request, send each person a link, then read the result and the evidence behind it.

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.

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.