# Observability

> **TL;DR** — For every Wandura call, log the time, endpoint, status, `error_code`, latency, your key's **prefix**, the episode and your `viewer_ref`, and the request id once it is live. Never log keys, tickets, signed links or raw device values. Watch ticket success by code, `5xx` and latency, catalog sync health, and deprecation headers.

## What to log on every call
| Field | Why |
|---|---|
| UTC timestamp (to the millisecond), endpoint and method | When and where. |
| HTTP status, `error_code` (or creatives `code`), `reason`, `fields` | What happened. |
| Latency | Spot slowness before viewers do. |
| `Wandura-Request-Id`, or `request_id` from an error body | The exact request in Wandura's logs. |
| `Wandura-Version`, `Wandura-API-Status`, `Retry-After`, `Deprecation`, `Sunset` | Version and lifecycle signals. |
| Key **prefix** (`wnd_live_ab12cd`), never the key | Which key, safely. |
| Episode (`episode_id`, or `film_ref` + `episode_no`), `intent`, batch size and per-item statuses | Playback problems are per episode. |
| Your `viewer_ref` | Ties Wandura's records to your viewer, without personal data. |

Every response carries `Wandura-Request-Id`, and every JSON error body `request_id`. Log it on every call.

## Never log
| Value | Instead |
|---|---|
| The API key, the `Authorization` header | The key prefix |
| `play_auth_token`, `manifest_url`, open video links | Nothing, or "present" |
| Raw `union_info`, `drm_kek` | A short hash |
| Viewer email, phone, name — also not inside `viewer_ref` | Your opaque `viewer_ref` |
| Full `/playback` response bodies | Status, code and `expires_at` |

This applies to APM tools, proxies, analytics and crash reporters too. The examples ship a redaction helper:

```ts
/** Secrets are dropped; device values are hashed; API keys are cut to the prefix the portal shows. */
const SECRET_FIELDS = new Set(['authorization', 'api_key', 'play_auth_token', 'grant_ticket', 'manifest_url']);
const HASHED_FIELDS = new Set(['union_info', 'drm_kek']);

/** `wnd_live_ab12cd…` → `wnd_live_ab12cd`. Enough for support, useless to an attacker. */
export function keyPrefix(key: string): string {
  return key.slice(0, 15);
}

/** Copy with secrets removed. Run everything you log, trace or send to a crash reporter through it. */
export function redact(value: unknown): unknown {
  if (Array.isArray(value)) return value.map(redact);
  if (typeof value === 'string') return value.replace(/wnd_live_[A-Za-z0-9_-]{6,}/g, (k) => `${keyPrefix(k)}…`);
  if (!value || typeof value !== 'object') return value;
  const out: Record<string, unknown> = {};
  for (const [k, v] of Object.entries(value)) {
    const lk = k.toLowerCase();
    if (SECRET_FIELDS.has(lk)) out[k] = '[redacted]';
    else if (HASHED_FIELDS.has(lk) && typeof v === 'string') out[k] = `sha256:${createHash('sha256').update(v).digest('hex').slice(0, 12)}`;
    else out[k] = redact(v);
  }
  return out;
}
```

## What to monitor
| Signal | Alert when | Usually means |
|---|---|---|
| Ticket answers by `error_code` | A jump in `not_entitled` | A licence ended — check your catalog sync |
|  | A jump in `invalid_device_info` or `sdk_required` | An app release broke the Player SDK wiring |
|  | `429` on `play` tickets | A retry loop, or a peak above your limit |
| `5xx` rate and ticket latency | `5xx` above 1 % or latency above 2 s for 5 minutes | A Wandura incident: report it ([Troubleshooting](https://docs.wandura.ai/v1/developers/production/troubleshooting#escalate)) |
| Last successful catalog sync | Older than two intervals | A stalled job keeps showing withdrawn titles |
| Number of films and playable episodes | A sudden drop | Worth a message to Wandura |
| `Deprecation` / `Sunset` headers | Any | A change is coming: [Migrating versions](https://docs.wandura.ai/v1/developers/guides/migrating-versions) |
| **Last used** per key, on **Developers** | A key you think unused is used | A leak, or a forgotten system |

On partner.wandura.ai → **Developers** → **API usage** you see calls per key and endpoint for the last 30 days.

## Related
- [Troubleshooting](https://docs.wandura.ai/v1/developers/production/troubleshooting)
- [Security](https://docs.wandura.ai/v1/developers/concepts/security#never-in)
