# Server DSN

Authenticate an SDK with a single connection string that carries the credential, the ingestion endpoint, and the service name.

A **Server DSN** is a single connection string that authenticates one service to Brizz. It replaces the `api_key` + `app_name` pair: the credential, the ingestion endpoint, and the service name all travel inside one value.

```
https://<credential>@<ingest-host>/<service-name>
```

Because the service name travels in the string, giving each service its own DSN attributes its traces correctly without extra configuration in your code. The service name is the part your SDK sends, so it's a convention worth keeping rather than a restriction the credential enforces.

## Creating a Server DSN

### During onboarding

Setting up a new service generates its DSN for you. Copy it before leaving the page — the credential is shown once.

### From the dashboard

1. Navigate to **Organization Settings**
2. Select the **API Keys** tab
3. Click **Create Telemetry API Key**
4. Under **Credential Type**, choose **Server DSN**
5. Give the credential a **Name** — how it's listed in the dashboard, not part of the DSN
6. Optionally enter the **service name** this DSN reports as — it's baked into the string and becomes the service you see in the dashboard. Leave it blank and the DSN comes back with a literal `<service-name>` placeholder for you to substitute later
7. Copy the DSN immediately — it won't be shown again

:::info
The service name must match the service you expect to see in Brizz. Sending from two codebases under one DSN merges their traces into a single service.
:::

## Using a Server DSN

Store it in an environment variable — a DSN contains a credential and must be treated like a password.

```bash
export BRIZZ_DSN="https://<credential>@<ingest-host>/<service-name>"
```

:::tabs
:::tab[Python]
```python
import os
from brizz import Brizz

Brizz.initialize(
    dsn=os.environ["BRIZZ_DSN"],
)
```
:::tab[Node.js]
```typescript
import { Brizz } from '@brizz/sdk';

Brizz.initialize({
  dsn: process.env.BRIZZ_DSN,
});
```
:::

That's the whole difference from the API-key setup — `app_name` is gone, because the DSN already carries the service name. Everything after initialization (sessions, users, events) is identical.

:::tip
Initialize Brizz **before** importing your AI libraries. Auto-instrumentation hooks those modules at import time, so loading them first means calls go untraced. See [Send your first session](/docs/get-started/first-session.md).
:::

## Server DSN vs API key

| | Server DSN | API key |
|---|---|---|
| Environment variable | `BRIZZ_DSN` | `BRIZZ_API_KEY` |
| Service name | Baked into the string | Set separately via `app_name` |
| Ingestion endpoint | Baked into the string | Resolved by the SDK |
| Scope | One service | Shared across services |
| Safe in client code | No | No |

Both authenticate the same SDKs and support the same features. If your workspace issues Server DSNs, use those — one value per service is less to configure and less to get wrong.

## Client DSN

A **Client DSN** is a separate credential class for the browser SDK (`@brizz/browser`). It's public by design and ships in your front-end bundle: it can submit telemetry but cannot read your data. It's meant for browser traffic and requires an `Origin` header on every request, so it isn't a substitute for a Server DSN on a backend.

Create one the same way as a Server DSN, choosing **Client DSN** as the credential type. Client DSNs start with `brizz-ing-c-`, and when the browser SDK is initialized with a `dsn` it rejects any other credential class. Requests must carry an `Origin` header, and you can optionally restrict which origins are accepted with an `allowed_origins` list — a browser-origin check, not proof of site ownership. See [Browser SDK](/docs/sdks/browser.md) for what to do with it.

## Rotating a DSN

1. Create a new Server DSN with the same service name
2. Update `BRIZZ_DSN` in your environment and redeploy
3. Confirm new sessions are arriving — see [Verify it landed](/docs/get-started/verify.md)
4. Delete the old DSN

## Troubleshooting

### No data arriving

- Confirm `BRIZZ_DSN` is actually set in the running environment, not just in a local `.env` that isn't loaded
- Check the DSN wasn't truncated on copy — it ends with the service name, not the host
- Make sure `Brizz.initialize()` runs before any AI library is imported

### Traces land under the wrong service

The service name comes from the DSN, not from your code. Check which DSN that environment is using.

### "Invalid DSN" at startup

- Verify no whitespace or quotes crept into the value
- Confirm the DSN hasn't been deleted in **Organization Settings → API Keys**
- A literal `<service-name>` left in the string is rejected on purpose — replace it with your real service name

## See also

- [API keys](/docs/admin/api-keys.md) — the alternative credential class, and rotation practices that apply to both.
- [Send your first session](/docs/get-started/first-session.md) — initialize the SDK and capture a session.
- [Services & configuration](/docs/admin/services-and-configuration.md) — how services appear and are managed in Brizz.
- [Telemetry ingestion API](/docs/api/telemetry.md) — sending without an SDK.
