# API contract (POC) Base: `/api`. JSON everywhere. Errors as `{error: {code, message}}` with proper HTTP status. ## Profile & CV - `GET /profile` -> profile object (create default if none) - `PUT /profile` -> update profile fields - `GET /profile/sections` -> list of cv_section ordered by kind, sort_order - `POST /profile/sections` -> create section - `PUT /profile/sections/{id}` -> update - `DELETE /profile/sections/{id}` - `POST /profile/sections/{id}/ai-assist` body `{instruction: str}` -> `{suggestions: [str]}` (LLM, cheap->strong routing per config) - `POST /profile/render-cv` -> `{artifact_id, url}` rendered PDF from current profile + sections (packages/artifacts) ## Job postings - `POST /postings` body `{url}` -> fetch via connectors (manual_url for POC), create job_posting + application(state=discovered) - `GET /postings` -> list - `POST /postings/{id}/score` -> run scoring rubric vs profile -> application.state=scored, returns `{score, rationale}` ## Applications (kanban) - `GET /applications` -> list with posting info joined - `POST /applications/{id}/transition` body `{to}` -> guarded per data-model.md table; 409 if illegal or guard fails - `POST /applications/{id}/artifacts` multipart upload or `{kind, content}` -> creates artifact with content_hash - `POST /applications/{id}/artifacts/cover-letter` body `{letter_text}` -> stores user draft, returns artifact + AI critique `{comments: [{quote, suggestion, severity}]}` (LLM review, does not rewrite) - `GET /applications/{id}/artifacts` -> list ## Approval & outbox (the gate) - `POST /applications/{id}/approvals` body `{action, artifact_id}` -> creates pending approval (expires_at = now+24h) - `POST /approvals/{id}/confirm` -> user confirms; verified artifact.content_hash == approval.artifact_hash or 409 - `POST /approvals/{id}/reject` - `POST /outbox/send` body `{approval_id, payload}` -> **fails 409 unless** approval confirmed, unexpired, hash match. On success: outbox.status=sent (POC: log/echo transport pluggable; real SMTP later) ## Telemetry - `GET /telemetry/tasks` -> task_run list (tokens, model, cost) — shows users their burn ## Health - `GET /health` -> `{status: "ok"}`