Job drafts
Create Job Draft
Create a job draft from a natural-language description and receive validation prompts for missing fields.
POST
Creates an unpublished job draft. The description-first workflow: send a plain-text job description, OpenTrain parses it into structured fields server-side, and the response tells you exactly what is still missing — each missing field carries a ready-to-ask
prompt, its type, allowed enumValues, and the updateKeys to patch via PATCH /job-drafts/{jobId}. Loop until validation.publishReady is true, then publish.
Structured imports (schema.org JSON-LD, Indeed-style XML, HR-XML, or OpenTrain’s canonical job object) are also accepted. See the posting guide for the full loop.
Requirements: jobs:write scope + the public_api_job_drafting feature (check capabilities).
Request
Send one of the body shapes below. All are JSON objects.Plain-text job description or project brief (max 60,000 characters). The simplest and recommended input — OpenTrain parses it into structured fields. Equivalent shorthand for
source: {type: "text", text: ...}.Structured import source.
Top-level alternative to
source.type — same supported values. Pair with job (canonical), jsonLd (schema.org), or xml (feeds).OpenTrain canonical job object when
format is opentrain_canonical — keys like title, description, paymentType, rateAmount, languages, countries, labelTypes, tools, experienceLevel.Top-level equivalent of
source.externalId.Top-level equivalent of
source.idempotencyKey.Response
true on success.The new draft’s job ID — use it for every subsequent PATCH and the publish call.
Always
DRAFT (this endpoint never auto-publishes).In-app URL of the draft editor.
In-app URL where a human can review the draft.
Publish-readiness summary.
The gap-filling work list. Relay each
prompt to your human, then patch the answer.The structured fields OpenTrain extracted from your input.
Non-blocking warnings.
Input keys that could not be mapped —
{path, reason, valuePreview}.Parsed fields worth double-checking with your human —
{path, reason}.Audit echo:
{format, externalId, idempotencyKey, rawSourcePreserved, autoPublished: false}.Parser metadata:
{source, warnings, parsedFields}.Errors
| Status | code | Meaning |
|---|---|---|
400 | BAD_REQUEST | Empty body, invalid JSON, unsupported format (details.supportedFormats), or description over 60,000 characters |
401 | UNAUTHORIZED | Missing or invalid token |
403 | FORBIDDEN | Missing jobs:write scope (details.requiredScopes) or public_api_job_drafting disabled (details.featureKey) |