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

# Tasks

> A task tells an agent what to do and what to return.

A task defines the input it accepts, the output it produces, and the work the agent performs on the source. You write the schema and task goal, Deck handles everything else. Every task run returns the same structured output regardless of which source it runs against, you only need a single task for every source.

## How tasks fit in

Tasks belong to an [agent](/concepts/agents). When you run a task, you provide the task input defined by its schema and either a source or a [credential](/concepts/credentials). Deck creates a [session](/concepts/sessions) and a [task run](/concepts/task-runs) that executes the work.

## Creating tasks

Tasks can be created in the Console with prompting or through the API. Once created, you reference them by ID in your API calls.

## Writing the prompt

The `prompt` field tells the agent what to accomplish on the source. Describe the goal, not the steps to get there.

A task runs across every source that supports it. The same "fetch my latest bill" task works on any utility provider, so the prompt should be source-agnostic. Don't reference specific websites, page layouts, or UI elements.

Your prompt gets combined with Deck's agent harness, a built-in set of guidance that tells the agent how to navigate sites, handle authentication, recover from errors, and use its tools. When your prompt includes detailed navigation instructions, they can conflict with the harness or restrict tools the agent would otherwise use to complete the task. Keep your prompt focused on the outcome and let the harness handle execution.

<Tabs>
  <Tab title="Good">
    ```text theme={null}
    Log in to the source and fetch my latest bill.
    ```

    ```text theme={null}
    Log in and fetch upcoming reservations.
    ```

    These prompts describe **what** the agent should do. The agent handles the how.
  </Tab>

  <Tab title="Bad">
    ```text theme={null}
    Go to the login page, click the sign-in button, enter the username
    in the email field, click submit, then navigate to the billing
    section and click on the most recent invoice.
    ```

    Step-by-step instructions fight the agent instead of guiding it. They assume a specific site layout that may differ across sources or change over time.
  </Tab>
</Tabs>

Reference inputs by name in the goal rather than writing values inline: `Download bills between {start_date} and {end_date}`. This keeps the prompt reusable across runs.

Never put credentials or login instructions in the prompt. Deck authenticates the session with the stored [credential](/concepts/credentials) before the agent starts on your goal.

## Read vs. write

Tasks can be read operations (fetching data) or write operations (performing actions).

| Type  | Examples                                                      |
| ----- | ------------------------------------------------------------- |
| Read  | Fetch account balance, list transactions, download statements |
| Write | Submit a form, make a payment, cancel a reservation           |

The API treats both the same way. The distinction is in what the agent does on the source.

## Input and output schemas

Every task defines a contract through JSON Schema:

* **Input schema** validates what you send when running the task. Deck rejects requests that don't match before the agent starts.
* **Output schema** defines the structure of the data the agent returns. Regardless of how the source renders its data, Deck returns a consistent shape.

This contract means your integration code works the same way across sources. A "fetch reservations" task returns the same structure whether the source is Hilton, Marriott, or Hyatt.

### Designing the input schema

Only include fields that change between runs. The input should capture what your application needs to parameterize, not how the source works. Keep it source-agnostic so the same task runs against any supporting source.

<Tabs>
  <Tab title="Good">
    ```json theme={null}
    {
      "start_date": "2026-04-01",
      "end_date": "2026-04-05"
    }
    ```

    Minimal, generic fields that apply to any source.
  </Tab>

  <Tab title="Bad">
    ```json theme={null}
    {
      "start_date": "2026-04-01",
      "end_date": "2026-04-05",
      "hilton_rewards_id": "HH-9281744",
      "booking_portal_region": "us-east"
    }
    ```

    Source-specific fields break the task for other sources.
  </Tab>
</Tabs>

### Accepting file inputs

<Note>
  File inputs are available on Enterprise plans. The `extraction` purpose additionally requires the extraction and storage add-ons.
</Note>

A task can accept files as input. Define a file field in the input schema as an object whose `purpose` selects how Deck handles the file, with `data` carrying the file as base64. Two purposes are supported:

| `purpose`    | What Deck does                                                              |
| ------------ | --------------------------------------------------------------------------- |
| `attachment` | The agent receives the file at run time and uses it on the source.          |
| `extraction` | Deck extracts structured JSON from the file directly. The agent is skipped. |

```json theme={null}
{
  "name": "Submit application",
  "agent_id": "agt_a1b2c3d4...",
  "input_schema": {
    "type": "object",
    "properties": {
      "applicant_name": { "type": "string" },
      "resume": {
        "type": "object",
        "properties": {
          "purpose": { "const": "attachment" },
          "file_name": { "type": "string" },
          "content_type": { "type": "string" },
          "data": { "type": "string", "contentEncoding": "base64" }
        }
      }
    },
    "required": ["applicant_name", "resume"]
  }
}
```

