# API Rules

> The API surfaces and the contracts/conventions they follow.

_Verified against `routes/api.php`, `routes/web.php`, and `AI_AGENTS_API_CONTRACT.md` on 2026-07-23._

---

## Surfaces
| Surface | Path | Auth |
|---------|------|------|
| AI / MCP | `/api/v1/ai/*` (MCP read/full, REST AI controllers) | `McpAuth` (OAuth 2.1 or Sanctum), feature-flagged `ai.enabled` |
| Public REST | `/api/v1/investors`, `/api/v1/startups` | as configured |
| PWA (read-only) | `/app/api/*` (admin JWT cookie), `/api/pwa/*` (Sanctum bearer `pwa:access`) | reuses `AppApi` controllers |
| OAuth 2.1 | `.well-known/*`, `/oauth/authorize|token|revoke|introspect|userinfo` | — |
| Webhooks | `webhooks/{monday,microsoft-bookings,sendpulse/whatsapp}` | provider verification (HMAC / client_state / shared secret) |
| Booking | `/api/bookings/{days,availability,create}` | OTP-gated, throttled |

## Conventions
- **Versioning:** `v1`.
- **No DELETE endpoints on the API/MCP surface** — deletion is not exposed there (see [`database-rules.md`](database-rules.md)). The admin dashboard may delete notes (audited before removal — DR-010 / DR-011); that is a web route, not an API endpoint.
- **Subject rule (agent/API contract):** exactly one of `startup_id` | `investor_id` identifies the subject.
- **Envelopes / enums:** shared success/error envelopes and enums per `AI_AGENTS_API_CONTRACT.md`.
- **Tiers:** MCP read vs full enforced by URL; PWA is read-only ("Executive monitor").
- **Writes are real business actions** — e.g. `startup_set_action` runs the full workflow (group move + notifications + meeting cancel + audit).
- **Single-source validation invariants** — a field written from multiple paths uses one authoritative rule. Example: the note-body limit is `EntityNote::BODY_MAX_LENGTH` (5000), shared by `Admin/NotesController`, `AiNoteWriteController`, and the `note_create`/`note_update` MCP tool schemas (DR-009). Divergence between paths is a bug (see [`../07-operation/change-management.md`](../07-operation/change-management.md)).

## Caveats
- The agent/Make API contract is documented but noted **"NOT deployed"** in source docs — treat live availability as **Unknown - requires confirmation**.
- Confirmation that the PWA surface is strictly GET-only (no write paths): **Unknown - requires confirmation.**
