> ## Documentation Index
> Fetch the complete documentation index at: https://developer.kodexa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Task Steps

> Use CREATE_TASK steps in Activity Plans to bring people into the workflow for review, correction, approval, exception handling, or escalation.

`CREATE_TASK` steps are how an Activity brings a person into the workflow. Use them when the next decision cannot be safely automated: analyst review, correction, approval, exception handling, reconciliation, or escalation.

An Activity is broader than a task. The Activity owns the business process. A Task is the unit of human work created when that process needs judgment.

## When to Use CREATE\_TASK

Use a `CREATE_TASK` step when the workflow needs someone to:

* Review extracted fields before posting them to a downstream system
* Correct data that failed validation
* Decide whether an exception should be accepted, rejected, or escalated
* Approve work above a business threshold
* Add missing context that is not present in the document
* Resolve a mismatch between the document and a system of record

Do not use `CREATE_TASK` for pure automation. Use `EXECUTION`, `SCRIPT`, `BRIDGE_CALL`, or `LLM` for automated work.

## Basic Shape

```json theme={null}
{
  "slug": "analyst-review",
  "type": "CREATE_TASK",
  "dependsOn": ["route:review"],
  "taskTemplateRef": "invoice-review",
  "taskStatusSlug": "open",
  "taskData": {
    "priority": "high",
    "sourceSystem": "{{inputs.sourceSystem}}"
  }
}
```

| Step field        | Description                                                            |
| ----------------- | ---------------------------------------------------------------------- |
| `taskTemplateRef` | Task Template used to create the human work item                       |
| `taskStatusSlug`  | Initial status for the created Task                                    |
| `taskData`        | Properties copied onto the Task                                        |
| `title`           | Optional explicit title for the Task                                   |
| `description`     | Optional explicit description for the Task                             |
| `priority`        | Optional priority; otherwise the parent Task priority can be inherited |

In the current runtime, the underlying materialized item type is still named `TASK` in some code and stored data. The Activity Plan concept should still be modeled as `CREATE_TASK`: create a Task, wait for human work, then continue the Activity from the Task result.

## Runtime Placeholders

An Activity Plan is defined once and can run in many projects, so task text often needs values that are only known when the Activity runs. Kodexa resolves the following placeholders at the moment the Task is created:

| Placeholder                               | Resolves to                                                                                        |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `${activity.title}`                       | The parent Activity's title at task-creation time, reflecting any automatic or manual rename       |
| `${project.name}`                         | The name of the project the Activity is running in                                                 |
| `${project.id}`                           | The ID of the project the Activity is running in                                                   |
| `${project.options.dataProperties.<key>}` | The value entered for `<key>` in the project's data properties, as defined by the project template |

Placeholders resolve in the Task's `title` and `description` and in top-level string values under `taskData.properties`:

```json theme={null}
{
  "slug": "analyst-review",
  "type": "CREATE_TASK",
  "dependsOn": ["route:review"],
  "taskTemplateRef": "invoice-review",
  "taskData": {
    "title": "Review ${activity.title}",
    "description": "For ${project.name}",
    "properties": {
      "regionCode": "${project.options.dataProperties.regionCode}"
    }
  }
}
```

Resolution rules:

* If `${activity.title}` or `${project.name}` cannot be resolved, the placeholder text is left as-is, so the unresolved token stays visible in the Task.
* A `${project.options.dataProperties.<key>}` placeholder always resolves: when the key is not set, or its value is not a simple value, it resolves to an empty string. This keeps literal tokens out of task properties that downstream systems filter on.

This lets one plan shared across many projects give each child Task a context-specific name, or stamp a project-scoped identifier onto every Task it creates.

## How It Runs

When the step becomes ready, Kodexa:

