openapi: 3.1.0 info: title: durable-workflow.v2.worker-protocol-api version: "7" summary: Durable Workflow worker-plane HTTP+JSON API description: > Normative OpenAPI specification for the worker-plane HTTP+JSON API: worker registration, graceful worker deregistration, worker heartbeat, worker-session lifecycle, long-poll task acquisition, task history paging, task heartbeat, task completion, and task failure. Long-poll timing, cancellation, and lease semantics are specified by durable-workflow.v2.worker-protocol-stream. The server advertises its current 1.N version and accepts request headers from the same major whose minor is less than or equal to N. x-durable-workflow-worker-protocol-negotiation: advertised_version_path: worker_protocol.version default_advertised_version: "1.13" request_header_rule: same_major_and_minor_less_than_or_equal_to_advertised accepted_request_versions_by_default: ["1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12", "1.13"] response_version: advertised_version fail_closed_on: [missing_header, malformed_version, different_major, minor_greater_than_advertised] x-durable-workflow-catalog-entry: worker_protocol_api x-durable-workflow-catalog-schema: durable-workflow.v2.platform-protocol-specs.catalog x-durable-workflow-catalog-version: 16 x-durable-workflow-evolution-rule: additive_minor_breaking_major x-durable-workflow-object-families: - name: worker_registration_request owner_repo: durable-workflow/server - name: worker_deregistration_result owner_repo: durable-workflow/server - name: worker_task_poll_request owner_repo: durable-workflow/server - name: worker_task_result owner_repo: durable-workflow/server - name: worker_query_task_poll_request owner_repo: durable-workflow/server - name: worker_query_task_result owner_repo: durable-workflow/server - name: external_task_input_contract owner_repo: durable-workflow/server - name: external_task_result_contract owner_repo: durable-workflow/server servers: - url: /api security: - durableWorkerAuth: [] paths: /worker/register: post: operationId: registerWorker tags: [worker-lifecycle] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/WorkerRegistrationRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "400": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } "422": { $ref: "#/components/responses/WorkerError" } /worker/registrations/{workerId}: delete: operationId: deregisterWorker summary: Gracefully deregister a worker description: > Removes the named worker registration in the resolved namespace and recovers its outstanding workflow-task leases for replacement workers. This worker-plane lifecycle operation requires the worker role; it is distinct from the administrator-only worker-management endpoint. tags: [worker-lifecycle] x-durable-workflow-required-role: worker parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/WorkerIdPath" responses: "200": { $ref: "#/components/responses/WorkerDeregistrationEnvelope" } "400": { $ref: "#/components/responses/WorkerError" } "401": { $ref: "#/components/responses/WorkerError" } "403": { $ref: "#/components/responses/WorkerError" } "404": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } /worker/heartbeat: post: operationId: heartbeatWorker tags: [worker-lifecycle] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/WorkerHeartbeatRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "404": { $ref: "#/components/responses/WorkerError" } /worker/sessions: post: operationId: createWorkerSession tags: [worker-sessions] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionCreateRequest" } responses: "200": { $ref: "#/components/responses/WorkerSessionOperation" } "201": { $ref: "#/components/responses/WorkerSessionOperation" } "409": { $ref: "#/components/responses/WorkerError" } "412": { $ref: "#/components/responses/WorkerError" } "422": { $ref: "#/components/responses/WorkerError" } /worker/sessions/{sessionId}/heartbeat: post: operationId: heartbeatWorkerSession tags: [worker-sessions] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/SessionIdPath" requestBody: required: true content: application/json: schema: { $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionHeartbeatRequest" } responses: "200": { $ref: "#/components/responses/WorkerSessionOperation" } "404": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } /worker/sessions/{sessionId}: delete: operationId: closeWorkerSession tags: [worker-sessions] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/SessionIdPath" requestBody: required: true content: application/json: schema: { $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionCloseRequest" } responses: "200": { $ref: "#/components/responses/WorkerSessionOperation" } "404": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } /worker/workflow-tasks/poll: post: operationId: pollWorkflowTask tags: [workflow-tasks] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/PollRequest" } responses: "200": description: A claimed workflow task, an empty long-poll result, or a draining-worker response. headers: { X-Durable-Workflow-Protocol-Version: { schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } } } content: application/json: schema: oneOf: - $ref: "#/components/schemas/WorkflowTaskClaim" - $ref: "#/components/schemas/EmptyPoll" - $ref: "#/components/schemas/DrainingPoll" "400": { $ref: "#/components/responses/WorkerError" } /worker/workflow-tasks/{taskId}/history: post: operationId: getWorkflowTaskHistoryPage tags: [workflow-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: false content: application/json: schema: { $ref: "#/components/schemas/HistoryPageRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "404": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } /worker/workflow-tasks/{taskId}/heartbeat: post: operationId: heartbeatWorkflowTask tags: [workflow-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: false content: application/json: schema: { $ref: "#/components/schemas/TaskHeartbeatRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "404": { $ref: "#/components/responses/WorkerError" } "409": { $ref: "#/components/responses/WorkerError" } /worker/workflow-tasks/{taskId}/complete: post: operationId: completeWorkflowTask tags: [workflow-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/WorkflowTaskCompleteRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } "422": { $ref: "#/components/responses/WorkerError" } /worker/workflow-tasks/{taskId}/fail: post: operationId: failWorkflowTask tags: [workflow-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/TaskFailureRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } /worker/query-tasks/poll: post: operationId: pollQueryTask tags: [query-tasks] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/PollRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } /worker/query-tasks/{queryTaskId}/complete: post: operationId: completeQueryTask tags: [query-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - name: queryTaskId in: path required: true schema: { type: string, minLength: 1 } requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/QueryTaskCompleteRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } /worker/query-tasks/{queryTaskId}/fail: post: operationId: failQueryTask tags: [query-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - name: queryTaskId in: path required: true schema: { type: string, minLength: 1 } requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/TaskFailureRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } /worker/activity-tasks/poll: post: operationId: pollActivityTask tags: [activity-tasks] parameters: [{ $ref: "#/components/parameters/WorkerProtocolVersionHeader" }] requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/PollRequest" } responses: "200": description: A claimed activity task, an empty long-poll result, or a draining-worker response. headers: { X-Durable-Workflow-Protocol-Version: { schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } } } content: application/json: schema: oneOf: - $ref: "#/components/schemas/ActivityTaskClaim" - $ref: "#/components/schemas/EmptyPoll" - $ref: "#/components/schemas/DrainingPoll" /worker/activity-tasks/{taskId}/heartbeat: post: operationId: heartbeatActivityTask tags: [activity-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: false content: application/json: schema: { $ref: "#/components/schemas/TaskHeartbeatRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } /worker/activity-tasks/{taskId}/complete: post: operationId: completeActivityTask tags: [activity-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/ActivityTaskCompleteRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } /worker/activity-tasks/{taskId}/fail: post: operationId: failActivityTask tags: [activity-tasks] parameters: - $ref: "#/components/parameters/WorkerProtocolVersionHeader" - $ref: "#/components/parameters/TaskIdPath" requestBody: required: true content: application/json: schema: { $ref: "#/components/schemas/TaskFailureRequest" } responses: "200": { $ref: "#/components/responses/WorkerEnvelope" } "409": { $ref: "#/components/responses/WorkerError" } components: securitySchemes: durableWorkerAuth: type: apiKey in: header name: Authorization parameters: WorkerProtocolVersionHeader: name: X-Durable-Workflow-Protocol-Version in: header required: true description: > Worker-selected protocol version. The default server advertises 1.13 and accepts same-major versions whose minor is no newer than 13. Missing, malformed, different-major, and ahead-of-server values fail closed. schema: { $ref: "#/components/schemas/AcceptedWorkerProtocolRequestVersion" } TaskIdPath: name: taskId in: path required: true schema: { type: string, minLength: 1 } SessionIdPath: name: sessionId in: path required: true schema: { type: string, minLength: 1, maxLength: 255 } WorkerIdPath: name: workerId in: path required: true description: Worker registration identity in the resolved namespace. schema: { type: string, minLength: 1, maxLength: 255 } responses: WorkerEnvelope: description: Worker-protocol response envelope. headers: X-Durable-Workflow-Protocol-Version: schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } content: application/json: schema: { $ref: "#/components/schemas/WorkerEnvelope" } WorkerError: description: Machine-readable worker-protocol error envelope. headers: X-Durable-Workflow-Protocol-Version: schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } content: application/json: schema: { $ref: "#/components/schemas/WorkerError" } WorkerSessionOperation: description: Worker-session lifecycle admission or renewal result. headers: X-Durable-Workflow-Protocol-Version: schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } content: application/json: schema: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionOperationResult" WorkerDeregistrationEnvelope: description: Graceful worker-deregistration result in the WorkerProtocol success envelope. headers: X-Durable-Workflow-Protocol-Version: schema: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } content: application/json: schema: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - $ref: "#/components/schemas/WorkerDeregistrationResult" schemas: AcceptedWorkerProtocolRequestVersion: type: string enum: ["1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12", "1.13"] description: > Request versions accepted by a server using the default advertised version 1.13. If deployment configuration changes the advertised version to 1.N, the accepted set is 1.0 through 1.N. AdvertisedWorkerProtocolVersion: type: string const: "1.13" description: Default worker protocol version advertised by Durable Workflow 2.0 beta responses. WorkerEnvelope: type: object additionalProperties: true required: [protocol_version, server_capabilities] properties: protocol_version: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } server_capabilities: { $ref: "#/components/schemas/WorkerServerCapabilities" } WorkerError: type: object additionalProperties: true required: [protocol_version, server_capabilities] properties: protocol_version: { $ref: "#/components/schemas/AdvertisedWorkerProtocolVersion" } error: { type: string } reason: { type: [string, "null"] } remediation: { type: [string, "null"] } server_capabilities: { $ref: "#/components/schemas/WorkerServerCapabilities" } WorkerServerCapabilities: type: object additionalProperties: true properties: worker_session_verbs: type: array items: { type: string, enum: [create, heartbeat, close] } minItems: 3 worker_sessions: $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionRuntimeContract" WorkerRegistrationRequest: type: object additionalProperties: true required: [worker_id, task_queues] properties: worker_id: { type: string, minLength: 1 } build_id: { type: [string, "null"] } task_queues: { type: array, items: { type: string, minLength: 1 } } workflow_types: { type: array, items: { type: string } } activity_types: { type: array, items: { type: string } } workflow_definition_fingerprints: { type: object, additionalProperties: { type: string } } WorkerHeartbeatRequest: type: object additionalProperties: true required: [worker_id] properties: worker_id: { type: string, minLength: 1 } task_queues: { type: array, items: { type: string } } active_slots: { type: integer, minimum: 0 } WorkerDeregistrationResult: type: object additionalProperties: true required: [worker_id, outcome, recovered_workflow_task_count] properties: worker_id: { type: string, minLength: 1 } outcome: { type: string, const: deregistered } recovered_workflow_task_count: { type: integer, minimum: 0 } PollRequest: type: object additionalProperties: true required: [worker_id, task_queues] properties: worker_id: { type: string, minLength: 1 } task_queues: { type: array, minItems: 1, items: { type: string, minLength: 1 } } build_id: { type: [string, "null"] } poll_timeout_seconds: { type: integer, minimum: 0 } EmptyPoll: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - type: object required: [task] properties: task: { type: "null" } poll_status: { type: string, enum: [timeout, empty] } DrainingPoll: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - type: object required: [task, poll_status] properties: task: { type: "null" } poll_status: { type: string, const: draining } drain_reason: { type: [string, "null"] } WorkflowTaskClaim: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - type: object required: [task] properties: task: type: object additionalProperties: true required: [task_id, workflow_id, run_id, history] properties: task_id: { type: string } workflow_id: { type: string } run_id: { type: string } history: { type: array, items: { type: object, additionalProperties: true } } ActivityTaskClaim: allOf: - $ref: "#/components/schemas/WorkerEnvelope" - type: object required: [task] properties: task: type: object additionalProperties: true required: [task_id, activity_type, attempt] properties: task_id: { type: string } activity_type: { type: string } attempt: { type: integer, minimum: 1 } worker_session: $ref: "./worker-sessions-runtime.schema.json#/$defs/workerSessionTaskAffinity" HistoryPageRequest: type: object additionalProperties: true properties: page_token: { type: [string, "null"] } page_size: { type: integer, minimum: 1 } TaskHeartbeatRequest: type: object additionalProperties: true properties: worker_id: { type: string } progress: true WorkflowTaskCompleteRequest: type: object additionalProperties: true required: [worker_id, commands] properties: worker_id: { type: string, minLength: 1 } commands: type: array items: type: object additionalProperties: true required: [type] properties: type: { type: string } QueryTaskCompleteRequest: type: object additionalProperties: true required: [worker_id] properties: worker_id: { type: string, minLength: 1 } result: true ActivityTaskCompleteRequest: type: object additionalProperties: true required: [worker_id] properties: worker_id: { type: string, minLength: 1 } result: true TaskFailureRequest: type: object additionalProperties: true required: [worker_id] properties: worker_id: { type: string, minLength: 1 } error: { type: [string, "null"] } exception_type: { type: [string, "null"] } message: { type: [string, "null"] } non_retryable: { type: [boolean, "null"] }