Documentation Index
Fetch the complete documentation index at: https://docs.nedzo.ai/llms.txt
Use this file to discover all available pages before exploring further.
Nedzo emits a set of platform lifecycle webhooks when key things happen on an account: a user signs up, finishes onboarding, a new workspace is created, a user is invited, or a subscription changes. These are separate from the Post-conversation webhook (which fires per conversation) and the Workflow webhook trigger (which sends data into Nedzo).
Use these events to sync your CRM, send transactional emails on signup, or trigger downstream automations when teams grow.
Lifecycle webhooks are configured per environment by Nedzo for whitelabel and enterprise customers. If you’d like to receive these events on your own endpoint, contact support@nedzo.ai with the URL you want them delivered to.
Delivery semantics
- Fire-and-forget. Nedzo sends the request but does not retry on failure. Failures are logged but never surfaced to the user-triggering action (e.g. signup is not blocked if your endpoint is down).
- Timeout. The request is aborted if your server takes longer than 10 seconds to respond.
- Auth header. When configured, Nedzo includes the shared token in an
Auth header. Use it to verify the request source.
- HTTPS only in production. Nedzo rejects non-HTTPS URLs and internal IPs/metadata endpoints (SSRF protection).
- Order. Events are sent in the order the underlying actions occur, but no ordering guarantee across events of different types.
Common request shape
All lifecycle events are sent as POST with Content-Type: application/json. The body schema is event-specific (see below). UTM/referrer fields are truncated server-side: 255 chars max for source/medium/campaign/code, 2048 chars max for URLs.
Events
| Event | Fires when |
|---|
registration_started | A new user finishes the welcome-email step during signup, before onboarding completes. Top-of-funnel signal. |
registration_completed | A new user finishes onboarding (account + workspace + user record all created). |
workspace_added | A workspace is created in an existing account (excludes the initial workspace from onboarding). |
user_added | A user is invited and accepted into an existing account (excludes the initial owner from onboarding, and excludes restoring a soft-deleted user). |
subscription_started | A paid subscription begins on an account. |
subscription_cancelled | A subscription is cancelled on an account. |
registration_started
Fires when a new user is sent the welcome email — before they complete onboarding. Lacks account context for self-serve signups (no account row exists yet) but includes account_id when the user signs up under an existing whitelabel account.
Payload:
| Field | Type | Description |
|---|
user_first_name | string | New user’s first name. |
user_last_name | string | New user’s last name. |
user_email | string | New user’s email. |
user_phone | string | null | Phone if provided at signup. |
user_signup_date | string (ISO date) | Date the welcome email was sent (YYYY-MM-DD). |
account_id | string (UUID) | null | Account ID for whitelabel signups, null for self-serve. |
user_referrer_code | string | null | Referral code captured at signup. |
user_referrer_source | string | null | UTM source. |
user_referrer_medium | string | null | UTM medium. |
user_referrer_campaign | string | null | UTM campaign. |
user_referrer_url | string | null | Full referrer URL. |
Example:
{
"user_first_name": "John",
"user_last_name": "Doe",
"user_email": "john@example.com",
"user_phone": "+14155551234",
"user_signup_date": "2026-04-25",
"account_id": null,
"user_referrer_code": "PARTNER42",
"user_referrer_source": "google",
"user_referrer_medium": "cpc",
"user_referrer_campaign": "spring-2026",
"user_referrer_url": "https://google.com/search?q=ai+voice+agent"
}
registration_completed
Fires when a user finishes onboarding — account, workspace, and user records all exist and the user has reached the dashboard. Includes full account context so downstream CRM sync can attribute the signup to the right account.
Payload:
| Field | Type | Description |
|---|
user_first_name | string | User’s first name. |
user_last_name | string | User’s last name. |
user_email | string | User’s email. |
user_phone | string | null | Phone if captured. |
user_signup_date | string (ISO date) | Date onboarding completed (YYYY-MM-DD). |
account_id | string (UUID) | Account the user belongs to. |
user_id | string (UUID) | User record ID. |
account_name | string | null | Account / company name set during onboarding. |
plan | string | null | Subscription plan selected during onboarding. Re-read from the persisted account record after Stripe writes complete; 'payg' for pay-as-you-go signups, null if no plan was persisted. |
industry | string | null | Industry selected during onboarding. |
user_referrer_code | string | null | Referral code. |
user_referrer_source | string | null | UTM source. |
user_referrer_medium | string | null | UTM medium. |
user_referrer_campaign | string | null | UTM campaign. |
user_referrer_url | string | null | Full referrer URL. |
Example:
{
"user_first_name": "John",
"user_last_name": "Doe",
"user_email": "john@example.com",
"user_phone": "+14155551234",
"user_signup_date": "2026-04-25",
"account_id": "a1b2c3d4-1111-2222-3333-444455556666",
"user_id": "u1u2u3u4-aaaa-bbbb-cccc-ddddeeeeffff",
"account_name": "Acme Co",
"plan": "pro",
"industry": "real_estate",
"user_referrer_code": "PARTNER42",
"user_referrer_source": "google",
"user_referrer_medium": "cpc",
"user_referrer_campaign": "spring-2026",
"user_referrer_url": "https://google.com/search?q=ai+voice+agent"
}
workspace_added
Fires when a workspace is created on an existing account. Skipped for the initial workspace created during onboarding (that signal is implicit in registration_completed). Fires for workspaces created via the dashboard and via the public API.
Payload:
| Field | Type | Description |
|---|
account_id | string (UUID) | Account that owns the workspace. |
account_name | string | null | Account name. |
workspace_id | string (UUID) | Workspace record ID. |
workspace_name | string | null | Workspace name as set by the user. |
total_workspaces | number | Total number of non-deleted workspaces on the account after this one was added. |
Example:
{
"account_id": "a1b2c3d4-1111-2222-3333-444455556666",
"account_name": "Acme Co",
"workspace_id": "w1w2w3w4-aaaa-bbbb-cccc-ddddeeeeffff",
"workspace_name": "EU Operations",
"total_workspaces": 3
}
user_added
Fires when a user is invited and added to an existing account. Skipped for the initial owner (covered by registration_completed) and for re-invites of soft-deleted users (the restored path) so team-size growth isn’t double-counted in the CRM.
Payload:
| Field | Type | Description |
|---|
account_id | string (UUID) | Account the user joined. |
account_name | string | null | Account name. |
user_id | string (UUID) | New user record ID. |
user_first_name | string | null | User’s first name. |
user_last_name | string | null | User’s last name. |
user_email | string | User’s email. |
user_phone | string | null | Phone if provided on the invite (optional field on the invite payload). |
total_users | number | Total number of non-deleted users on the account after this one was added. |
Example:
{
"account_id": "a1b2c3d4-1111-2222-3333-444455556666",
"account_name": "Acme Co",
"user_id": "u9u8u7u6-aaaa-bbbb-cccc-ddddeeeeffff",
"user_first_name": "Jane",
"user_last_name": "Smith",
"user_email": "jane@acme.com",
"user_phone": "+14155559876",
"total_users": 7
}
subscription_started
Fires when a paid subscription begins on an account.
Payload:
| Field | Type | Description |
|---|
user_first_name | string | null | Account owner’s first name. |
user_last_name | string | null | Account owner’s last name. |
user_email | string | Account owner’s email. |
user_phone | string | null | Phone. |
user_signup_date | string (ISO date) | null | Owner’s signup date. |
user_subscription_status | string | Stripe subscription status (e.g. active, trialing). |
user_subscription_start_date | string (ISO date) | Subscription start date. |
user_subscription_end_date | string (ISO date) | null | Period end if known. |
user_subscription_plan_name | string | Plan name. |
user_subscription_plan_value | number | Monthly plan price in dollars. |
user_referrer_* | string | null | UTM/referrer fields, same shape as registration. |
subscription_cancelled
Fires when a subscription is cancelled. Same shape as subscription_started with user_subscription_status always set to "canceled" and any unknown fields nullable.
Verifying requests
When configured, Nedzo includes a shared token in the Auth header:
POST /your-webhook HTTP/1.1
Host: yourdomain.com
Content-Type: application/json
Auth: <shared-token>
{ ... payload ... }
Compare the header value against the token you provided to Nedzo. Reject any request that doesn’t match.