Before you begin
You need an access token and your partner id. See Authentication and first request.
A KYB lookup tells you who to verify. It does not verify anyone. Once you have the owner list, run Verification on the individuals.
Submit a lookup
POST /v1/business-lookups
X-Partner-Id: YOUR_PARTNER_ID
Content-Type: application/json
{ "abn": "51824753556" }
Supply an ABN or an ACN. The call returns
202 immediately with a lookupRequestId.
The resolved owner list arrives asynchronously in the
business-lookup.completed webhook. Correlate on that
id.
Choosing the depth
scope controls what runs. Confirming the company exists
on ASIC is separate from tracing who owns it.
scope |
What runs |
|---|---|
FULLdefault |
ASIC organisation verification and the multi-level UBO report. |
ASIC_ONLY |
ASIC organisation verification only. It does not run the
multi-level UBO report, but the register result can still
include directors in individuals[]. Use each
party's role and partyCounts.
|
UBO_ONLY |
Multi-level UBO and ownership report only. |
Omitting scope is the same as FULL. The
selected scope is returned by
GET /v1/business-lookups/{id}.
Pick ASIC_ONLY when you already know the owners and
only need the company confirmed. Pick UBO_ONLY when the
company is already confirmed and you only need the ownership tree.
Reading the result
The business-lookup.completed webhook tells you the
lookup finished and carries one individuals[] entry per
discovered owner.
{
"type": "business-lookup.completed",
"lookupRequestId": "3f0c…",
"entity": { "name": "Acme Pty Ltd", "type": "COMPANY" },
"individuals": [{ "idvEntityId": "idv_9a71…" }]
}
The webhook entries carry only an
idvEntityId.
Owner names and roles are left out of it deliberately, for data
minimisation. The array is always present even when empty, so
Array.isArray consumers do not have to special-case it.
If you need the names and roles, pull them from the authenticated endpoint. They are on the record, just not in the webhook:
GET /v1/business-lookups/{id}
X-Partner-Id: YOUR_PARTNER_ID
This is also the polling fallback if you do not subscribe to the webhook. The row must be owned by you.
{
"status": "COMPLETED",
"scope": "ASIC_ONLY",
"partyCounts": {
"beneficialOwners": 0,
"directors": 2,
"officers": 0,
"total": 2
},
"individuals": [
{ "role": "DIRECTOR", "idvEntityId": "idv_9a71…" }
]
}
uboCount is retained for compatibility, but historic
values can count directors as well as UBOs. Use
partyCounts.beneficialOwners for a UBO total and
partyCounts.directors for the ASIC finding.
entity.name is the ASIC registered name, falling back
to the ABR name.
For a sole trader that is a natural person's name,
because that is what the register holds. Treat it as personal
information and handle it under the same controls as the
individuals.
Chaining into verification
Bind a completed FULL or UBO_ONLY lookup,
and Admiin creates one individual per discovered owner:
{ "mode": "AUSTRAC_CDD", "lookupRequestId": "3f0c…" }
Or bind a chosen subset by listing their ids:
{
"mode": "AUSTRAC_CDD",
"lookupRequestId": "3f0c…",
"individuals": [{ "idvEntityId": "idv_9a71…" }]
}
You do not need names to do this. idvEntityId is what
links the owner the register found to the person you verify.
An ASIC_ONLY lookup cannot be bound automatically. It
confirms the organisation and may return directors for display, but
it does not establish the beneficial-ownership structure. Create
deliberate manual verification parties instead; attempting to bind
the lookup returns 400 VALIDATION_ERROR at
/lookupRequestId.
A verification created from a lookup carries the register record, so
it is treated as authoritative: the request goes to
READY_TO_SEND rather than sitting in
UBO_REVIEW. It is also the only way the entity report
can print registry identity. A hand-built request renders an
explicit "register data not available" note instead.
Curate the list before you submit it. Nothing forces you to verify every owner the report returned.
Rendering registry and ownership views
Read company facts from
GET /v1/business-lookups/{id}/registry and the tree
from GET /v1/business-lookups/{id}/ownership. The three
timestamps answer different questions:
-
updatedAt— when the lookup record last changed -
structureAsOf— when the ownership structure was determined retrievedAt— when the registry panel was read
A successful response does not prove a complete tree. Show a high
completeness state only when ownershipSource is
AVAILABLE, complete is true,
truncated is false and unlinkedOwners[] is
empty. Show partial when blocked nodes, unlinked owners or
truncation are present. Show unknown when
traversalComplete is null, the reason is
UNKNOWN, no graph exists or the source is unavailable.
The lookup identifies register parties; it does not verify their
identities. To show a Verified status, read the later verification
request and join the person by idvEntityId. Treat only
PASSED and MANUALLY_PASSED as verified.
A live ownershipSource: AVAILABLE response includes the
compliance-relevant structured names, dates of birth, addresses and
screening summary returned by the live read. Verification provider
names, internal request/check identifiers and raw provider payloads
are removed. Identity-document and biometric evidence remains on the
verification evidence endpoints. Cache a response for the current
page or session to conserve the per-lookup daily read budget.
A refresh is a new paid POST /v1/business-lookups.
Re-reading the registry or ownership routes does not determine a
fresh structure, so show the price before starting a refresh.
When the registers hold nothing
A trust's controlling parties are exactly what ASIC and the ABR cannot tell you. A lookup on a trust returns nothing useful. That is the register being complete, not the lookup failing.
For a trust, read the parties out of the deed instead. See Trust deed analysis, then build the verification from the parties it extracts and confirm the structure yourself.
Billing
A lookup is billed to your partner account by default. To bill your
own customer instead, pass contactId and see
Customer billing.
If the billing gate blocks the call you get
PAYMENT_METHOD_REQUIRED,
CONTACT_BILLING_BLOCKED or
CONTACT_INVALID. No lookup runs and no charge is
written.