{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/api-evangelist/appen/main/json-schema/appen-job-dto-schema.json", "title": "JobDTO", "description": "Job Data Transfer Object for updating job settings.\n\n## FIELD OVERVIEW\n\n** REQUIRED (5):** `id`, `projectId`, `teamId`, `title`, `type`\n\n** CORE CONFIG:** `version`, `assignmentLeaseExpiry`, `judgmentsPerRow`, `rowsPerPage`, `displayContributorName`, `judgmentModifiable`\n\n** WORKFLOW:** `state`, `activeStatus`, `feedback`, `sendBackOp`, `unitSegmentType`, `allowSelfQa`, `allowAbandonUnits`\n\n** TIME & LIMITS:** `timeLimitThresholdSec` (0-100%), `enableExpirationTime`, `expirationDurationSet`, `expirationDurationUpdate`\n\n** QUALITY:** `dynamicJudgements` (minimumConfidence 0.0-1.0), `threshold` (0.0-1.0), `maxJudgmentPerContributor`\n\n** FEATURES:** `enableBlueTooth`, `enableShareLink`, `enableExternalAutoAssignJob`, `launchPlatform`, `latestAppVersion`\n\n** SESSION:** `totalSessionNumber`, `reusablePrompt`, `reusablePin`, `maxSkippablePromptNum`\n\n** CONTENT:** `instruction`, `jobCml`, `jobFilter`, `jobCrowd`, `testQuestionSettings`\n\n** BUSINESS:** `payRateType`, `invoiceStatisticsType`, `validationRuleId`, `qaAdvancedOptions`\n\n** METADATA:** `createdAt`, `displayId`, `flowId`, `internalSecret`, `copiedFrom` (read-only fields)\n\n## KEY RULES\n- TeamId must match query parameter | Job titles must be unique in project\n- Negative values not allowed for: time, expiration, confidence fields\n- timeLimitThresholdSec is percentage (0-100), not seconds\n- When enableExpirationTime > 0, duration fields must be > 0\n- WORK jobs cannot have feedback ENABLED\n", "x-generated": "2026-09-23", "x-method": "derived", "x-generator": "derive-json-schema.py", "x-source": "openapi/appen-jobs-api-openapi.yml#/components/schemas/JobDTO", "type": "object", "required": [ "id", "projectId", "teamId", "title", "type" ], "properties": { "id": { "type": "string", "description": "**REQUIRED**: Unique job identifier (UUID). Identifies the job to update." }, "version": { "type": "integer", "description": "**RECOMMENDED**: Job version for optimistic locking. Prevents conflicting updates." }, "projectId": { "type": "string", "description": "**REQUIRED**: Project identifier (UUID). Must have access to this project." }, "teamId": { "type": "string", "maxLength": 50, "description": "**REQUIRED**: Team identifier (UUID). Must match teamId query parameter." }, "title": { "type": "string", "description": "**REQUIRED**: Job title. Must be unique within project (error 60080 if duplicate)." }, "displayId": { "type": "integer", "description": "**READ-ONLY**: Auto-generated human-readable job ID. Default: auto-generated." }, "cycleNumber": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Job cycle number. Default: 0, Range: ≥0." }, "feedback": { "type": "string", "enum": [ "ENABLED", "DISABLED" ], "description": "**OPTIONAL**: Contributor feedback setting. Default: DISABLED. WORK jobs cannot have ENABLED." }, "flowId": { "type": "string", "description": "**OPTIONAL**: Workflow identifier (UUID). Default: same as job ID." }, "type": { "type": "string", "enum": [ "WORK", "QA" ], "description": "**REQUIRED**: Job type. WORK = standard job, QA = quality assurance. WORK jobs cannot have feedback ENABLED." }, "state": { "type": "string", "enum": [ "DRAFT", "RUNNING", "PAUSED", "COMPLETED", "CANCELLED" ], "description": "**OPTIONAL**: Current job state. Controls job execution status." }, "activeStatus": { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ], "description": "**OPTIONAL**: Job active status. Default: ACTIVE." }, "assignmentLeaseExpiry": { "type": "integer", "minimum": 60, "description": "**RECOMMENDED**: Assignment lease time in seconds. Min: 60, controls how long assignments are held." }, "judgmentsPerRow": { "type": "integer", "minimum": 1, "description": "**RECOMMENDED**: Judgments required per row. Default: 1, Min: 1. Higher = more consensus." }, "rowsPerPage": { "type": "integer", "minimum": 1, "description": "**RECOMMENDED**: Rows per assignment page. Min: 1, controls assignment size." }, "displayContributorName": { "type": "boolean", "description": "**OPTIONAL**: Show contributor names. Default: false (anonymous)." }, "judgmentModifiable": { "type": "boolean", "description": "**OPTIONAL**: Allow judgment editing after submission. Default: false." }, "sendBackOp": { "type": "string", "enum": [ "SEND_BACK_TO_SAME_CONTRIBUTOR", "SEND_BACK_TO_ANY_CONTRIBUTOR", "SEND_BACK_TO_POOL", "IGNORE" ], "description": "**OPTIONAL**: Rejected work handling. Default: SEND_BACK_TO_SAME_CONTRIBUTOR." }, "copiedFrom": { "type": [ "string", "null" ], "description": "**READ-ONLY**: ID of job this was copied from (if applicable).\n\n- **Default**: null\n- **Purpose**: Track job lineage for copied jobs\n- **Note**: Set automatically when copying jobs\n" }, "maxJudgmentPerContributorEnabled": { "type": "boolean", "description": "**OPTIONAL**: Whether to limit judgments per contributor.\n\n- **Default**: false\n- **Purpose**: Enable contributor workload limits\n- **Related**: Works with maxJudgmentPerContributor field\n" }, "maxJudgmentPerContributor": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Maximum judgments per contributor.\n\n- **Default**: 0 (unlimited)\n- **Range**: ≥ 0 (0 = unlimited, positive values set limit)\n- **Purpose**: Prevent single contributor from dominating job\n- **Requirement**: Only applies when maxJudgmentPerContributorEnabled = true\n" }, "maxSkippablePromptNum": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Maximum number of skippable prompts.\n\n- **Default**: 0 (no skipping allowed)\n- **Range**: ≥ 0 (0 = no skipping, positive values allow skipping)\n- **Purpose**: Allow contributors to skip difficult assignments\n" }, "unitSegmentType": { "type": "string", "enum": [ "UNIT_ONLY", "UNIT_SEGMENT", "UNIT_WITH_PREVIEW" ], "description": "**OPTIONAL**: Unit segment type for data presentation.\n\n- **Default**: UNIT_ONLY\n- **Values**:\n - UNIT_ONLY: Present data as single units\n - UNIT_SEGMENT: Present data in segments\n - UNIT_WITH_PREVIEW: Include preview capability\n- **Purpose**: Controls how data is structured for contributors\n" }, "internalSecret": { "type": "string", "description": "**SYSTEM**: Internal secret for job access (auto-generated).\n\n- **Default**: Auto-generated secure string\n- **Purpose**: Internal authentication token\n- **Note**: Do not modify unless specifically required\n" }, "createdAt": { "type": "string", "format": "date-time", "description": "Job creation timestamp" }, "allowSelfQa": { "type": "boolean", "description": "Whether self QA is allowed" }, "allowAbandonUnits": { "type": "boolean", "description": "Whether units can be abandoned" }, "maxNumberOfAllowedAbandonment": { "type": "integer", "minimum": 0, "description": "Maximum number of allowed abandonments (must be non-negative)" }, "sendAbandonedUnitsBackToJob": { "type": "boolean", "description": "Whether abandoned units are sent back to job" }, "instruction": { "type": "string", "description": "Job instructions" }, "validationRuleId": { "type": [ "string", "null" ], "description": "Validation rule identifier" }, "enableBlueTooth": { "type": "boolean", "description": "Whether Bluetooth is enabled" }, "launchPlatform": { "type": "array", "items": { "type": "string" }, "description": "Launch platforms" }, "latestAppVersion": { "type": "boolean", "description": "Whether latest app version is required" }, "reusablePrompt": { "type": "boolean", "description": "Whether prompts are reusable" }, "reusablePin": { "type": "boolean", "description": "Whether pins are reusable" }, "totalSessionNumber": { "type": "integer", "minimum": 0, "description": "Total number of sessions (0 = no limit, positive values set session limit)" }, "firstLaunchTime": { "type": [ "string", "null" ], "format": "date-time", "description": "First launch timestamp" }, "promptsEnabling": { "type": [ "string", "null" ], "description": "Prompts enabling configuration" }, "reviewReasons": { "type": "string", "description": "Review reasons" }, "reviewReasonOption": { "type": "string", "description": "Review reason option" }, "parentJobId": { "type": [ "string", "null" ], "description": "Parent job identifier" }, "unitGroupOption": { "type": "string", "description": "Unit group option" }, "appendable": { "type": "boolean", "description": "**OPTIONAL**: Allow job data appending. Default: false." }, "enableShareLink": { "type": "boolean", "description": "**OPTIONAL**: Enable job sharing links. Default: false." }, "payRateType": { "type": "string", "description": "**OPTIONAL**: Payment rate type. Default: empty string." }, "invoiceStatisticsType": { "type": "string", "enum": [ "UNIT_COUNT", "JUDGMENT_COUNT", "TIME_BASED" ], "description": "**OPTIONAL**: Invoice statistics calculation type. Default: UNIT_COUNT." }, "operateHistoryId": { "type": "string", "description": "**SYSTEM**: Operation history identifier (auto-generated)." }, "jobCml": { "type": [ "object", "null" ], "description": "**OPTIONAL**: Job CML (Contributor Markup Language) configuration." }, "jobFilter": { "type": [ "object", "null" ], "description": "**OPTIONAL**: Job data filtering configuration." }, "jobCrowd": { "type": [ "object", "null" ], "description": "**OPTIONAL**: Job crowd/contributor settings." }, "testQuestionSettings": { "type": [ "object", "null" ], "description": "**OPTIONAL**: Test question configuration. jobId and teamId must match main job." }, "timeLimitThresholdSec": { "type": "integer", "minimum": 0, "maximum": 100, "description": "**OPTIONAL**: Time limit threshold as percentage (0-100), not seconds. Default: 0 (disabled)." }, "enableExternalAutoAssignJob": { "type": "boolean", "description": "**OPTIONAL**: Enable external auto assignment. Default: false." }, "enableExpirationTime": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Expiration control. Default: 0 (disabled). When >0, duration fields must be >0." }, "expirationDurationSet": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Assignment expiration duration (seconds). Default: 0 (disabled), Range: ≥0." }, "expirationDurationUpdate": { "type": "integer", "minimum": 0, "description": "**OPTIONAL**: Update expiration duration (seconds). Default: 0 (disabled), Range: ≥0." }, "threshold": { "type": "number", "format": "float", "minimum": 0, "description": "**OPTIONAL**: Job threshold value. Default: 0.0, Range: 0.0-1.0." }, "qaAdvancedOptions": { "type": [ "object", "null" ], "description": "**OPTIONAL**: QA advanced configuration options. Default: null." }, "active": { "type": "boolean", "description": "**READ-ONLY**: Whether job is active (computed field)." }, "alias": { "type": "string", "description": "**READ-ONLY**: Job alias (auto-generated like W837054 or Q837054)." }, "running": { "type": "boolean", "description": "**READ-ONLY**: Whether job is currently running (computed field)." }, "draft": { "type": "boolean", "description": "**READ-ONLY**: Whether job is in draft state (computed field)." }, "segmented": { "type": "boolean", "description": "**READ-ONLY**: Whether job uses segmentation (computed field)." }, "appenConnectCrowd": { "type": "boolean", "description": "**READ-ONLY**: Whether using Appen Connect crowd (computed field)." }, "multipleJudgement": { "type": "boolean", "description": "**READ-ONLY**: Whether multiple judgments enabled (computed from judgmentsPerRow > 1)." }, "dynamicJudgements": { "type": [ "object", "null" ], "description": "**OPTIONAL**: Dynamic judgments configuration. Default: disabled.", "properties": { "enableDynamicJudgements": { "type": "boolean", "description": "Enable dynamic judgment adjustment. Default: false." }, "maxDynamicJudgements": { "type": "integer", "minimum": 1, "maximum": 10000, "description": "Max dynamic judgments allowed. Range: 1-10000." }, "mode": { "type": "string", "enum": [ "MINIMUM_CONFIDENCE", "MATCHING_JUDGEMENTS" ], "description": "Dynamic judgment mode. Default: MINIMUM_CONFIDENCE." }, "minimumConfidence": { "type": [ "number", "null" ], "format": "float", "minimum": 0, "maximum": 1.0, "description": "Confidence threshold. Default: 0.0 (disabled), Range: 0.0-1.0." }, "matchingJudgements": { "type": [ "integer", "null" ], "minimum": 1, "description": "Required matching judgments. Min: 1 when used." }, "enabledQuestions": { "type": "string", "description": "JSON string of enabled questions configuration." }, "id": { "type": "string", "description": "Dynamic judgments configuration ID." }, "version": { "type": "integer", "description": "Dynamic judgments configuration version." } } } } }