Engineering
API Reference
Status: Living document · Owner: Engineering · Last reviewed: 2026-07-07
All endpoints are Next.js Route Handlers under /api. Unless noted as public,
every route runs the shared guard: session check → per-IP rate limit → Zod
validation → timeout/retry → leak-proof error envelope.
Auth legend: 🔒 requires a valid Studio session · 🌐 public/edge · 🤖 machine (webhook/cron with a shared secret).
Identity
GET /api/studio/ms/login 🌐
Starts the Microsoft Entra ID OAuth 2.0 authorization-code flow. Sets a signed
CSRF state nonce and redirects to Entra ID (where MFA is enforced).
GET /api/studio/ms/callback 🌐
OAuth redirect target. Validates state, exchanges the code, checks the returned
email against the allowlist, encrypts and stores the refresh token, and mints
the Studio session cookie.
POST /api/studio/login 🌐
Password sign-in. On success, issues the HMAC session cookie (12h, HTTP-only).
POST /api/studio/logout 🔒
Clears the Studio session.
Studio state
GET /api/studio/state 🔒
Returns the current snapshot and its version.
POST /api/studio/state 🔒
Writes a new snapshot. Uses optimistic concurrency (send the version you
based your edit on) under a Postgres advisory lock. A version mismatch returns
a conflict for the client to reconcile.
GET /api/studio/monitor 🔒
Operational status for the console (health, recent activity).
GET /api/studio/search 🔒
Search across the photo library.
POST /api/studio/notify 🔒
Internal notification hook for the console.
Cloud ingestion (OneDrive & Google Drive)
Both providers share one import model: download bytes once → derive private renditions → run AI → delete the staged original. The full-res original is never permanently stored on our side (see ADR-009).
GET /api/studio/drive 🔒
Lists images in a watched folder / returns the delta for a provider
(?provider=microsoft|google).
POST /api/studio/drive/materialize 🔒
Takes raw cloud files (vendor URLs) and returns durable /api/media rendition
paths, downloading + transcoding + deleting the staged original server-side.
Used by the interactive picker and the client-side watched-folder poll so they
match the headless pipeline.
POST /api/studio/onedrive 🔒
Triggers an on-demand OneDrive delta sync.
POST /api/studio/onedrive/subscription 🔒
Creates or renews the Graph change-notification subscription.
POST /api/studio/onedrive/webhook 🤖
Graph change-notification receiver. Answers the validation handshake, verifies
clientState, then pulls the delta. Writes are concurrency-safe.
AI agents
Each agent accepts photo/post context and returns a structured result. Results are cached by a hash of (agent + prompt + input) and fall back to a deterministic mock if the model is unavailable.
| Endpoint | Auth | Purpose |
|---|---|---|
POST /api/agents/curator | 🔒 | Score and select the strongest frames |
POST /api/agents/editor | 🔒 | Editing / crop / treatment guidance |
POST /api/agents/copywriter | 🔒 | Captions and long-form copy |
POST /api/agents/hashtags | 🔒 | Tag sets per post |
POST /api/agents/scheduler | 🔒 | Proposed posting cadence |
Publishing
POST /api/publish/instagram 🔒
Creates an Instagram media container and publishes it. Runs a tighter rate limit; the publish call is non-idempotent and never retried. Stores the returned permalink on success.
GET /api/ig-image/[id] 🌐
Serves an image rendition for Instagram publishing.
Platform utilities
POST /api/revalidate 🤖
Revalidates public gallery/collection routes after a publish or ingest.
GET /api/cron/maintenance 🤖
Scheduled job (requires CRON_SECRET). Renews Microsoft tokens and the OneDrive
subscription so ingestion keeps working with no browser open.
Error envelope
Failures return a consistent, non-leaking JSON shape:
{ "error": { "code": "string", "message": "human-readable, safe to display" } }
Internal details (stack traces, upstream payloads) are never returned to clients.