> ## Documentation Index
> Fetch the complete documentation index at: https://notifizz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Debug Notifications — Observability

> Correlation IDs, AI usage observability, where to look when 'my event didn't fire' or 'my campaign didn't run'. End-to-end tracing inside Notifizz.

# Observability

Notifizz emits enough signal to follow any single delivery from event acceptance to bell update — the trick is knowing where to look. This page covers the customer-side observability surface: correlation IDs, the dashboard's tracing views, AI usage observability.

## TL;DR

* **Correlation ID** stamped at message creation time — propagates through every queue hop and inbox write.
* **Per-workflow-instance trace** in the dashboard — every step (orchestrator, enricher, channel) with timing.
* **AI usage observability** — see which campaign / user consumed how many AI credits.
* **Dev tasks** — proactive surfacing of orchestrator issues before they hit prod.

## Correlation IDs

Every notification carries a correlation id stamped at message creation time. The id propagates through:

* The workflow instance that created it.
* Every queue hop (the internal queue stages).
* The delivery record document.
* The widget delivery (visible in the message detail).

Use it to trace one delivery end-to-end:

1. Find the correlation id in the dashboard delivery history (per-message detail view).
2. Search backend logs for the id — every log line touched by the delivery includes it.
3. Cross-reference with the workflow trace view in the dashboard.

The id format is opaque (UUID-like). It's stable across retries — a retried delivery keeps the same correlation id.

## Workflow trace

Every workflow instance gets a trace view in the dashboard:

* **Steps** in execution order — initial event match, orchestrator code, enricher calls, channel dispatch.
* **Timing per step** — useful to spot the slow link (usually a cold enricher or a slow channel render).
* **Inputs and outputs** at each boundary — the orchestrator's recipient list, the enricher's params and response, the rendered template.
* **Errors** with stack traces (for orchestrator code) or typed error codes (for enrichers, channels).

This is the first place to look for "my event reached Notifizz but no notification fired" — the trace shows where the chain broke.

## Dev tasks

Dev tasks are proactive — the dashboard surfaces orchestrator issues at edit time, before they hit traffic:

| Dev task                   | Trigger                                                                          |
| -------------------------- | -------------------------------------------------------------------------------- |
| **Missing event property** | Orchestrator reads `event.properties.foo` but no event you've sent has that key. |
| **Undefined enricher**     | Orchestrator calls `enrichWith("notARegisteredEnricher", ...)`.                  |
| **Empty recipient list**   | Orchestrator returns `[]` for typical inputs.                                    |
| **Type mismatch**          | The orchestrator's typed signature contradicts the event's actual shape.         |

Resolution is mostly automatic — the AI proposes fixes, you accept or edit.

## AI usage observability

The AI authoring layer (orchestrator codegen, dev-task auto-resolution) consumes credits. The dashboard shows:

* **Per-user usage** — how many credits each team member consumed.
* **Per-campaign usage** — which campaigns required the most AI work to author.
* **Per-action breakdown** — codegen vs review vs dev-task resolution.

Credits are pooled daily per organisation, with a soft cap that slows new AI requests rather than blocking them when the pool is exhausted.

## "My event didn't fire" — checklist

| Check                                   | Where to look                                                                                                    |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Did the SDK call succeed (no 4xx/5xx)?  | Your application logs.                                                                                           |
| Did the backend accept the event?       | Dashboard → Events → recent events for the environment.                                                          |
| Was a campaign matched?                 | Dashboard → Delivery History → filter by event name. No entries means no campaign listened.                      |
| Was the campaign in a runnable status?  | Campaign detail → status. `Editing` only fires on dev (and even then may not dispatch); `Live` fires everywhere. |
| Did the orchestrator run?               | Workflow instance trace — if absent, the campaign was filtered out (status, env mismatch).                       |
| Did the orchestrator return recipients? | Trace step "build recipients" — empty means no message gets created.                                             |
| Did the channel dispatch?               | Trace step "send" — failures show the typed error.                                                               |

## "My campaign didn't run" — same checklist, deeper

If the workflow instance was created but no notification reached the user:

* **Recipient resolution** — orchestrator returned empty list, or returned a recipient with missing `email`.
* **Channel config** — the campaign references an NC config that no longer exists, or an email config without verified sending domain.
* **Variable rendering** — the template references a variable that didn't resolve.
* **Provider-side rejection** — for email, the provider may reject deliverability (bounce, complaint history).

Each shows up in the workflow trace.

## "My enricher times out" — what next?

In the workflow trace, locate the enricher step. Three signals:

| Signal                                         | Likely cause                    | Fix                                                                                                 |
| ---------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------- |
| Step timed out after 10–15s                    | Slow handler or unreachable URL | Cache aggressively (`cache: { ttl: "1h" }`); confirm the URL is reachable from the Notifizz region. |
| `EnricherHmacVerificationError: bad-signature` | Secret mismatch                 | Re-copy `webhookSigningSecret` from the dashboard.                                                  |
| `EnricherInputValidationError`                 | Schema mismatch                 | The orchestrator passes params your `input` schema rejects. Update one to match.                    |

See [enrichers tutorial](/docs/sdks/how-to/enrichers-tutorial) for the full debugging matrix.

## FAQ

<AccordionGroup>
  <Accordion title="Event tracked but no campaign — what do I check first?">
    The Events catalog (Dashboard → Events). If your event is missing, the SDK secret you used didn't resolve to this environment. If your event is there, the campaign side is the issue — most likely no campaign is wired to the exact event name (typo, casing, environment mismatch).
  </Accordion>

  <Accordion title="Campaign ran but no message — where do I look?">
    Workflow instance trace. The orchestrator returns a recipient list; if empty, no messages get created. If the orchestrator branches on a property, verify that property reached it (the trace shows inputs).
  </Accordion>

  <Accordion title="Correlation ID for one delivery?">
    Per-message detail view in delivery history. The id is in the metadata block; click to copy. Use it as a search term across your application logs and the workflow trace.
  </Accordion>

  <Accordion title="Enricher took 12 seconds — find which one?">
    The workflow trace lists per-step timings. The slow step is usually the cold cache miss on a per-call enricher; check the cache policy on the enricher's registration and consider raising the TTL.
  </Accordion>

  <Accordion title="AI usage spiked — see who used what?">
    Dashboard → Settings → AI Usage. The per-user breakdown shows credits by team member; per-campaign shows which campaigns drove the spike. Most spikes trace to a single dev iterating on a complex orchestrator — pair-review can shorten the loop.
  </Accordion>

  <Accordion title="Logs show my event but no `correlationId` field — why?">
    The id is stamped at message creation time, not at event acceptance. If the campaign matched and a message was created, the id is in the workflow instance and the delivery record. If no message was ever created (orchestrator returned empty recipients), there's no message-level id — use the workflow instance id instead.
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Delivery history & stats" icon="chart-line" href="/docs/operations/delivery-history-and-stats">
    Aggregated funnel view, per-campaign metrics.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/docs/operations/troubleshooting">
    Symptom → cause → fix tables.
  </Card>

  <Card title="Activity log" icon="clock-rotate-left" href="/docs/concepts/activity-log">
    Team-side audit trail of campaign edits.
  </Card>

  <Card title="Error catalogue" icon="circle-exclamation" href="/docs/sdks/error-catalogue">
    Every typed error code.
  </Card>
</CardGroup>
