Skip to content
OpenTrain AIOpenTrain AIOpenTrain AIDocs

Ask OpenTrain

Answers from the documentation, with sources.

What would you like to do with OpenTrain?

AI answers can be mistaken. Check the linked sources. Don’t include private account information.

Open app

DEVELOPER DOCUMENTATION

Roll Out a Quiz (Plan, Then Confirm)

Publish a quiz draft and assign it as a Project To-do in one reviewed decision: a no-write plan with a signed token, then one idempotent confirm.

POST/api/public/v1/project-todos/quizzes/manage

A rollout publishes a quiz and assigns it to AI trainers as one decision that a person reviews once. It has two steps on the shared manage endpoint:

  1. quiz_rollout_plan writes nothing. It returns every fact the person needs to approve: the exact version that will be published, the To-do settings with the projected due and blocking times, the masked list of current recipients, active duplicates, the notification impact, and a signed plan.token.
  2. quiz_rollout_confirm takes that token. It publishes the draft (or binds the version you planned), then creates and assigns the Project To-do, all under one idempotency key.

The person’s “yes” in the agent conversation or terminal is the confirmation. No OpenTrain page is required.

quiz_rollout_plan needs only project_todos:read and no idempotency key. For a draft grounded in the job’s Instructions it also needs instructions:read, because it reads the cited pages. It changes nothing users see. For a grounded draft, resolving the released Instructions may record the same idempotent view row that an AI trainer’s read records.

actionstringbodyrequired
quiz_rollout_plan
jobIdstringbodyrequired
formIdstringbodyrequired
sourceobjectbodyrequired

{ "kind": "DRAFT", "expectedDraftRevision": n } plans to publish the draft at the revision you reviewed. { "kind": "VERSION", "formVersionId": "…" } plans to bind a version that is already published, without publishing again.

todoobjectbodyrequired

The Project To-do settings: completionPolicy (ON_SUBMIT, ON_PASS, or ON_REVIEW), audience (ACTIVE, FUTURE, ACTIVE_AND_FUTURE, or SELECTED with up to 500 selectedContractIds), and optional priority (NORMAL, HIGH, URGENT), blockingMode (NONE, IMMEDIATE, AFTER_DUE), dueOffsetMinutes (1 to 525,600), required, title, description, and categoryId.

REST

Terminal window
curl -s -X POST "https://www.opentrain.ai/api/public/v1/project-todos/quizzes/manage" \
-H "Authorization: Bearer $OPENTRAIN_API_TOKEN" -H 'content-type: application/json' -d '{
"action": "quiz_rollout_plan",
"jobId": "job_123", "formId": "form_456",
"source": { "kind": "DRAFT", "expectedDraftRevision": 3 },
"todo": {
"completionPolicy": "ON_PASS", "audience": "ACTIVE_AND_FUTURE",
"priority": "HIGH", "blockingMode": "AFTER_DUE", "dueOffsetMinutes": 1440
}
}'
FieldMeaning
publishabletrue when nothing blocks. Only then is plan set.
blockers[]Each blocker has a code and a message. Codes: PROJECT_TODOS_DISABLED, FORM_ARCHIVED, DRAFT_REVISION_STALE, DRAFT_INVALID, NOT_PUBLISHABLE, ASSET_UNUSABLE, SOURCE_CHANGED, GROUNDING_DRAFT_PREVIEW, LEARNING_PLAN_MISMATCH, ON_PASS_REQUIRES_PASS_RULE, ON_PASS_REQUIRES_AUTO_GRADING.
warnings[]Facts to show the person that do not block.
formThe source (DRAFT or VERSION), draftRevision, nextVersionNumber, and contentHash of what will be published.
publicationTotal points, answerable and manually graded question counts, the pass rule, the attempt policy, and the result release mode.
todoThe settings as they will be stored, with projectedDueAt and projectedBlockAt.
audienceWhether the audience is broad, whether it includes future hires, currentRecipientCount, and recipients (contract id plus masked display name).
duplicatesActive to-dos on the same form (sameForm) or the same version (sameFormVersion).
notificationsHow many assignment notifications go out, whether future hires get the to-do automatically, and whether it blocks project work.
plan{ token, expiresAt }. The token expires after 15 minutes and is bound to the actor, job, form, draft revision and content hash (or version), the To-do settings, and the recipient set.
nextActionOne sentence that says what to do next.

Show the plan to the person before you confirm.

quiz_rollout_confirm needs project_todos:write, a claimed account, and a stable idempotencyKey. For a grounded draft it also needs instructions:read.

actionstringbodyrequired
quiz_rollout_confirm
idempotencyKeystringbodyrequired
8–128 characters of letters, digits, ., _, :, or -. Keep it stable across retries.
planTokenstringbodyrequired
The plan.token from the plan.
todoobjectbodyrequired

The exact same todo you planned. The token signs a digest of it, not its contents, so you send it again.

allowDuplicatebooleanbody
Set to true to assign the exact published version again when the plan listed it under duplicates.sameFormVersion. Without it that request is refused. An earlier version of the same form (sameForm) only adds a warning: confirming adds a new to-do next to the old one.

REST

Terminal window
curl -s -X POST "https://www.opentrain.ai/api/public/v1/project-todos/quizzes/manage" \
-H "Authorization: Bearer $OPENTRAIN_API_TOKEN" -H 'content-type: application/json' -d '{
"action": "quiz_rollout_confirm",
"idempotencyKey": "safety-quiz-rollout-2026-11",
"planToken": "PLAN_TOKEN_FROM_THE_PLAN",
"todo": {
"completionPolicy": "ON_PASS", "audience": "ACTIVE_AND_FUTURE",
"priority": "HIGH", "blockingMode": "AFTER_DUE", "dueOffsetMinutes": 1440
}
}'

The response has ok: true, published (formVersionId, versionNumber, createdNow, resumed), todo (itemId, versionId, replayed), the fan-out counts (matchedContracts, createdAssignments, skippedExistingAssignments, failedAssignments), warnings, and replayed.

Before writing anything, confirm checks the roster and the Project To-dos setting again.

Status and details.reasonWhat happenedWhat to do
409 PLAN_STALESomething changed since the plan: the roster, the Project To-dos setting, the draft, the archive state, or the version content. details.changed says what. Nothing was written.Plan again.
409 PLAN_TODO_MISMATCHThe todo differs from the planned one.Send the planned todo.
409 PLAN_TOKEN_EXPIRED / PLAN_TOKEN_INVALIDThe token is older than 15 minutes, or it belongs to another actor or plan.Plan again.
409 TARGET_ALREADY_MUTATEDThis plan was already confirmed under a different key. Nothing is assigned twice.Retry with the first key to get the result, or plan again for a new rollout.
409 IDEMPOTENCY_KEY_REUSEDAnother operation already used this key to create a to-do on the job. Refused before anything is published.Use a new key.

A retry with the same key returns the same version and to-do with replayed: true. The publication is recorded under rollout:<idempotencyKey>, so a confirm that lost its reply after publishing resumes that version on retry, even after the token would have expired. If the roster changes between the publication and the assignment, the 409 PLAN_STALE names the new version in details.published. Retry with the same key once the roster matches, or plan again with { "kind": "VERSION", "formVersionId": … } to bind it without publishing a duplicate.