# API Interception (Reduced Scope for E2E)

E2E should hit real APIs by default. Interception is allowed only for targeted cases where real systems cannot reliably produce the scenario.

## Allowed use cases

1. Simulate error states (`500`, `403`, timeout) to verify UI fallback behavior
2. Simulate permission responses for role-gated UI
3. Block non-critical third-party calls (analytics, tracking, Sentry) to reduce noise

## Not allowed for standard coverage

- mocking happy-path CRUD flows
- replacing full backend behavior for normal regression tests
- hiding real contract issues between frontend and backend

## Example patterns

```ts
await page.route('**/api/goals/**', async (route) => {
  await route.fulfill({ status: 500, body: JSON.stringify({ message: 'internal error' }) });
});
```

```ts
await page.route('**/analytics/**', async (route) => {
  await route.abort();
});
```

## Guardrails

- keep interception scoped to the test that needs it
- always document why interception was required
- ensure at least one non-mocked path covers the same feature
