DEVELOPER DOCUMENTATION
Create Job Draft
Create a job draft from a natural-language description and receive validation prompts for missing fields.
/api/public/v1/job-draftsCreates 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
Section titled “Request”Send one of the body shapes below. All are JSON objects.
rawJobDescriptionstringbodyPlain-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: ...}.
sourceobjectbodyStructured import source.
formatstringbodyTop-level alternative to source.type — same supported values. Pair with job (canonical), jsonLd (schema.org), or xml (feeds).
jobobjectbodyOpenTrain canonical job object when format is opentrain_canonical — keys like title, description, paymentType, rateAmount, languages, countries, labelTypes, tools, experienceLevel.
externalIdstringbodyTop-level equivalent of source.externalId.
idempotencyKeystringbodyTop-level equivalent of source.idempotencyKey.
Response
Section titled “Response”okbooleantrue on success.
jobIdstringThe new draft’s job ID — use it for every subsequent PATCH and the publish call.
statusstringAlways DRAFT (this endpoint never auto-publishes).
draftUrlstringIn-app URL of the draft editor.
reviewUrlstringIn-app URL where a human can review the draft.
validationobjectPublish-readiness summary.
missingFieldsobject[]The gap-filling work list. Relay each prompt to your human, then patch the answer.
normalizedFieldsobjectThe structured fields OpenTrain extracted from your input.
warningsstring[]Non-blocking warnings.
unmappedFieldsobject[]Input keys that could not be mapped — {path, reason, valuePreview}.
lowConfidenceFieldsobject[]Parsed fields worth double-checking with your human — {path, reason}.
importobjectAudit echo: {format, externalId, idempotencyKey, rawSourcePreserved, autoPublished: false}.
parserobjectParser metadata: {source, warnings, parsedFields}.
Errors
Section titled “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) |