Onboarding Webhooks
All onboarding events follow the platform's standard webhook envelope (same delivery format, authentication, retries and idempotency). This page documents the accreditation-specific events.
Events
| Event | When it is emitted |
|---|---|
accreditation.pf.created | A PF accreditation was created. |
accreditation.pj.created | A PJ accreditation was created. |
accreditation.biometry.link.created | A facial capture link was generated for a person (emitted per person; re-emitted on retry). |
accreditation.acceptance.link.created | An acceptance link was generated for a person (BYO biometrics flow only). |
accreditation.consent.link.created | An authorization link was generated because the CPF already has an account (re-emitted on retry). |
account.shared_access.granted | Another tenant started operating an account you already operated, authorized by the holder. |
accreditation.updated | Every state transition of the accreditation. Source of truth for progress. |
accreditation.active | Account opened successfully — accountId ready to operate. |
accreditation.failed | Process ended without opening an account. |
Subscribe to accreditation.updated as the source of truth for progress, and use accreditation.active / accreditation.failed as terminal triggers in your system. The link events are meant to automate delivering links to end users.
callbackUri does not replace these eventsIf you use the return to your app, the outcome that arrives in the URI is a UI hint: it travels in the address bar and the holder can edit it. Use it only to decide which screen to show when the user comes back. Every trigger with an effect in your system still comes from here — or from GET /v1/accreditations/{accreditationId}.
accreditation.updated
Emitted on every state transition, with the previous status, the current one and per-person details.
{
"id": "evt_acr_upd_001",
"type": "accreditation.updated",
"occurredAt": "2026-07-07T18:20:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accreditationId": "acr_9f8e7d6c5b4a",
"type": "pf",
"document": "12345678901",
"previousStatus": "PENDING_BIOMETRY",
"status": "INTEGRATING",
"persons": [
{
"cpf": "12345678901",
"name": "Maria da Silva",
"biometryStatus": "APPROVED"
}
]
}
}
data field | Description |
|---|---|
accreditationId | Accreditation ID. |
type | pf or pj. |
document | Holder's CPF (PF) or CNPJ (PJ). |
previousStatus / status | State transition (vocabulary from the Overview). |
persons[] | Per-person details: cpf, name, biometryStatus (PENDING, APPROVED, FAILED, EXPIRED) and, in the BYO flow, acceptanceStatus (PENDING, ACCEPTED). |
errorReason | Present when status = FAILED. |
accreditation.biometry.link.created
Emitted when a facial capture link is generated for a person (at accreditation creation and on each retry).
{
"id": "evt_acr_link_001",
"type": "accreditation.biometry.link.created",
"occurredAt": "2026-07-07T18:00:05.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accreditationId": "acr_9f8e7d6c5b4a",
"type": "pf",
"cpf": "12345678901",
"name": "Maria da Silva",
"biometryLink": "https://cadastro.unico.app/process/abc123...",
"linkExpiresAt": "2026-07-14T18:00:00Z"
}
}
For PJ, this event is emitted once per partner — use the cpf to know who each link belongs to.
accreditation.acceptance.link.created
BYO biometrics flow only. Emitted when the acceptance link is generated for a person.
{
"id": "evt_acr_acc_001",
"type": "accreditation.acceptance.link.created",
"occurredAt": "2026-07-07T18:05:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accreditationId": "acr_9f8e7d6c5b4a",
"type": "pf",
"cpf": "12345678901",
"name": "Maria da Silva",
"acceptanceLink": "https://tenant.api.corpx.com/v1/accreditations/accept/tok_...",
"linkExpiresAt": "2026-07-14T18:00:00Z"
}
}
accreditation.consent.link.created
Emitted when the CPF already has an account and the accreditation starts as PENDING_CONSENT: instead of opening a new account, the holder must authorize you to operate the existing one. Deliver the consentLink to them. Re-emitted on every retry.
{
"id": "acr-acr_5c4b3a2f1e0d-consent-12345678901-1",
"type": "accreditation.consent.link.created",
"occurredAt": "2026-07-23T18:00:05.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"data": {
"accreditationId": "acr_5c4b3a2f1e0d",
"type": "pf",
"cpf": "12345678901",
"name": "Maria da Silva",
"consentId": "cns_8f2a1c9d4b70",
"consentLink": "https://tenant.api.corpx.com/v1/accreditations/consent/cst_...",
"linkExpiresAt": "2026-07-30T18:00:00Z",
"status": "PENDING_CONSENT"
}
}
Journey details in Holder who already has an account.
accreditation.active
Terminal success event — the account is ready to operate.
{
"id": "evt_acr_active_001",
"type": "accreditation.active",
"occurredAt": "2026-07-07T18:25:41.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accreditationId": "acr_9f8e7d6c5b4a",
"type": "pf",
"document": "12345678901",
"status": "ACTIVE",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8"
}
}
When the accreditation came from the consent flow, data carries two extra fields:
data field | Description |
|---|---|
sharedAccount | true — the account already existed and remains operated by whoever the holder had already authorized. Balance and statement are shared. |
partnerAccountId | Holder identifier at the settlement partner, common to every authorized tenant. Useful for reconciliation. |
account.shared_access.granted
Emitted to the tenants that already operated an account when the holder authorizes a new tenant to operate it too. Your access does not change — this event exists so that you know the account is now being moved by someone else as well.
{
"id": "acr-acr_5c4b3a2f1e0d-shared-tenant-acme",
"type": "account.shared_access.granted",
"occurredAt": "2026-07-23T18:40:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"tenantId": "tenant-acme",
"partnerAccountId": "hld_7c1e...",
"grantedAt": "2026-07-23T18:40:00Z",
"reason": "account_holder_authorized_another_tenant"
}
}
data field | Description |
|---|---|
accountId | Your account (the identifier you already use), not the one of the tenant that joined. |
partnerAccountId | Holder at the settlement partner — this is what evidences it is the same account. |
grantedAt | Moment of the holder's authorization. |
reason | account_holder_authorized_another_tenant. |
If the sharing does not make sense for your case, contact support: the holder can revoke the granted access, and from then on the revoked tenant's calls for that account return 403.
accreditation.failed
Terminal failure event — the process ended without opening an account.
{
"id": "evt_acr_failed_001",
"type": "accreditation.failed",
"occurredAt": "2026-07-08T10:00:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"accountId": "c283eb5a-58da-47ef-844a-f36e51f078d8",
"data": {
"accreditationId": "acr_9f8e7d6c5b4a",
"type": "pf",
"document": "12345678901",
"status": "FAILED",
"errorReason": "biometry_expired",
"errorMessage": "Facial biometrics not completed within the 7-day deadline"
}
}
Common errorReason values:
errorReason | Meaning |
|---|---|
biometry_failed | Facial biometrics rejected. |
biometry_expired | Facial link expired without completion. |
evidence_invalid | BYO evidence not validated with the partner (BYO flow). |
acceptance_timeout | Acceptance term not confirmed in time (BYO flow). |
cancelled | Cancelled by the integrator via POST /v1/accreditations/{id}/cancel (still PENDING_BIOMETRY or PENDING_CONSENT). |
review_rejected | Rejected during prior review. |
partner_rejected | Rejected by the settlement partner during account opening. |
consent_declined | The holder declined to authorize access to the account they already had. |
consent_expired | The holder did not complete the authorization in time (7-day link, 30-day journey). |
consent_facial_failed | The identity verification did not confirm the person as the CPF holder. |
consent_link_failed | The authorization could not be prepared or completed (e.g. holder data diverged between the request and the authorization). Contact support. |
castle_deny | The device risk assessment blocked the acceptance — both on the BYO acceptance term and on the portability authorization. Contact support. |
existing_partner_account | CPF/CNPJ that already has an account. Portability is manual: the holder must request it from support. For PF, if your tenant has automatic portability enabled, this reason does not occur — the path is the consentLink. There is no hosted authorization flow for PJ. |
accreditation.pf.created / accreditation.pj.created
Emitted when the accreditation is created (workflow start), as an asynchronous confirmation of the POST. Subscribe in the portal (Settings → Webhooks) or via PUT on the subscription.
{
"id": "acr-acr_1a2b3c4d5e6f-created",
"type": "accreditation.pj.created",
"occurredAt": "2026-07-07T18:00:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-acme",
"data": {
"accreditationId": "acr_1a2b3c4d5e6f",
"type": "pj",
"document": "12345678000199",
"status": "PENDING_BIOMETRY",
"biometryMode": "external"
}
}