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

# Example: multi-step modular task

> Chain a search step into a scrape step so discovered URLs flow straight into structured extraction in one execution.

## Scenario

You track pricing coverage across competitor blogs. You do not have a fixed URL list—you have a query. You want one task that discovers candidate pages, then extracts a structured record from each of them, without running two separate jobs and stitching results together yourself.

This is what an **execution plan** is for: a task with more than one action step, where a later step reads the output of an earlier one.

## Architecture

```mermaid theme={null}
sequenceDiagram
    participant You
    participant TaskService as Task Service
    participant Worker
    You->>TaskService: Create task with a 2-step execution plan
    You->>TaskService: Run task
    TaskService->>Worker: Step 1 — search
    Worker-->>TaskService: Discovered URLs
    TaskService->>Worker: Step 2 — scrape (input from step 1)
    Worker-->>TaskService: Structured records
    You->>TaskService: Read per-step results
```

## Recommended request flow

| Step | API call                                            |
| ---- | --------------------------------------------------- |
| 1    | `POST /api/v1/tasks` with `execution_plan`          |
| 2    | `POST /api/v1/tasks/:id/run`                        |
| 3    | `GET /api/v1/executions/:id/steps`                  |
| 4    | `GET /api/v1/executions/:id/steps/:step_id/results` |

## Step 1: create the task with an execution plan

Each step needs a `step_id`, an `action_type`, and an `input_source`. Set `next_step_id` to wire steps together, and set `input_source: previous_step` on the downstream step so it consumes what the upstream step discovered.

```bash theme={null}
curl -sS -X POST "$TITAN_API_URL/api/v1/tasks" \
  -H "Authorization: Bearer $TITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Competitor pricing page discovery",
    "objective": "Find competitor pricing pages and extract plan names and prices",
    "execution_type": "single",
    "urls": ["https://search.brave.com/search?q=competitor+pricing+page"],
    "execution_plan": {
      "version": 1,
      "steps": [
        {
          "step_id": "discover",
          "action_type": "search",
          "input_source": "static_urls",
          "template_slug": "titan-brave-search-v1",
          "limits": { "max_results": 25, "timeout_seconds": 30 },
          "next_step_id": "extract"
        },
        {
          "step_id": "extract",
          "action_type": "scrape",
          "input_source": "previous_step",
          "template_slug": "generic-web-page-extraction-v1",
          "limits": { "max_urls": 25, "timeout_seconds": 60 },
          "payload": { "format": "markdown", "only_main_content": true },
          "retry_policy": { "max_attempts": 2, "backoff_seconds": 15 }
        }
      ]
    }
  }'
```

<Note>
  `template_slug` values must exist in your deployment's template catalog. List what is available with `GET /api/v1/templates`, or see [Use templates and preview runs](/docs/use-the-platform/use-templates-and-preview-runs).
</Note>

## Step 2: run the task

```bash theme={null}
curl -sS -X POST "$TITAN_API_URL/api/v1/tasks/$TASK_ID/run" \
  -H "Authorization: Bearer $TITAN_TOKEN"
```

The response contains the `execution_id` for this run.

## Step 3: watch step progress

A multi-step execution reports per-step state, so you can see which stage the run is in rather than only an overall status.

```bash theme={null}
curl -sS "$TITAN_API_URL/api/v1/executions/$EXECUTION_ID/steps" \
  -H "Authorization: Bearer $TITAN_TOKEN"
```

Each entry carries a `step_id`, `status`, `expected_count`, and `processed_count`. The `extract` step stays queued until `discover` produces URLs for it.

## Step 4: read results per step

Results are addressed per step, so you can inspect what discovery found separately from what extraction produced.

```bash theme={null}
# What the search step discovered
curl -sS "$TITAN_API_URL/api/v1/executions/$EXECUTION_ID/steps/discover/results?limit=25" \
  -H "Authorization: Bearer $TITAN_TOKEN"

# What the scrape step extracted
curl -sS "$TITAN_API_URL/api/v1/executions/$EXECUTION_ID/steps/extract/results?limit=25" \
  -H "Authorization: Bearer $TITAN_TOKEN"
```

To export everything the run produced in one file, use `GET /api/v1/executions/$EXECUTION_ID/results/export`.

## Retry behavior across steps

`retry_policy` is per step:

| Field             | Effect                                                                                               |
| ----------------- | ---------------------------------------------------------------------------------------------------- |
| `max_attempts`    | How many times a failing work item is retried within the step                                        |
| `backoff_seconds` | Delay between attempts                                                                               |
| `fail_execution`  | When `true`, exhausting retries fails the whole execution instead of continuing with partial results |

Leave `fail_execution` unset when partial coverage is more useful than no results—a discovery step that finds 20 of 25 pages usually still has value.

## Why this example matters

Multi-step plans are what separate a scraping job from a pipeline. The same shape scales to:

* `search` → `scrape` for discovery-first monitoring
* `crawl` → `scrape` for site-wide extraction
* `scrape` → `api_call` for enrichment against your own services

Agents get the same capability without composing plans by hand—see [MCP tool reference](/docs/mcp/tools/overview).

## Next steps

* [Action types overview](/docs/about-platform/action-types/overview)
* [Example: scheduled monitoring workflow](/docs/examples/example-scheduled-monitoring-workflow)
* [Monitor and control executions](/docs/use-the-platform/monitor-and-control-executions)
* [Download results and access media](/docs/use-the-platform/download-results-and-access-media)
