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

# Notifizz Dev / Prod Environments

> How Notifizz environments map to API keys, when to rotate, testing in Dev before Live, key per CI step.

# Environments

Each Notifizz organisation has multiple environments — typically `dev` and `prod`, plus optional `staging` or per-team variants. Each environment owns its **own** copy of every secret and its **own** event traffic. Sharing keys across environments is the most common cause of "weird" failures.

## TL;DR

* Every environment has its own SDK Secret, Auth Secret, Front API Key, Webhook Signing Secret.
* `Dev` campaigns run on dev only; `Live` runs on every environment.
* Rotate by generating the new key alongside the old, deploy, retire the old.
* Don't share keys across environments — even for internal tooling.

## What's per-environment

Every secret and every campaign-runtime decision is per-environment:

| Surface                               | Per-environment?                                      |
| ------------------------------------- | ----------------------------------------------------- |
| SDK Secret                            | yes                                                   |
| Auth Secret                           | yes                                                   |
| Front API Key                         | yes                                                   |
| Webhook Signing Secret                | yes                                                   |
| Campaign status (Live / Dev / …)      | resolved per env at instance creation                 |
| Connector source `verificationSecret` | per source, scoped to its environment                 |
| Enricher URL                          | yes (you can declare different URLs per env)          |
| Region                                | per environment (the env determines the API hostname) |

The campaign object itself is shared across environments; the **status check** is per-env. A `Dev` campaign exists in both dev and prod's view of the campaign list, but only runs on dev (see [campaigns](/docs/concepts/campaigns) for the runnable filter).

## Typical environment layout

| Environment          | Purpose                      | Campaign statuses that run                                                                         |
| -------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------- |
| `dev`                | Local development, iteration | Editing, Dev, Live, Offline (per the [runnable filter](/docs/concepts/campaigns#runnable-filter))  |
| `staging` (optional) | Pre-prod validation          | Same as dev, but with prod-like data volumes                                                       |
| `prod`               | Customer traffic             | Live, plus Editing and Offline at instance creation (downstream behaviour varies — consult source) |

The `Dev` gate is the explicit guardrail: orchestrators staged for review can't accidentally fire on prod traffic.

## When to rotate keys

| Trigger                                    | What to rotate                                                                                                                                   |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Engineer leaves the company                | All secrets they had access to.                                                                                                                  |
| Suspicion of leak                          | The compromised secret immediately, with the dashboard's emergency rotation flow.                                                                |
| Routine policy (every 6–12 months)         | All secrets, environment by environment.                                                                                                         |
| Front API Key visible in a leaked git repo | The Front API Key is public-by-design (embedded in your frontend) — rotate only if you're using `none` mode in production (which you shouldn't). |

## Rotation flow

The dashboard exposes a rotation flow per secret with an overlap window:

<Steps>
  <Step title="Generate the new key">
    Dashboard → Environment → API Keys → "Rotate". A new key is generated; the old key remains valid for the overlap window (configurable, typically 24h).
  </Step>

  <Step title="Update your services">
    Push the new key to your secret manager / env vars. Redeploy.
  </Step>

  <Step title="Wait the overlap window">
    Both keys work during this period. Existing in-flight requests using the old key complete; new requests pick up the new key.
  </Step>

  <Step title="Retire the old key">
    Click "Retire previous". The old key is invalidated immediately; any service still using it gets `403 auth/invalid-authorization` on the next call.
  </Step>
</Steps>

For emergencies (suspected leak), the "rotate now, no grace period" path skips the overlap window. Use it when the cost of "any service might still be using the old key" is lower than the cost of "the leaked key remains valid".

## Test in Dev before Live

The standard flow for any campaign change:

1. Edit on dev. Promote `Editing → Dev`.
2. Fire test events from your dev backend. Verify delivery in dev's delivery history.
3. Fix dev tasks (missing properties, broken orchestrator code, …) until clean.
4. Promote `Dev → Live`. The campaign now also fires on prod traffic.

The dev-task system is what makes this safe — the dashboard surfaces problems before they hit prod.

## CI integration

In CI environments, use a dedicated key per pipeline:

* A read-only key for "verify a notification path works" tests against dev.
* A separate prod-tracking key only for the build that actually emits to prod (typically a release job).

Don't share keys between developer machines and CI. Generating one CI key per pipeline gives you per-pipeline audit trails and lets you revoke access without rotating dev keys.

## FAQ

<AccordionGroup>
  <Accordion title="Share keys between dev and prod?">
    No. Each environment has its own pair. Sharing causes hard-to-debug cross-traffic — your dev test events end up in prod's queue, or vice versa. Treat keys as environment-scoped from day one.
  </Accordion>

  <Accordion title="Run a campaign only on dev?">
    Set its status to `Dev` and never promote it. The runnable filter explicitly excludes `Dev` from production environments — your dev iteration stays out of prod traffic.
  </Accordion>

  <Accordion title="Keys for CI?">
    One per pipeline. CI keys are usually scoped to the dev environment for test/integration work; only the release job uses a prod key, and that key only ever touches prod.
  </Accordion>

  <Accordion title="I rotated a key and the SDK throws 401 — how long until propagation?">
    Within seconds — the backend reads keys per request, no caching beyond a short TTL on the resolution. If your SDK throws 401 minutes after rotation, your service is still using the old key (env var not reloaded, secret manager not refetched).
  </Accordion>

  <Accordion title="Delete an environment safely?">
    Archive all its campaigns first. Then revoke its keys (rotate to nothing, decline the new generation). Then delete from the dashboard. In-flight workflow instances complete or fail naturally; no live traffic continues post-delete.
  </Accordion>

  <Accordion title="Multiple developers — one shared dev environment or one each?">
    Either works. One shared dev is simpler operationally; one-per-developer is cleaner if you have many engineers. The dashboard supports both — environments are cheap.
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Keys and environments reference" icon="key" href="/docs/environments/api-keys">
    The five secrets and where each goes.
  </Card>

  <Card title="Campaigns" icon="diagram-project" href="/docs/concepts/campaigns">
    Statuses, runnable filter, versioning.
  </Card>

  <Card title="Delivery history & stats" icon="chart-line" href="/docs/operations/delivery-history-and-stats">
    Where to verify a delivery worked.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/docs/operations/troubleshooting">
    Cross-cutting failure modes.
  </Card>
</CardGroup>
