Introduction to the Processes API#
The Processes API enables you to programmatically create, configure, validate, and run workflow processes in Workiva. Use it to automate recurring workflows like financial close checklists, data collection assignments, and certification campaigns — distributing tasks to assignees, tracking completion status, and managing the entire lifecycle without manual intervention.
Before getting started, make sure you have credentials set up.
This guide covers the following scenarios:
Prerequisites & Authentication#
All requests to the Processes API require:
A valid OAuth 2.0 Bearer token
The
X-Version: 2026-04-01.processes.previewheader on every requestThe appropriate OAuth scopes for each operation (noted per endpoint below)
Acceptance of the Preview Features Agreement (contact your CSM or Partner Success Manager)
export TOKEN="your_access_token_here"
export PROCESS_ID="your-process-id"
export PROCESS_RUN_ID="your-process-run-id"
Important
This API is in preview status. Always include X-Version: 2026-04-01.processes.preview on all requests. The API may change before general availability. Do not rely on it for business-critical production workflows until GA.
Note
The Processes API uses a different version header than the main Workiva Platform API (2026-01-01). The preview version is 2026-04-01.processes.preview.
Key Concepts#
Concept |
Description |
|---|---|
Process |
A build-time definition of a workflow. Contains a tree structure of Jobs organized into Groups that define execution order. Think of it as the blueprint. |
ProcessRun |
A runtime instance created when you start a Process. There is a 1:N relationship — one Process can be run many times. Each run tracks its own status independently. |
Job |
A single unit of work within a Process. Each Job has an |
JobRun |
A runtime instance of a Job created when its parent Process is started. Tracks execution status ( |
Group |
A container that organizes Jobs (and nested Groups) into either parallel or serial execution order. Every Process has a |
GroupRun |
A runtime instance of a Group. Tracks aggregated status of its child JobRuns. |
Action |
The type of work a Job performs. Determines the argument schema. Available actions: |
Trigger Type |
Controls when a Job/Group starts: |
Build-Time vs. Run-Time#
The API cleanly separates design from execution:
Phase |
Resources |
What You Do |
|---|---|---|
Build-time |
Process, ProcessJob, ProcessGroup |
Create and configure the workflow structure |
Run-time |
ProcessRun, JobRun, ProcessGroupRun |
Start, monitor, and modify running workflows |
Action Types#
Action |
Purpose |
Key Arguments |
|---|---|---|
|
Send a task assignment to a user with optional approval |
|
|
Request content from a user for a specific document/section |
|
|
Run a certification workflow with signers and approvers |
|
Creating a Process#
Use the create a process endpoint to create a new Process with its full job hierarchy in a single request. The request body defines the process configuration and its root group containing jobs.
Required scope: file:write
POST /processes
{
"name": "Q4 2024 Financial Close",
"autoClose": true,
"certAutoApprove": false,
"relativeDates": true,
"businessStartDate": "2024-10-01",
"businessEndDate": "2024-12-31",
"dueDate": "2024-12-31",
"businessDaysOfWeek": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday"
],
"businessDateExclusions": [
"2024-11-28",
"2024-12-25"
],
"root": {
"name": "Close Workflow",
"parallel": false,
"readOnly": false,
"triggerType": "whenEligible",
"children": [
{
"type": "job",
"job": {
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Reconcile accounts receivable",
"assignee": { "id": "user-analyst-001", "type": "user" },
"approver": { "id": "user-manager-001", "type": "user" },
"dueDate": "2024-12-15",
"approverDueDate": "2024-12-20",
"instructions": "Complete the AR reconciliation for all accounts over $10,000."
}
},
"triggerType": "whenEligible"
}
},
{
"type": "job",
"job": {
"arguments": {
"type": "contentRequest",
"contentRequestArgs": {
"title": "Provide Q4 revenue commentary",
"assignee": { "id": "user-analyst-002", "type": "user" },
"approver": { "id": "user-manager-001", "type": "user" },
"document": "doc-revenue-report-id",
"section": "section-commentary-id",
"dueDate": "2024-12-18",
"instructions": "Add variance explanations for all line items exceeding 5% threshold."
}
},
"triggerType": "whenEligible"
}
}
]
}
}
curl -X POST "https://api.app.wdesk.com/processes" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "X-Version: 2026-04-01.processes.preview" \
-d @request.json
{
"id": "e7b9920095e342889190b4d7eaeca6fa",
"name": "Q4 2024 Financial Close",
"autoClose": true,
"certAutoApprove": false,
"relativeDates": true,
"businessStartDate": "2024-10-01",
"businessDaysOfWeek": ["monday", "tuesday", "wednesday", "thursday", "friday"],
"dueDate": "2024-12-31",
"revision": 1,
"created": {
"dateTime": "2024-10-01T14:30:00Z",
"user": { "id": "V1ZVd2VyFzU3NiQ1NDA4NjIzNzk2MjD" }
},
"modified": {
"dateTime": "2024-10-01T14:30:00Z",
"user": { "id": "V1ZVd2VyFzU3NiQ1NDA4NjIzNzk2MjD" }
},
"root": {
"id": "root-group-abc123",
"name": "Close Workflow",
"parallel": false,
"readOnly": false,
"triggerType": "whenEligible",
"children": [
{
"type": "job",
"job": {
"id": "job-001",
"arguments": { "type": "sendTask" }
}
},
{
"type": "job",
"job": {
"id": "job-002",
"arguments": { "type": "contentRequest" }
}
}
]
}
}
Save the id field — you’ll need it to validate, update, or run the process.
Tip
Set parallel: false on the root group when jobs must execute in sequence (e.g., reconciliation before commentary). Set parallel: true when jobs can run concurrently.
Note
Jobs can be built incrementally. You can create a process with minimal job arguments and fill in details later via the Patch or Batch Update endpoints before running it.
Note
The assignee and approver fields in sendTaskArgs and contentRequestArgs accept a Participant object with id and type properties (e.g., { "id": "userId", "type": "user" }). This matches the SendTaskArguments and ContentRequestArguments schemas. Some API reference examples may show a flat-string shorthand (assigneeUser, approverUser) — always use the object form shown in this guide.
Retrieving a Process#
Use the get a process endpoint to retrieve a process definition by its ID to inspect its current configuration and job hierarchy.
Required scope: file:read
GET /processes/{processId}
curl -X GET "https://api.app.wdesk.com/processes/${PROCESS_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/json" \
-H "X-Version: 2026-04-01.processes.preview"
{
"id": "e7b9920095e342889190b4d7eaeca6fa",
"name": "Q4 2024 Financial Close",
"autoClose": true,
"certAutoApprove": false,
"relativeDates": true,
"dueDate": "2024-12-31",
"revision": 3,
"root": {
"id": "root-group-abc123",
"name": "Close Workflow",
"parallel": false,
"readOnly": false,
"triggerType": "whenEligible",
"children": [
{
"type": "job",
"job": {
"id": "job-001",
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Reconcile accounts receivable",
"assignee": { "id": "user-analyst-001", "type": "user" },
"dueDate": "2024-12-15"
}
}
}
}
]
}
}
Excluding Generated Jobs#
For certification processes, the system generates child jobs (signer actions, approver actions) automatically. To retrieve only the jobs you explicitly defined, use the excludeGeneratedJobs parameter:
GET /processes/{processId}?excludeGeneratedJobs=true
curl -X GET "https://api.app.wdesk.com/processes/${PROCESS_ID}?excludeGeneratedJobs=true" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/json" \
-H "X-Version: 2026-04-01.processes.preview"
Tip
Use excludeGeneratedJobs=true when you only need to inspect the structure you defined. Omit it when you need the full runtime picture including system-generated certification steps.
Updating a Process#
There are two ways to update a process before running it: JSON Patch for configuration changes, and Batch Update for renaming jobs and groups.
Patching Process Configuration#
Use the update a process endpoint with JSON Patch (RFC 6902) to update process-level properties like name, due date, business calendar, and execution settings.
Required scope: file:write
PATCH /processes/{processId}
[
{
"op": "replace",
"path": "/name",
"value": "Q4 2024 Financial Close — Updated"
},
{
"op": "replace",
"path": "/dueDate",
"value": "2025-01-15"
},
{
"op": "replace",
"path": "/autoClose",
"value": false
},
{
"op": "remove",
"path": "/businessDateExclusions"
}
]
curl -X PATCH "https://api.app.wdesk.com/processes/${PROCESS_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json-patch+json" \
-H "X-Version: 2026-04-01.processes.preview" \
-d @request.json
Response (200 OK): Returns the updated Process object.
Patchable paths:
Path |
Operations |
Description |
|---|---|---|
|
|
Process name |
|
|
Process due date |
|
|
Anchor date for relative dates |
|
|
End date for the process |
|
|
Working days array |
|
|
Holiday dates to exclude |
|
|
Override dates to include |
|
|
Auto-close on completion |
|
|
Enable relative date shifting |
|
|
Root group execution mode |
|
|
Root group trigger type |
|
|
Auto-approve certifications |
|
|
Calendar IDs associated with the process |
|
|
IPM beta feature flag |
|
|
IWM opt-out flag |
|
|
Default signer reminders |
|
|
Default approver reminders |
Batch Renaming Jobs and Groups#
Use the bulk update group and job names endpoint to rename multiple jobs and groups in a single request.
Required scope: file:write
POST /processes/{processId}/batchUpdates
{
"data": [
{
"type": "jobName",
"id": "job-001",
"newName": "Reconcile AR — All Entities"
},
{
"type": "groupName",
"id": "root-group-abc123",
"newName": "Q4 Close Workflow — Final"
}
]
}
curl -X POST "https://api.app.wdesk.com/processes/${PROCESS_ID}/batchUpdates" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "X-Version: 2026-04-01.processes.preview" \
-d @request.json
Response (200 OK): Returns the updated Process object.
Note
The batch update endpoint only supports renaming. To update job arguments, due dates, or other structural changes, use the process-level Patch endpoint or recreate the process.
Validating a Process#
Use the validate a process endpoint before running a process to catch configuration errors like missing assignees, invalid dates, or incomplete job arguments. Validation is a read-only operation that does not modify the process.
Required scope: file:read
POST /processes/{processId}/validation
curl -X POST "https://api.app.wdesk.com/processes/${PROCESS_ID}/validation" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/json" \
-H "X-Version: 2026-04-01.processes.preview"
{
"errors": []
}
{
"errors": [
{
"code": "MISSING_REQUIRED_FIELD",
"message": "Job is missing required field: assigneeUser",
"target": "/root/children/0/job"
},
{
"code": "INVALID_DUE_DATE",
"message": "Due date must be in the future",
"target": "/dueDate"
}
]
}
Important
Always validate before running. A process with validation errors will fail to start, returning a 400 Bad Request. Validating first gives you clear, actionable error messages.
Tip
Integrate validation into your automation pipeline as a pre-flight check. If errors is an empty array, the process is ready to run.
Running a Process#
Use the run a process endpoint to start execution of a validated process. This creates a ProcessRun — a runtime instance that tracks status and sends tasks to assignees.
Required scope: file:write
POST /processes/{processId}/run
{
"sendProcessCompleteEmail": true
}
curl -X POST "https://api.app.wdesk.com/processes/${PROCESS_ID}/run" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "X-Version: 2026-04-01.processes.preview" \
-d @request.json
{
"id": "processrun-xyz789",
"name": "Q4 2024 Financial Close",
"process": "e7b9920095e342889190b4d7eaeca6fa",
"status": "running",
"autoClose": true,
"certAutoApprove": false,
"relativeDates": true,
"dueDate": "2024-12-31",
"revision": 0,
"created": {
"dateTime": "2024-10-01T15:00:00Z",
"user": { "id": "V1ZVd2VyFzU3NiQ1NDA4NjIzNzk2MjD" }
},
"statusCounts": {
"waiting": 2
},
"modified": {
"dateTime": "2024-10-01T15:00:00Z",
"user": { "id": "V1ZVd2VyFzU3NiQ1NDA4NjIzNzk2MjD" }
},
"root": {
"id": "grouprun-root123",
"name": "Close Workflow",
"parallel": false,
"readOnly": false,
"status": "waiting",
"children": [
{
"type": "job",
"job": {
"id": "jobrun-001",
"status": "waiting",
"actionStatus": "waiting",
"ordinal": 0,
"readOnly": false,
"revision": 0,
"metadata": {
"type": "sendTask"
},
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Reconcile accounts receivable",
"assignee": { "id": "user-analyst-001", "type": "user" },
"dueDate": "2024-12-15"
}
}
}
}
]
}
}
Save the ProcessRun id — you’ll need it to monitor status and add jobs.
Note
The POST .../run response wraps each child in a job key (the build-time resource name). When you later retrieve the run via GET /processRuns/{id}, the same children use the jobRun key instead, reflecting the runtime resource name. Your code should handle both keys depending on which endpoint it calls.
Note
Setting sendProcessCompleteEmail to true (the default) sends an email notification to the user who started the process when all actions are completed or cancelled. Set to false to suppress this notification.
Tip
You can run the same Process multiple times. Each run creates an independent ProcessRun with its own status tracking.
Monitoring a Process Run#
Use the get a ProcessRun endpoint to retrieve the current state of a running (or completed) process to check overall status and individual job progress.
Required scope: file:read
GET /processRuns/{processRunId}
curl -X GET "https://api.app.wdesk.com/processRuns/${PROCESS_RUN_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/json" \
-H "X-Version: 2026-04-01.processes.preview"
{
"id": "processrun-xyz789",
"name": "Q4 2024 Financial Close",
"process": "e7b9920095e342889190b4d7eaeca6fa",
"status": "running",
"statusCounts": {
"Completed": 1,
"Running": 1,
"Waiting": 1
},
"root": {
"id": "grouprun-root123",
"name": "Close Workflow",
"parallel": false,
"readOnly": false,
"status": "running",
"children": [
{
"type": "job",
"jobRun": {
"id": "jobrun-001",
"action": "sendTask",
"status": "complete",
"actionStatus": "Completed",
"ordinal": 0,
"readOnly": false,
"job": "job-001",
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Reconcile accounts receivable",
"assignee": { "id": "user-analyst-001", "type": "user" },
"dueDate": "2024-12-15"
}
},
"metadata": {
"type": "sendTask",
"sendTaskMetadata": {
"status": "Completed",
"task": "task-abc123",
"permalink": "https://app.wdesk.com/a/workspace123/tasks/task-abc123",
"taskCancelled": false,
"cancelCleanupComplete": false,
"taskCancelledNotificationSent": false
}
}
}
},
{
"type": "job",
"jobRun": {
"id": "jobrun-002",
"action": "contentRequest",
"status": "waiting",
"actionStatus": "Waiting",
"ordinal": 1,
"readOnly": false,
"job": "job-002",
"arguments": {
"type": "contentRequest",
"contentRequestArgs": {
"title": "Provide Q4 revenue commentary",
"assignee": { "id": "user-analyst-002", "type": "user" },
"document": "doc-revenue-report-id"
}
},
"metadata": {
"type": "contentRequest",
"contentRequestMetadata": {
"status": "Created",
"task": "task-def456",
"permalink": "https://app.wdesk.com/a/workspace123/tasks/task-def456",
"taskCancelled": false,
"cancelCleanupComplete": false,
"taskCancelledNotificationSent": false
}
}
}
},
{
"type": "job",
"jobRun": {
"id": "jobrun-003",
"action": "sendTask",
"status": "running",
"actionStatus": "Running",
"ordinal": 2,
"readOnly": false,
"job": "job-003"
}
}
]
}
}
Understanding Status Fields#
Each ProcessRun and JobRun has two status-related fields:
status— the general execution status of the JobRun (lowercase values):
Status |
Meaning |
|---|---|
|
Not yet started; waiting for predecessors to complete |
|
Currently active; tasks have been sent to assignees |
|
All work finished successfully |
|
Explicitly cancelled |
|
Cancel in progress |
|
Failed due to an error |
|
Paused due to an error; may be retried |
actionStatus— an action-specific status (capitalized values, e.g.,"Waiting","Running","Completed").
The statusCounts object provides a quick summary of how many JobRuns are in each action status. Note that these keys use capitalized values (e.g., "Completed": 1, "Running": 1, "Waiting": 1), matching actionStatus casing — not the lowercase status field.
Tip
Poll the ProcessRun endpoint periodically to track progress. Use statusCounts for a high-level overview, or traverse root.children for per-job detail. When writing code that checks statuses, be aware that status is lowercase while actionStatus and statusCounts keys are capitalized.
Note
The metadata field on each JobRun contains action-specific runtime information. For sendTask actions, it includes the created task ID, a permalink URL that links directly to the task in the Workiva UI, and boolean tracking fields like taskCancelled and cancelCleanupComplete. For contentRequest actions, a similar contentRequestMetadata object is returned.
Adding Jobs to a Running Process#
Use the create job runs endpoint to add new jobs to a process that is already running. This is useful when additional work emerges mid-workflow that wasn’t part of the original process definition.
Required scope: file:write
POST /processRuns/{processRunId}/jobRuns
You can control placement of new jobs using query parameters:
Parameter |
Description |
|---|---|
|
Place the new jobs in this group (defaults to root group) |
|
Insert relative to this existing job or group |
|
String. If |
[
{
"action": "sendTask",
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Review intercompany eliminations",
"assignee": { "id": "user-analyst-003", "type": "user" },
"approver": { "id": "user-manager-001", "type": "user" },
"dueDate": "2024-12-22",
"instructions": "Verify all intercompany balances net to zero."
}
},
"triggerType": "whenEligible"
}
]
curl -X POST "https://api.app.wdesk.com/processRuns/${PROCESS_RUN_ID}/jobRuns?parentGroupId=grouprun-root123" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "X-Version: 2026-04-01.processes.preview" \
-d @request.json
[
{
"id": "jobrun-new-001",
"action": "sendTask",
"status": "waiting",
"ordinal": 2,
"parent": "grouprun-root123",
"triggerType": "whenEligible",
"arguments": {
"type": "sendTask",
"sendTaskArgs": {
"title": "Review intercompany eliminations",
"assignee": { "id": "user-analyst-003", "type": "user" },
"approver": { "id": "user-manager-001", "type": "user" },
"dueDate": "2024-12-22"
}
}
}
]
Important
New jobs added to a running process will start executing according to their triggerType. If set to whenEligible and the process is already past the insertion point in serial execution, the job may start immediately.
Tip
You can add multiple jobs in a single request by including multiple objects in the array. They will be inserted in order at the specified position.
Trashing and Restoring a Process#
Trashing a Process#
Use the delete a process endpoint to soft-delete a process by moving it to trash. This does not permanently destroy the process.
Required scope: file:write
DELETE /processes/{processId}
curl -X DELETE "https://api.app.wdesk.com/processes/${PROCESS_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/json" \
-H "X-Version: 2026-04-01.processes.preview"
Response (204 No Content)
Restoring a Process#
Use the restore a process endpoint to restore a previously trashed process.
Required scope: file:write
POST /processes/{processId}/restore
curl -X POST "https://api.app.wdesk.com/processes/${PROCESS_ID}/restore" \
-H "Authorization: Bearer ${TOKEN}" \
-H "X-Version: 2026-04-01.processes.preview"
Response (200 OK): Returns the restored Process object.
Note
Only trashed processes can be restored. Attempting to restore an active process will return a 409 Conflict.
Common Issues#
Issue |
Solution |
|---|---|
|
Run validation first ( |
Jobs not starting in expected order |
Check the |
|
The process may already have an active run or be in a state that doesn’t support starting. Check existing ProcessRuns. |
Missing |
Every request requires |
|
Ensure your OAuth 2.0 token has the |
Jobs created with incomplete arguments |
Jobs can be created incrementally with partial arguments. Validation will catch missing required fields before you attempt to run. |
Certification jobs generate unexpected children |
Certification actions automatically generate signer and approver JobRuns. Use |
Relative dates not shifting |
Ensure |
Rate limiting ( |
The API enforces rate limits. If you receive a |
Summary of API Endpoints#
Operation |
Method |
Endpoint |
Required Scope |
|---|---|---|---|
Create a Process |
|
|
|
Get a Process |
|
|
|
Patch a Process |
|
|
|
Batch Update a Process |
|
|
|
Validate a Process |
|
|
|
Run a Process |
|
|
|
Get a Process Run |
|
|
|
Create Job Runs |
|
|
|
Trash a Process |
|
|
|
Restore a Process |
|
|
|