See [providing files as input](/guides/storage#providing-files-as-input) for both purposes and the full walkthrough.

### Designing the output schema

Design the output for what your application needs, not what a specific source displays. The schema should be generic enough to work across all sources that support the task. Optional fields come back `null` when the source doesn't contain that information. If the source doesn't contain a field the schema marks as `required`, the run fails with a [`task_not_supported`](/api/errors) error.

Captured files appear in [storage](/concepts/storage), not the output schema. Don't add fields like file names or file counts; they duplicate what storage already returns and can drift from what was actually captured. The storage object is the source of truth for captured files and downloads. Keep the output schema for data the agent reads from the source.

<Tabs>
  <Tab title="Good">
    ```json theme={null}
    {
      "reservations": [
        {
          "confirmation_number": "HLT-849271",
          "hotel_name": "Hilton Garden Inn",
          "check_in": "2026-04-01",
          "check_out": "2026-04-05",
          "total_cost": 847.50
        }
      ]
    }
    ```

    Flat, generic fields. Any hotel source can populate these.
  </Tab>

  <Tab title="Bad">
    ```json theme={null}
    {
      "hilton_honors_data": {
        "tier_status": "Gold",
        "points_breakdown": {
          "base_points": 12000,
          "bonus_points": 3000,
          "milestone_bonuses": 5000
        }
      }
    }
    ```

    Mirrors a single source's data model. Other sources can't fill these fields.
  </Tab>
</Tabs>

## Tokenizing sensitive fields

<Note>
  Available on Enterprise plans.
</Note>

Some tasks take sensitive input, such as a card number or CVV, that should never sit in plaintext in your task input or appear in logs. Declare those fields in a `tokenized` array on the input schema when you create the task. Each entry must match a property defined in `properties`.

```json theme={null}
{
  "name": "Add payment method",
  "agent_id": "agt_...",
  "prompt": "Add a new payment method to the user's account.",
  "input_schema": {
    "type": "object",
    "properties": {
      "card_number":     { "type": "string" },
      "expiration":      { "type": "string" },
      "cvv":             { "type": "string" },
      "cardholder_name": { "type": "string" }
    },
    "required": ["card_number", "expiration", "cvv", "cardholder_name"],
    "tokenized": ["card_number", "cvv", "cardholder_name"]
  }
}
```

Here `card_number`, `cvv`, and `cardholder_name` are tokenized; `expiration` is sent normally. When you run the task, pass every field as usual. Deck vaults the marked values as the run is created, before anything is written: the stored run holds tokens in place of the real values, and if vaulting fails the run isn't created rather than stored in the clear. The values are restored only when the run executes, so the agent can use them on the source. Tokenized fields must be string values.

Tokenized inputs go into [Deck Vault](/platform/credential-management), the same vault that holds credential secrets, and get the same handling: scrubbed from logs and never readable back. In API responses, tokenized fields are removed from the run's `input` entirely, and a `tokenized` array lists which field names were removed. You can't query the original values back through the API.

## Run timeout

Each run of a task is bounded by a timeout. Set it per task with `settings.timeout_seconds`, a positive integer giving the maximum wall-clock seconds a single run may execute before Deck stops it and the run fails with a `timeout` error.

```json theme={null}
{
  "name": "Fetch latest bill",
  "agent_id": "agt_a1b2c3d4...",
  "settings": {
    "timeout_seconds": 3600
  }
}
```

If you don't set one, the task uses your plan's default timeout. The maximum you can set is determined by your plan — see [pricing](https://deck.co/pricing) for the cap on each tier — and the overall ceiling is **8 hours** (`28800` seconds).

Deck validates the value when you create or update the task:

| Condition                 | Result                                                 |
| ------------------------- | ------------------------------------------------------ |
| Above your plan's maximum | Rejected with a `422` `timeout_exceeds_plan_max` error |
| Not a positive integer    | Rejected with a `422` `invalid_field_value` error      |

The task object echoes back what you set under `settings.timeout_seconds`. A `null` `settings` means no custom timeout is set and runs use your plan's default. See [task run timeouts](/concepts/task-runs#timeouts) for what happens when a run exceeds the window.

## Task statuses

| Status     | Meaning                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------- |
| `learning` | The agent is learning how to perform the task. You can run it, but expect lower success rates. |
| `test`     | The agent understands the task but is still improving. Higher success rates than `learning`.   |
| `live`     | Production-ready. The agent fully understands the task.                                        |

A task graduates after **3 successful runs** in its current stage: `learning` → `test` after 3 successes, then `test` → `live` after 3 more. Check `status` on the task object to see where it currently sits.

If you update a task, it may move back to `learning` or `test` while the agent adapts to the changes.

## Resetting a task

Once a task has progressed to `test` or `live`, the agent reuses what it has learned on subsequent runs. If the task is struggling to deliver successful results or you want the agent to start over, you can reset the task back to `learning`.

Reset a task from the Console on the task detail page, or call [`POST /tasks/{task_id}/reset`](/api-reference/tasks/reset-a-task). The task's status returns to `learning`, and on the next run the agent learns how to perform the task again. Expect lower success rates until it progresses back to `test` or `live`.

## Deep dives

<CardGroup cols={2}>
  <Card title="Storage" icon="box-archive" href="/concepts/storage">
    Capture files during task execution and extract structured data.
  </Card>

  <Card title="Task runs" icon="play" href="/concepts/task-runs">
    What happens when you execute a task.
  </Card>
</CardGroup>
