---
title: Workflow Parameters
subtitle: Configure how your workflow runs
slug: multi-step-automations/workflow-parameters
---

This page covers all parameters you can pass when creating and running workflows.

---

## Quick reference: Creating a workflow

| Parameter | Type | Use this to |
|-----------|------|-------------|
| [`title`](#title) **(Required)** | string | Name the workflow for identification |
| [`workflow_definition`](#workflow_definition) **(Required)** | object | Define blocks, parameters, and logic |
| [`description`](#description) | string | Document what the workflow does |
| [`proxy_location`](#proxy_location-create) | string or object | Set default proxy for all blocks |
| [`webhook_callback_url`](#webhook_callback_url) | string | Get notified when any run of this workflow completes |
| [`persist_browser_session`](#persist_browser_session) | boolean | Keep the browser session alive across blocks |

---

## Quick reference: Running a workflow

| Parameter | Type | Use this to |
|-----------|------|-------------|
| [`workflow_id`](#workflow_id) **(Required)** | string | Specify which workflow to run |
| [`parameters`](#parameters) | object | Pass values for workflow input parameters |
| [`title`](#title-run) | string | Name this specific workflow run |
| [`proxy_location`](#proxy_location-run) | string or object | Override the default proxy location |
| [`webhook_url`](#webhook_url) | string | Get notified when the workflow completes |
| [`browser_session_id`](#browser_session_id) | string | Reuse a persistent browser session |
| [`browser_profile_id`](#browser_profile_id) | string | Reuse a browser profile (cookies, storage) |

---

## Creating a workflow

<Info>
All create parameters (`title`, `workflow_definition`, `description`, `proxy_location`, etc.) are nested inside a **`json_definition`** object — not passed at the top level. You can alternatively use `yaml_definition` (a YAML string) instead.
</Info>

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "...",
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "...",
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "...",
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

### `title`

**Required.** Display name for the workflow. This field goes inside the `json_definition` object.

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "Invoice Downloader",
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "Invoice Downloader",
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "Invoice Downloader",
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

---

### `workflow_definition`

**Required.** The workflow structure containing parameters and blocks.

```json
{
  "workflow_definition": {
    "parameters": [...],
    "blocks": [...]
  }
}
```

#### `parameters`

Input parameters the workflow accepts. Each parameter has:

| Field | Type | Description |
|-------|------|-------------|
| `key` | string | Parameter name, used to reference via `{{ key }}` |
| `parameter_type` | string | Always `"workflow"` for input parameters |
| `workflow_parameter_type` | string | Data type: `string`, `integer`, `float`, `boolean`, `json`, `file_url`, `credential_id` |
| `default_value` | any | Optional default value |
| `description` | string | Optional description |

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "Job Application Workflow",
        "workflow_definition": {
            "parameters": [
                {
                    "key": "resume",
                    "parameter_type": "workflow",
                    "workflow_parameter_type": "file_url",
                    "description": "URL to the resume PDF"
                },
                {
                    "key": "job_urls",
                    "parameter_type": "workflow",
                    "workflow_parameter_type": "json",
                    "default_value": []
                },
                {
                    "key": "cover_letter",
                    "parameter_type": "workflow",
                    "workflow_parameter_type": "string",
                    "default_value": ""
                }
            ],
            "blocks": [...]
        }
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "Job Application Workflow",
      workflow_definition: {
        parameters: [
          {
            key: "resume",
            parameter_type: "workflow",
            workflow_parameter_type: "file_url",
            description: "URL to the resume PDF",
          },
          {
            key: "job_urls",
            parameter_type: "workflow",
            workflow_parameter_type: "json",
            default_value: [],
          },
          {
            key: "cover_letter",
            parameter_type: "workflow",
            workflow_parameter_type: "string",
            default_value: "",
          },
        ],
        blocks: [...],
      },
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "Job Application Workflow",
      "workflow_definition": {
        "parameters": [
          {
            "key": "resume",
            "parameter_type": "workflow",
            "workflow_parameter_type": "file_url",
            "description": "URL to the resume PDF"
          },
          {
            "key": "job_urls",
            "parameter_type": "workflow",
            "workflow_parameter_type": "json",
            "default_value": []
          },
          {
            "key": "cover_letter",
            "parameter_type": "workflow",
            "workflow_parameter_type": "string",
            "default_value": ""
          }
        ],
        "blocks": [...]
      }
    }
  }'
```
</CodeGroup>

**Parameter types:**

| Type | Description | Example |
|------|-------------|---------|
| `string` | Text value | `"John Smith"` |
| `integer` | Whole number | `42` |
| `float` | Decimal number | `99.99` |
| `boolean` | True/false | `true` |
| `json` | JSON object or array | `{"key": "value"}` or `["a", "b"]` |
| `file_url` | URL to a file | `"https://example.com/resume.pdf"` |
| `credential_id` | Reference to a stored credential | `"cred_abc123"` |

#### `blocks`

Array of blocks that execute in sequence. See [Workflow Blocks Reference](/multi-step-automations/workflow-blocks-reference) for all block types.

---

### `description`

Optional description of what the workflow does.

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "Invoice Downloader",
        "description": "Downloads all invoices from the vendor portal since a given date",
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "Invoice Downloader",
      description: "Downloads all invoices from the vendor portal since a given date",
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "Invoice Downloader",
      "description": "Downloads all invoices from the vendor portal since a given date",
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

---

### `proxy_location` (create)

Default proxy location for all blocks in the workflow. Individual blocks can override this.

See [Proxy & Geo Targeting](/going-to-production/proxy-geolocation) for all available locations.

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "UK Price Checker",
        "proxy_location": "RESIDENTIAL_GB",
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "UK Price Checker",
      proxy_location: "RESIDENTIAL_GB",
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "UK Price Checker",
      "proxy_location": "RESIDENTIAL_GB",
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

---

### `webhook_callback_url`

URL to receive a POST request whenever any run of this workflow completes. This is set at the workflow level and applies to all runs. To set a webhook for a single run instead, use [`webhook_url`](#webhook_url) when running the workflow.

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "Invoice Downloader",
        "webhook_callback_url": "https://your-server.com/webhook",
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "Invoice Downloader",
      webhook_callback_url: "https://your-server.com/webhook",
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "Invoice Downloader",
      "webhook_callback_url": "https://your-server.com/webhook",
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

---

### `persist_browser_session`

If `true`, the browser session is kept alive across all blocks in the workflow. This means blocks share the same browser context including cookies, local storage, and login state.

Defaults to `false`.

<CodeGroup>
```python Python
workflow = await client.create_workflow(
    json_definition={
        "title": "Multi-Step Portal Scraper",
        "persist_browser_session": True,
        "workflow_definition": {...}
    }
)
```

```typescript TypeScript
const workflow = await client.createWorkflow({
  body: {
    json_definition: {
      title: "Multi-Step Portal Scraper",
      persist_browser_session: true,
      workflow_definition: {...},
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "json_definition": {
      "title": "Multi-Step Portal Scraper",
      "persist_browser_session": true,
      "workflow_definition": {...}
    }
  }'
```
</CodeGroup>

<Info>
Additional advanced parameters are available when creating a workflow, including `totp_verification_url`, `totp_identifier`, `model`, and `extra_http_headers`. See the [API Reference](/api-reference) for the full list.
</Info>

---

## Running a workflow

### `workflow_id`

**Required.** The ID of the workflow to run. This is the `workflow_permanent_id` returned when creating the workflow.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    parameters={...}
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    parameters: {...},
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "parameters": {...}
  }'
```
</CodeGroup>

---

### `parameters`

Values for the workflow's input parameters. Keys must match the `key` field in the workflow's parameter definitions.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    parameters={
        "resume": "https://example.com/resume.pdf",
        "job_urls": [
            "https://jobs.lever.co/company/position-1",
            "https://jobs.lever.co/company/position-2"
        ],
        "cover_letter": "I am excited to apply for this position..."
    }
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    parameters: {
      resume: "https://example.com/resume.pdf",
      job_urls: [
        "https://jobs.lever.co/company/position-1",
        "https://jobs.lever.co/company/position-2",
      ],
      cover_letter: "I am excited to apply for this position...",
    },
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "parameters": {
      "resume": "https://example.com/resume.pdf",
      "job_urls": [
        "https://jobs.lever.co/company/position-1",
        "https://jobs.lever.co/company/position-2"
      ],
      "cover_letter": "I am excited to apply for this position..."
    }
  }'
```
</CodeGroup>

Parameters with `default_value` in the workflow definition are optional. Parameters without defaults are required.

---

### `proxy_location` (run)

Override the workflow's default proxy location for this run.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    parameters={...},
    proxy_location="RESIDENTIAL_CA"
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    parameters: {...},
    proxy_location: "RESIDENTIAL_CA",
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "parameters": {...},
    "proxy_location": "RESIDENTIAL_CA"
  }'
```
</CodeGroup>

**Proxy locations:**

| Value | Location |
|-------|----------|
| `RESIDENTIAL` | United States **(default)** |
| `RESIDENTIAL_ISP` | United States (static ISP IPs) |
| `RESIDENTIAL_AR` | Argentina |
| `RESIDENTIAL_AU` | Australia |
| `RESIDENTIAL_BR` | Brazil |
| `RESIDENTIAL_CA` | Canada |
| `RESIDENTIAL_DE` | Germany |
| `RESIDENTIAL_ES` | Spain |
| `RESIDENTIAL_FR` | France |
| `RESIDENTIAL_GB` | United Kingdom |
| `RESIDENTIAL_IE` | Ireland |
| `RESIDENTIAL_IN` | India |
| `RESIDENTIAL_IT` | Italy |
| `RESIDENTIAL_JP` | Japan |
| `RESIDENTIAL_MX` | Mexico |
| `RESIDENTIAL_NL` | Netherlands |
| `RESIDENTIAL_NZ` | New Zealand |
| `RESIDENTIAL_TR` | Türkiye |
| `RESIDENTIAL_ZA` | South Africa |
| `NONE` | No proxy |

For US state or city-level targeting, pass a `GeoTarget` object instead:

```json
{
  "proxy_location": {
    "country": "US",
    "subdivision": "CA",
    "city": "San Francisco"
  }
}
```

`country` is required (ISO 3166-1 alpha-2 code). `subdivision` and `city` are optional.

See [Proxy & Geo Targeting](/going-to-production/proxy-geolocation) for more details.

---

### `webhook_url`

URL to receive a POST request when the workflow completes.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    parameters={...},
    webhook_url="https://your-server.com/webhook"
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    parameters: {...},
    webhook_url: "https://your-server.com/webhook",
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "parameters": {...},
    "webhook_url": "https://your-server.com/webhook"
  }'
```
</CodeGroup>

The webhook payload contains the same data as the polling response. See [Webhooks](/going-to-production/webhooks) for authentication and retry options.

---

### `title` (run)

Optional display name for this specific workflow run. Useful for distinguishing runs in the UI and API responses.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    title="January 2025 Invoice Batch",
    parameters={...}
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    title: "January 2025 Invoice Batch",
    parameters: {...},
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "title": "January 2025 Invoice Batch",
    "parameters": {...}
  }'
```
</CodeGroup>

---

### `browser_session_id`

ID of an existing Skyvern browser session to reuse. The workflow run continues from the current screen state of that session. Browser session IDs start with `pbs_`.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    browser_session_id="pbs_abc123",
    parameters={...}
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    browser_session_id: "pbs_abc123",
    parameters: {...},
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "browser_session_id": "pbs_abc123",
    "parameters": {...}
  }'
```
</CodeGroup>

---

### `browser_profile_id`

ID of a browser profile to reuse. Browser profiles persist cookies, local storage, and other browser state across runs. Profile IDs start with `bp_`.

<CodeGroup>
```python Python
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    browser_profile_id="bp_xyz789",
    parameters={...}
)
```

```typescript TypeScript
const run = await client.runWorkflow({
  body: {
    workflow_id: "wpid_123456789",
    browser_profile_id: "bp_xyz789",
    parameters: {...},
  },
});
```

```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/workflows" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wpid_123456789",
    "browser_profile_id": "bp_xyz789",
    "parameters": {...}
  }'
```
</CodeGroup>

<Info>
Additional advanced parameters are available when running a workflow, including `totp_url`, `totp_identifier`, `browser_address`, `extra_http_headers`, and `max_screenshot_scrolls`. See the [API Reference](/api-reference) for the full list.
</Info>

---

## Run response

When you run a workflow, the response contains:

| Field | Type | Description |
|-------|------|-------------|
| `run_id` | string | Unique ID for this run (starts with `wr_`). |
| `status` | string | One of: `created`, `queued`, `running`, `completed`, `failed`, `terminated`, `timed_out`, `canceled`. |
| `output` | object/array/string/null | Extracted data from the workflow, if any. |
| `failure_reason` | string/null | Why the run failed, if applicable. |
| `errors` | array/null | List of errors encountered during the run. |
| `downloaded_files` | array/null | Files downloaded during the run. |
| `recording_url` | string/null | URL to the browser recording. |
| `screenshot_urls` | array/null | Latest screenshots in reverse chronological order. |
| `app_url` | string/null | Link to view this run in the Skyvern UI. |
| `created_at` | datetime | When the run was created. |
| `started_at` | datetime/null | When execution started. |
| `finished_at` | datetime/null | When execution finished. |

---

## Next steps

<CardGroup cols={2}>
  <Card
    title="Build a Workflow"
    icon="hammer"
    href="/multi-step-automations/build-a-workflow"
  >
    Create and run your first workflow
  </Card>
  <Card
    title="Workflow Blocks Reference"
    icon="cube"
    href="/multi-step-automations/workflow-blocks-reference"
  >
    Detailed documentation for all block types
  </Card>
  <Card
    title="Proxy & Geo Targeting"
    icon="globe"
    href="/going-to-production/proxy-geolocation"
  >
    Full list of proxy locations
  </Card>
  <Card
    title="Webhooks"
    icon="webhook"
    href="/going-to-production/webhooks"
  >
    Handle webhook authentication and retries
  </Card>
</CardGroup>
