curl --request POST \
--url https://app.instantcompliance.ai/api/v1/entities/{id}/kyb \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"method": "automated"
}
'import requests
url = "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb"
payload = { "method": "automated" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({method: 'automated'})
};
fetch('https://app.instantcompliance.ai/api/v1/entities/{id}/kyb', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'method' => 'automated'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb"
payload := strings.NewReader("{\n \"method\": \"automated\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.instantcompliance.ai/api/v1/entities/{id}/kyb")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"method\": \"automated\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.instantcompliance.ai/api/v1/entities/{id}/kyb")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"method\": \"automated\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"external_id": "crm-ent-311",
"type": "COMPANY",
"name": "Acme Holdings Pty Ltd",
"origin": "AUSTRALIAN",
"abn": "12345678901",
"acn": "123456789",
"country_of_formation": "AUS",
"registration_number": null,
"kyb_status": "IN_PROGRESS",
"kyb_started_at": "2026-06-23T01:00:00Z",
"kyb_completed_at": null,
"contact": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "crm-7741",
"full_name": "Jane Doe",
"email": "jane@example.com",
"kyc_status": "PENDING",
"kyc_required": true
},
"aml": {
"status": "CLEAR",
"screened_at": "2026-06-23T01:12:00Z",
"last_reviewed_at": null,
"flags": {
"pep": false,
"sanctions": false,
"adverse_media": false,
"terrorism": false
}
},
"added_via": "INTEGRATION",
"created_at": "2026-06-22T22:14:00Z",
"updated_at": "2026-06-23T01:12:05Z"
}{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
}
}{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits to start this verification."
}
}{
"error": {
"code": "feature_disabled",
"message": "The Groups feature is not enabled for this organisation. Contact support to enable it.",
"details": {
"feature": "Groups"
}
}
}{
"error": {
"code": "not_found",
"message": "Customer not found."
}
}{
"error": {
"code": "conflict",
"message": "KYB verification has already been started for this customer."
}
}{
"error": {
"code": "validation_failed",
"message": "Invalid customer payload.",
"details": {
"issues": {
"email": [
"Must be a valid email address."
]
}
}
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Slow down and retry shortly.",
"details": {
"limit": 60,
"window_seconds": 60
}
}
}Start an entity's KYB
Start business verification (KYB) for an entity — the same lane flows
the app runs, selected by method. This spends credits (or bills
the customer) on the emailing lanes.
automated(default) emails the entity’s contact a secure link to upload the entity document, which you then review (“org-led”). Charges.contact_ledemails the contact to complete the whole flow. Charges. Requires thekyb_extra_methodsfeature — otherwise403 feature_disabled.manualarms the record for an officer to collect/upload the document (company), or manages a trust/partnership by hand. No charge, no email. Trust and partnership entities support onlymanual.
Payer follows the entity record’s billing default unless payer
overrides it; the customer-paid lanes arm payment-pending and email the
pay link.
Requires the verification:write scope. Include an Idempotency-Key
header to make retries safe for 24 hours.
curl --request POST \
--url https://app.instantcompliance.ai/api/v1/entities/{id}/kyb \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"method": "automated"
}
'import requests
url = "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb"
payload = { "method": "automated" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({method: 'automated'})
};
fetch('https://app.instantcompliance.ai/api/v1/entities/{id}/kyb', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'method' => 'automated'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.instantcompliance.ai/api/v1/entities/{id}/kyb"
payload := strings.NewReader("{\n \"method\": \"automated\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.instantcompliance.ai/api/v1/entities/{id}/kyb")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"method\": \"automated\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.instantcompliance.ai/api/v1/entities/{id}/kyb")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"method\": \"automated\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"external_id": "crm-ent-311",
"type": "COMPANY",
"name": "Acme Holdings Pty Ltd",
"origin": "AUSTRALIAN",
"abn": "12345678901",
"acn": "123456789",
"country_of_formation": "AUS",
"registration_number": null,
"kyb_status": "IN_PROGRESS",
"kyb_started_at": "2026-06-23T01:00:00Z",
"kyb_completed_at": null,
"contact": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "crm-7741",
"full_name": "Jane Doe",
"email": "jane@example.com",
"kyc_status": "PENDING",
"kyc_required": true
},
"aml": {
"status": "CLEAR",
"screened_at": "2026-06-23T01:12:00Z",
"last_reviewed_at": null,
"flags": {
"pep": false,
"sanctions": false,
"adverse_media": false,
"terrorism": false
}
},
"added_via": "INTEGRATION",
"created_at": "2026-06-22T22:14:00Z",
"updated_at": "2026-06-23T01:12:05Z"
}{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
}
}{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits to start this verification."
}
}{
"error": {
"code": "feature_disabled",
"message": "The Groups feature is not enabled for this organisation. Contact support to enable it.",
"details": {
"feature": "Groups"
}
}
}{
"error": {
"code": "not_found",
"message": "Customer not found."
}
}{
"error": {
"code": "conflict",
"message": "KYB verification has already been started for this customer."
}
}{
"error": {
"code": "validation_failed",
"message": "Invalid customer payload.",
"details": {
"issues": {
"email": [
"Must be a valid email address."
]
}
}
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Slow down and retry shortly.",
"details": {
"limit": 60,
"window_seconds": 60
}
}
}method. Unlike ingest, the emailing lanes spend
credits (or bill the customer), so this needs the separate
verification:write scope.
Lanes
automated(default, “org-led”) — emails the entity’s contact a secure link to upload the entity document, which you then review. Charges. Returns the link asverification_link.contact_led— emails the contact to complete the whole flow themselves. Charges. Requires thekyb_extra_methodsfeature — otherwise you get403 feature_disabled.manual— arms the record for an officer to collect/upload the document (company), or to manage a trust/partnership by hand. No charge, no email.
manual — they have no
emailing lane.Who pays
payer is optional and works exactly as for KYC:
omit to honour the entity record’s default, or set payer: customer to
arm payment-pending and email the pay link. Manual lanes never charge, so
payer has no effect there.
Errors worth handling
402 insufficient_credits— no credits for an org-paid emailing lane; nothing armed or charged.403 feature_disabled—contact_ledrequested while the feature is off for your org.409 conflict— a verification has already been started for this entity.422 validation_failed— a precondition is missing (e.g. no contact person with an email for an emailing lane).
Idempotency-Key header so a retried start is not run twice.Authorizations
Bearer API key issued from Settings → Developers in your
Instant Compliance organisation. Format: ic_live_….
Headers
Caller-supplied unique key for safe retries. Repeat the same key within 24 hours and we replay the original response instead of repeating the side effect. Reusing the key with a different request body returns 409 idempotency_conflict.
255Path Parameters
Entity identifier. Accepts either Instant Compliance's UUID or your
own external_id.
Body
Options for starting an entity's KYB. All fields optional.
automated (org-led) and contact_led email the contact and
charge; manual arms for officer upload / trust-partnership
handling and does not charge. Trust and partnership entities support
only manual.
automated, contact_led, manual Who pays for the check. Omit to honour the customer record's own
billing default. customer arms the check payment-pending and emails a
pay link — the customer pays by card at the portal.
organization, customer Optional note included in the verification email.
2000Optional enhanced due-diligence add-ons (emailing lanes).
An enhanced due-diligence add-on check.
SOURCE_OF_FUNDS, SOURCE_OF_WEALTH, BIOMETRIC_VERIFICATION Response
The entity record after arming, plus verification_link when a
portal link was generated (the emailing lanes).
Instant Compliance customer UUID (entities are customers too).
Entity customer types accepted by /entities. SMSF is treated
as a type of trust and OTHER as a company for verification
purposes, but the type you post round-trips back unchanged.
Immutable after creation.
COMPANY, TRUST, PARTNERSHIP, SMSF, OTHER The entity's legal name.
Where the entity is formed. AUSTRALIAN (the default) uses
ABN/ACN identifiers; INTERNATIONAL uses countryOfFormation +
registrationNumber. Immutable after creation.
AUSTRALIAN, INTERNATIONAL NOT_STARTED, PENDING, IN_PROGRESS, VERIFIED, FAILED, NOT_REQUIRED, AWAITING_RESUBMISSION Show child attributes
Show child attributes
How the record entered Instant Compliance.
ADMIN_MANUAL, AI_EXTRACTED, CONTACT_PORTAL, BULK_IMPORT, INTEGRATION, SYSTEM ISO 3166-1 alpha-3. AUS for Australian entities; the country
of formation for international entities.
Registry number recorded for international entities.
The entity's current contact person, or null when none is set.
Show child attributes
Show child attributes
Shareable portal link (emailing lanes only).

