Identity Hub API
The Identity Hub is the server-to-server API you use to register the people and businesses you want to monitor as entities, and to read back their risk state. Once an entity exists you can stream its events for scoring.
Base URL & authentication
All Identity Hub endpoints live under a single base URL — the same for sandbox and production:
https://trust.myaza.co/api/identityEvery endpoint requires a secret (sk_) key as a Bearer token — these are backend-only, server-to-server calls that read and write identity data, so a publishable (pk_) key is rejected with 403 secret_key_required.
curl "https://trust.myaza.co/api/identity/entities/user_42" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"The key identifies your organization and its environment; sk_test_ keys operate on sandbox data, sk_live_ on production. See Authentication.
Register or update an entity
POST /entities — create or update an entity, keyed by your own externalUserId. The call is idempotent: sending the same externalUserId again updates the existing entity rather than creating a duplicate.
Request
{
"externalUserId": "user_42",
"type": "INDIVIDUAL",
"kycProvenance": "MYAZA_VERIFIED",
"kycSource": null,
"profile": {
"fullName": "John Doe",
"dateOfBirth": "1990-01-01",
"nationality": "NG",
"idType": "bvn",
"idNumber": "12345678901",
"address": { "city": "Lagos", "country": "NG" },
"declaredMonthlyVolume": 500000,
"declaredTxnTypes": ["transfer", "deposit"],
"walletAddresses": [
{ "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "chain": "bitcoin", "label": "withdrawal" }
]
}
}| Field | Required | Notes |
|---|---|---|
externalUserId | Yes | Your own stable reference for the user. The entity's primary key within your org + environment. |
type | No | INDIVIDUAL (default) or BUSINESS. |
kycProvenance | No | How the entity was KYC'd: MYAZA_VERIFIED, EXTERNAL_VERIFIED, or UNVERIFIED (default). |
kycSource | No | Free-text label of the external KYC provider, when kycProvenance is EXTERNAL_VERIFIED. |
profile | No | Declared attributes — all optional. nationality and declared fields feed monitoring rules (e.g. cross-border). |
profile.walletAddresses | No | Up to 20 crypto wallet addresses ({ address, chain?, label? }, address 20–128 chars). Omit the key to leave the stored set unchanged; send an array (including []) to replace it. Attaching a wallet enrols the entity in WALLET screening; changing the set re-screens promptly. Wallets are risk attributes — never identity keys. |
Response
201 Created for a new entity, 200 OK for an update:
{
"entityId": "ent_01j9abc123",
"identityId": "idn_01j9xyz456",
"externalUserId": "user_42",
"kycProvenance": "MYAZA_VERIFIED",
"created": true,
"screening": { "status": "QUEUED", "types": ["SANCTIONS", "PEP"] }
}identityIdis the entity's link to a global identity — a person or company shared across organizations and environments. It'snulluntil resolution links one (see below).screeningreflects screening enrolment. It's the string"INACTIVE"when no screening provider is configured for your org — never a fakeQUEUED.
KYC provenance & identity resolution
When you declare an entity verified (MYAZA_VERIFIED or EXTERNAL_VERIFIED) and supply an ID (profile.idType + profile.idNumber), the Hub runs resolution: it links the entity to a global identity, matching an existing one where the ID is already known or creating a new one. UNVERIFIED entities skip resolution and stay unlinked.
A linked identity carries its own trustState (UNVERIFIED, VERIFIED, FLAGGED), risk tier, and the set of verified identifiers (e.g. BVN and NIN) the person has accumulated across your org.
Look up an entity
GET /entities/:externalUserId — fetch an entity by your own reference, scoped to the key's org and environment.
{
"entity": {
"entityId": "ent_01j9abc123",
"externalUserId": "user_42",
"identityId": "idn_01j9xyz456",
"type": "INDIVIDUAL",
"status": "ACTIVE",
"disposition": "APPROVED",
"kycProvenance": "MYAZA_VERIFIED",
"kycSource": null,
"kycVerifiedAt": "2026-04-27T12:00:00.000Z",
"riskTier": "LOW",
"riskScore": 12,
"createdAt": "2026-04-27T12:00:00.000Z",
"profile": { "fullName": "John Doe", "nationality": "NG" }
},
"identity": {
"id": "idn_01j9xyz456",
"type": "INDIVIDUAL",
"trustState": "VERIFIED",
"riskTier": "LOW",
"riskScore": 12
},
"identifiers": [
{ "idType": "bvn", "idNumber": "12345678901" }
],
"verifications": []
}identity and identifiers are populated only when the entity is linked. verifications is the entity's full KYC history (newest first). A missing entity returns 404 { "error": "entity_not_found" }.
Bulk import
For backfilling an existing user base, POST /entities/import accepts 1–1000 entities in one call. It's durable and asynchronous: the request is persisted and acknowledged with 202 immediately, then a worker processes each item in the background (nothing is lost on a restart).
Request
{
"entities": [
{ "externalUserId": "user_1", "type": "INDIVIDUAL", "kycProvenance": "EXTERNAL_VERIFIED", "kycSource": "acme-kyc" },
{ "externalUserId": "user_2", "type": "BUSINESS" }
]
}Each element uses the same shape as a single entity registration.
Response
{ "jobId": "job_01j9def789", "status": "PROCESSING", "total": 2 }Poll import progress
GET /entities/import/:jobId:
{
"jobId": "job_01j9def789",
"status": "COMPLETED",
"totalCount": 2,
"succeededCount": 2,
"failedCount": 0,
"pendingCount": 0,
"createdAt": "2026-04-27T12:00:00.000Z",
"completedAt": "2026-04-27T12:00:05.000Z",
"failures": []
}failures lists up to 50 failed items with externalUserId and an error string so you can retry them. An unknown job returns 404 { "error": "import_job_not_found" }.
Webhooks
Registering entities emits webhook events you can subscribe to:
| Event | When it fires | data |
|---|---|---|
entity.imported | A new entity was created. | entityId, identityId, externalUserId, environment |
identity.resolved | An entity was linked to a global identity (new or existing). | entityId, identityId, environment, matchedExisting |
Errors
| Status | Body | Cause |
|---|---|---|
400 | { "error": "invalid_request", "details": … } | The body failed validation; details is a field-level breakdown. |
401 | { "error": "Invalid API key" } | Missing, unknown, or revoked key. |
403 | { "error": "secret_key_required" } | A publishable (pk_) key was used — Identity Hub is secret-key only. |
404 | { "error": "entity_not_found" } | No entity with that externalUserId in this org + environment. |
See Errors for the platform-wide list.
Next steps
- Event monitoring — stream this entity's transactions for scoring.
- Screening — how watchlist enrolment and matches work.