DEVELOPER DOCUMENTATION
Selective Quiz Coaching
Review chosen quiz questions with threaded feedback, a signed send-back plan, worker-owned responses, bounded exports, and private feedback images.
Selective coaching returns only the questions an employer chose. It does not grant a full retake or expose grading material to the worker. The account’s default-off Project To-dos agent surface must be enabled for tenant reads and writes.
Base path: /api/public/v1/project-todos/quizzesDiscover the contract
Section titled “Discover the contract”GET /coaching/capabilities requires project_todos:read but deliberately does not require feature enablement, a claimed account, or a job. It returns static operation, scope, limit, export, image, event, and typed-error facts without tenant data.
Employer reads
Section titled “Employer reads”| Method | Path | Purpose |
|---|---|---|
GET | /coaching-queue?jobId=… | Keyset-paged submitted assignments, with deterministic filters and masked worker identity. |
GET | /coaching/{assignmentId} | Bounded current state for one assignment. |
GET | /coaching/{assignmentId}/cycles | Full coaching-cycle history with keyset pagination. |
GET | /coaching/{assignmentId}/threads | Feedback threads. |
GET | /coaching/{assignmentId}/threads/{threadId}/comments | Comments for one thread. |
GET | /coaching/export | One bounded JSON, JSONL, or formula-neutral CSV page. |
These endpoints require project_todos:read, employer access to the job, and a claimed account. Names are masked; emails and answer keys never appear.
Draft and apply employer feedback
Section titled “Draft and apply employer feedback”Employer coaching mutations use POST /manage with project_todos:write and a stable idempotencyKey:
| Action | Purpose |
|---|---|
coaching_comment | Add a private draft-batch comment or immediate feedback on the reviewed attempt. |
coaching_redo_selection | Set the exact requested-question IDs. |
coaching_draft_cancel | Cancel the unpublished draft batch. |
coaching_thread_resolve / coaching_thread_reopen | Change feedback-thread state. |
coaching_accept | Accept the current submission using expectedSubmittedAt as the stale-review guard. |
coaching_send_back_plan | Validate without writing and mint a signed, expiring planToken bound to the draft and review-state digests. |
coaching_send_back_confirm | Return only the selected questions from that exact plan. |
The plan action is keyless and requires only project_todos:read; nothing becomes worker-visible until confirm. Any changed selection, draft, submission, or review state makes confirm fail closed with 409 PLAN_STALE.
Worker lane
Section titled “Worker lane”Workers mint the separate project_todos:respond scope from their own settings. Employer API keys — including Full access — cannot receive or use this scope.
| Method | Path | Purpose |
|---|---|---|
GET | /worker/coaching/{assignmentId} | Pure context read; never starts or consumes an attempt. |
POST | /worker/coaching/{assignmentId} | start, autosave, resubmit, or reply on the token owner’s assignment. |
GET | /worker/coaching/{assignmentId}/threads | Worker-visible threads only. |
GET | /worker/coaching/{assignmentId}/threads/{threadId}/comments | Published comments only; private drafts stay hidden. |
GET | /worker/coaching/{assignmentId}/history | The worker’s attempt and sent-cycle history. |
Autosave rejects changes to answers outside the requested set and uses expectedRevision as an optimistic lock. Worker responses never include answer keys, correct values, scoring rules, other workers, or private employer drafts.
Feedback images
Section titled “Feedback images”Images use a three-step private lifecycle under /coaching/{assignmentId}/assets: prepare a deterministic reservation and short-lived single-PUT grant, upload bytes directly with upsert disabled, then finalize after server-side size, type, and SHA-256 verification. Status and delivery endpoints return lifecycle facts or a short-lived delivery link.
Never log or persist the upload grant. Bytes do not belong in JSON or base64 request fields. If an upload outcome is ambiguous, retry through canonical finalize/status reconciliation rather than requesting a different object path.
Full retakes
Section titled “Full retakes”To reopen the entire quiz, use require_retake_plan and require_retake_apply. Those checksum-bound actions are intentionally separate from selective coaching.