1. Resolves the target project from the running Activity context.
2. Resolves `taskTemplateRef` inside that project organization.
3. Resolves `taskStatusSlug` to the initial project task status.
4. Builds task properties from `taskData`, title, description, and priority, resolving any [runtime placeholders](#runtime-placeholders).
5. Creates the child Task and links it to the Activity step.
6. Attaches the relevant document families.
7. Waits for the Task to reach an outcome that can continue the Activity.

```mermaid theme={null}
sequenceDiagram
    participant Activity
    participant Step as CREATE_TASK step
    participant Task as Human Task
    participant Reviewer
    Activity->>Step: Dependencies complete
    Step->>Task: Create from Task Template
    Task->>Reviewer: Appears in queue
    Reviewer->>Task: Complete with status or action
    Task-->>Activity: Outcome recorded
    Activity->>Activity: Continue matching downstream path
```

## Document Family Handling

A `CREATE_TASK` step should carry the document context the reviewer needs. The runtime copies document families from the parent workflow context onto the created Task.

When the upstream dependency is a per-document step, Kodexa can narrow the copied document families to the document-level results that actually succeeded. This is useful for exception queues because the reviewer sees only the documents that need attention.

## Document Order on the Task

A task with more than one document opens on a specific document, and its document list is presented in a fixed order. That order comes from an integer `ordinal` carried on each document link:

* When the Activity starts, each document is stamped with its position in the `documentFamilyIds` list it was started with. Index `0` is the Activity's primary document.
* When a `CREATE_TASK` step creates the Task, that order is copied onto the Task's own document links. Ordinal `0` is the Task's primary document — the one the reviewer's workspace opens on.
* When the step narrows the copied set (a per-document dependency where only some documents succeeded), the surviving documents keep their relative Activity order.

So you choose which document a reviewer sees first by listing it first in `documentFamilyIds` when you start the Activity.

Document links created directly through the API follow the same rule. `ordinal` is a field on `TaskDocumentFamily` and `ActivityDocumentFamily`, and on their create and update requests. On `POST /api/task-document-families` and `POST /api/activity-document-families`, omitting `ordinal` — or sending `0` — appends the document after the existing ones, so a link added later never displaces the primary document. An explicit non-zero `ordinal` is stored as given.

<Note>
  Existing multi-document Tasks and Activities were backfilled with a stable order, so they open deterministically without being reprocessed.
</Note>

## Task Templates

The Task Template is where you define the review surface:

* Which Data Form the reviewer sees
* Which document families and data definitions are relevant
* Which actions or statuses complete the work
* Which assignment, priority, or team rules should apply
* Which fields are required before completion

Keep the Activity Plan focused on orchestration. Keep the reviewer experience in the Task Template and Data Form.

## Routing From a Task

Downstream steps can depend on the Task outcome.

```json theme={null}
[
  {
    "slug": "analyst-review",
    "type": "CREATE_TASK",
    "dependsOn": ["route:review"],
    "taskTemplateRef": "invoice-review"
  },
  {
    "slug": "post-approved-invoice",
    "type": "BRIDGE_CALL",
    "dependsOn": ["analyst-review:approved"],
    "serviceBridgeRef": "finance-erp",
    "endpointName": "post-invoice"
  },
  {
    "slug": "notify-rejection",
    "type": "BRIDGE_CALL",
    "dependsOn": ["analyst-review:rejected"],
    "serviceBridgeRef": "finance-erp",
    "endpointName": "reject-invoice"
  }
]
```

The Task remains the human unit of work. The Activity uses the Task outcome to keep the business process moving.

## Naming Tasks

Use clear, business-facing titles. A reviewer should be able to scan a queue and know what needs attention. Titles can include [runtime placeholders](#runtime-placeholders) — for example `Review ${activity.title}` — so a plan shared across projects still produces context-specific names.

Good titles:

* `Review invoice INV-10482`
* `Resolve vendor mismatch`
* `Approve loan packet exception`
* `Review missing claim documents`

Avoid titles that describe implementation details:

* `Step 3 child task`
* `Script exception`
* `Manual checkpoint`

## Practical Pattern

A common Activity Plan shape is:

```mermaid theme={null}
flowchart LR
    Intake["EXECUTION: extract"] --> Route["SCRIPT: route"]
    Route -->|"clean"| Post["BRIDGE_CALL: post"]
    Route -->|"review"| Review["CREATE_TASK: analyst review"]
    Review -->|"approved"| Post
    Review -->|"rejected"| Reject["BRIDGE_CALL: notify rejection"]
```

The Activity handles the process. The Task exists only for the review segment.

## Checklist

* The Task Template exists and is bound to the project.
* The Data Form gives the reviewer all required document and data context.
* The Activity Plan declares every Task outcome that downstream steps depend on.
* The created Task receives the right document families.
* Task titles and priorities are meaningful in a real review queue.
* Automated follow-up work depends on explicit Task outcomes, not only on the Task existing.

<CardGroup cols={2}>
  <Card title="Activity Plan Steps" icon="diagram-project" href="/guides/activity-plans/steps">
    Compare CREATE\_TASK with the other step kinds.
  </Card>

  <Card title="Data Forms" icon="table-layout" href="/guides/data-forms/index">
    Build the reviewer interface used by human Tasks.
  </Card>
</CardGroup>
