Skip to main content

Customer Event

Overview

The Customer webhook event is triggered when a customer completes Noah's hosted onboarding form, after being directed to the hosted URL returned by the Hosted Onboarding API, as well as when the customer's hosted onboarding status changes.

A Customer can have one the following statuses at a given time:

  • Pending
  • Approved
  • Declined

Once the Customer's Verification status is Approved, any of Noah's transactional flows can be used.

To configure a Customer webhook subscription, reference the Webhook Configuration page.

How Webhooks Relate to FiatOptions

When you call the Hosted Onboarding API, you can specify one or more FiatOptions (currencies) that you want the customer to be verified for. For each FiatOption provided, Noah will fire a separate Pending webhook once the customer begins the onboarding process.

The Verifications object in each webhook payload indicates which specific FiatOption that webhook relates to, allowing you to track the verification status for each currency independently.

Typical Onboarding Flow

Understanding the webhook firing sequence is crucial for properly implementing your webhook handlers.

Here's what to expect during the customer onboarding flow:

  1. Call the Hosted Onboarding API with one or more FiatOptions (e.g., ["USD", "EUR"])
  2. Customer begins onboarding - Noah immediately fires one Pending webhook per FiatOption
  3. Customer completes the onboarding form and submits their information
  4. Verification processing occurs (typically within seconds)
  5. Final webhook(s) arrive with either:
    • Approved status - customer passed automated verification (happy path)
    • Declined status - customer failed automated verification
    • Status remains Pending - customer requires manual review

Timeline Expectations

Happy Path (Automated Approval):

  • Initial Pending webhooks: Fired immediately when customer starts onboarding
  • Approved webhooks: Typically arrive within 5-15 seconds after customer submission
  • You'll receive one webhook per FiatOption for each status change

Manual Review Scenario: When a customer's submission requires manual review (due to unclear documentation, risk factors, or verification ambiguity):

  • Initial Pending webhooks arrive immediately
  • Status remains Pending while under manual review
  • No additional webhooks are sent until review is complete
  • Once review completes, you'll receive Approved or Declined webhooks

Important: Always implement webhook handling that can process multiple webhooks per customer, especially when using multiple FiatOptions.

Verifications Object Structure

Each webhook contains a Verifications object. The status provided in the main Verifications object is the overall compliance status. The main compliance status becomes Approved when a user has at least one approved entity. It will be Declined if a user is offboarded and is no longer able to transact (non-retryable).

An individual EntityVerification status reflects a status for that particular entity. If it's Declined there, users can retry verifications for that specific entity, e.g., a blurry document for example; it doesn't impact the other entities that are already approved. If one single entity is approved, the main status would also be Approved.

"Verifications": {
"EntityVerifications": [
{
"Created": "2025-05-28T20:52:32Z",
"Entity": "Lt",
"Model": "Standard",
"Modified": "2025-05-28T20:52:32Z",
"Status": "Approved"
},
{
"Created": "2025-05-28T20:53:18Z",
"Entity": "Us",
"Model": "Standard",
"Modified": "2025-05-28T20:53:20Z",
"Status": "Pending"
}
],
"Status": "Approved",
"Type": "Individual"
}

Field Descriptions:

  • Entity: Noah's geographical jurisdiction, Us (USA), Lt (EU), or Ca (Canada)
  • Model: Verification method - Standard (verified by Noah) or Reliance (reliance model)
  • Status: Current verification status - Pending, Approved, or Declined

Event Payload Structure

Example: Pending Status

When a Customer event occurs with status Pending, Noah sends a webhook notification to your configured endpoint with the following JSON payload:

{
"Data": {
"Created": "2025-05-28T20:52:32Z",
"CustomerID": "20531",
"DateOfBirth": "2005-11-29",
"FullName": {
"FirstName": "John",
"LastName": "Mock-Doe"
},
"Identities": [
{
"ExpiryDate": "2026-05-19",
"IDNumber": "Mock-CAZQSUG0SL",
"IDType": "Passport",
"IssuedDate": "2016-01-17",
"IssuingCountry": "DE"
}
],
"PrimaryResidence": {
"City": "Test",
"Country": "DE",
"PostCode": "TT1TT0",
"State": "Test",
"Street": "Test Road"
},
"Type": "Individual",
"Verifications": {
"EntityVerifications": [
{
"Created": "2025-05-28T20:52:32Z",
"Entity": "Lt",
"Model": "Standard",
"Modified": "2025-05-28T20:52:32Z",
"Status": "Pending"
}
],
"Status": "Pending",
"Type": "Individual"
}
},
"EventType": "Customer",
"EventVersion": 1748465552988,
"Occurred": "2025-05-28T20:52:33Z",
"UserID": "ory|99be1afe-7018-4a7c-be0e-5ab06bdee8c6"
}

Example 2: Approved Status

When the status is Approved, Noah sends a webhook notification to your configured endpoint with the following JSON payload:

{
"Data": {
"Created": "2025-05-28T20:52:32Z",
"CustomerID": "20531",
"DateOfBirth": "2005-11-29",
"FullName": {
"FirstName": "John",
"LastName": "Mock-Doe"
},
"Identities": [
{
"ExpiryDate": "2026-05-19",
"IDNumber": "Mock-CAZQSUG0SL",
"IDType": "Passport",
"IssuedDate": "2016-01-17",
"IssuingCountry": "DE"
}
],
"PrimaryResidence": {
"City": "Test",
"Country": "DE",
"PostCode": "TT1TT0",
"State": "Test",
"Street": "Test Road"
},
"Verifications": {
"EntityVerifications": [
{
"Created": "2025-05-28T20:52:32Z",
"Entity": "Lt",
"Model": "Standard",
"Modified": "2025-05-28T20:52:32Z",
"Status": "Approved"
}
],
"Status": "Approved",
"Type": "Individual"
}
},
"EventType": "Customer",
"EventVersion": 1748465552988,
"Occurred": "2025-05-28T20:52:33Z",
"UserID": "ory|99be1afe-7018-4a7c-be0e-5ab06bdee8c6"
}

Example 3: Declined Status

When the status is Declined, Noah sends a webhook notification to your configured endpoint with the following JSON payload:

{
"Data": {
"Created": "2025-05-28T20:52:32Z",
"CustomerID": "20531",
"DateOfBirth": "2005-11-29",
"FullName": {
"FirstName": "John",
"LastName": "Mock-Doe"
},
"Identities": [
{
"ExpiryDate": "2026-05-19",
"IDNumber": "Mock-CAZQSUG0SL",
"IDType": "Passport",
"IssuedDate": "2016-01-17",
"IssuingCountry": "DE"
}
],
"PrimaryResidence": {
"City": "Test",
"Country": "DE",
"PostCode": "TT1TT0",
"State": "Test",
"Street": "Test Road"
},
"Type": "Individual",
"Verifications": {
"EntityVerifications": [
{
"Created": "2025-05-28T20:52:32Z",
"Entity": "Lt",
"Model": "Standard",
"Modified": "2025-05-28T20:52:32Z",
"Status": "Declined"
}
],
"Status": "Declined",
"Type": "Individual"
}
},
"EventType": "Customer",
"EventVersion": 1748465552988,
"Occurred": "2025-05-28T20:52:33Z",
"UserID": "ory|99be1afe-7018-4a7c-be0e-5ab06bdee8c6"
}