```yaml
product: AlterLab
title: Agent Runs
category: guides
comparison_context: "AlterLab is an alternative to Firecrawl, ScrapingBee, and Bright Data."
source_url: https://alterlab.io/docs/guides/agent-runs
```

# Agent Runs

One run API for multi-step work: submit a plan, get one estimate, approve a hard credit budget and follow typed progress events.

> **Beta.** Runs are in beta and enabled per account. When the beta is not enabled, the endpoints, MCP tools and CLI commands return the API's beta error.

## Lifecycle

A run moves from `awaiting_approval` to `running` and ends in `succeeded`, `partial`, `failed`, `cancelled` or `budget_exhausted`. Nothing executes until you approve it, unless you set `auto_approve` and the estimate fits `max_credits`. Steps are scrape or search steps; each `params` object is the request body of the matching endpoint.

## Create a Run

```bash
curl -X POST https://api.alterlab.io/api/v1/runs \
  -H "X-API-Key: your_api_key" \
  -H "Idempotency-Key: pricing-check-1" \
  -H "Content-Type: application/json" \
  -d '{
    "max_credits": 50000,
    "steps": [
      {"id": "s1", "type": "search", "params": {"query": "acme pricing"}},
      {"id": "s2", "type": "scrape", "params": {"url": "https://example.com/pricing"}}
    ]
  }'
```

The response holds the run id, its state and one estimate summed over every step. The same `Idempotency-Key` with the same plan returns the original run; with a different plan it returns 409. Add `"dry_run": true` to validate and estimate without storing a run.

## Approve

```bash
curl -X POST https://api.alterlab.io/api/v1/runs/RUN_ID/approve \
  -H "X-API-Key: your_api_key"
```

Approval reserves the budget in one debit before any step starts. An insufficient balance returns 402 and no step runs. An unapproved run expires after 24 hours.

## Stream Events

```bash
curl -N https://api.alterlab.io/api/v1/runs/RUN_ID/events \
  -H "X-API-Key: your_api_key" \
  -H "Last-Event-ID: 12"
```

Server-sent events carry a per-run `seq` as the SSE id. Reconnect with `Last-Event-ID` to replay the events you missed in order. The stream closes once the run is finished and drained.

## Fetch the Result

```bash
curl https://api.alterlab.io/api/v1/runs/RUN_ID \
  -H "X-API-Key: your_api_key"
```

Returns the state, estimate, credits spent and a summary of each step.

## Budget

`max_credits` is a hard cap. Spend never goes past it, the stricter of your key spend limit and the run budget applies, and the unused part of the reservation is refunded when the run ends or is cancelled.

## MCP Tools

- `alterlab_run_create`: submit a plan and get the estimate
- `alterlab_run_approve`: approve and start the run
- `alterlab_run_stream`: collect events, resume with `last_event_id`
- `alterlab_run_result`: state, spend and step summaries
- `alterlab_run_cancel`: cancel and refund the unused budget

## CLI

```bash
alterlab run create plan.json --max-credits 50000
alterlab run approve RUN_ID
alterlab run stream RUN_ID
alterlab run result RUN_ID
alterlab run cancel RUN_ID
```

Every command prints one JSON object per line on stdout. `stream` prints one event per line and resumes with `Last-Event-ID` if the connection drops; `--last-event-id N` starts after a known `seq`.
