# Web search

Search the web (or a bound search connection) once per record.

## When to use it

Search once for each input record. Choose a stored search connection or the configured search route, a query or query template, language, and date window. Provider failures can appear on individual records while the step completes. Check those records before treating the absence of results as definitive.

## Add and configure

1. Add **Web search** from the workflow step picker.
2. Give the step a recognisable name and connect its required inputs.
3. Set the options below. Nested names identify fields within an object or a list item.
4. Validate the recipe, inspect the test result, then run it on the intended data.

The step identifier used in the editor’s code view is `web_search`.

## Settings

| Setting | Accepted value | Required | Default | What it controls |
| --- | --- | --- | --- | --- |
| Catalog Slug (`catalog_slug`) | string; pattern `^[a-z0-9][a-z0-9._-]{0,199}$` or null | No | null | Catalog slug the bound connection is expected to have (`platform_search`, `reddit`, `huggingface`, `hackernews`). Set together with `connection_id` or `connection_id_field`. The provider is chosen by the slug the connection actually resolves to. |
| Connection Id (`connection_id`) | string; format uuid or null | No | null | Search through this connection (a Platform Search, Reddit, Hugging Face or Hacker News connection). Requires `catalog_slug`; exclusive with `connection_id_field`. |
| Connection Id Field (`connection_id_field`) | string; pattern `^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$` or null | No | null | Dotted path into each input record holding the connection id to search through (e.g. `connectors.platform_search.connection_id` on an App config record). Requires `catalog_slug`; exclusive with `connection_id`. A record without an id degrades to a per-record error — it never falls back to the unbound provider. |
| Language (`language`) | string; pattern `^[a-z]{2}(-[A-Z]{2})?$` or string; pattern `^\$\{[a-zA-Z_][a-zA-Z0-9_.]*\}$` or null | No | null | Result language as `xx` or `xx-YY` (e.g. `en`, `en-US`), or a `${field}` placeholder rendered per record (e.g. `${params.language}`). |
| Max Results (`max_results`) | integer; minimum 1; maximum 10 | No | 5 | Maximum results per record (1-10). |
| Query (`query`) | string or null | No | null | Literal search query, applied to every input record. Provide this OR `query_template`. |
| Query Template (`query_template`) | string or null | No | null | Per-record query template. `${field}` placeholders are replaced with values from the record (dotted paths supported, e.g. `${company.name}`). Takes precedence over `query` when both are set. |
| Time Range (`time_range`) | "day" / "week" / "month" / "year" or string; pattern `^\$\{[a-zA-Z_][a-zA-Z0-9_.]*\}$` or null | No | null | Only results from the last day / week / month / year, or a `${field}` placeholder rendered per record (e.g. `${params.time_range}`). |
| Topic (`topic`) | "general" / "news" / "finance" | No | "general" | Search topic — steers the provider's ranking. |

## Inputs and outputs

| Direction | Port | Content | Required | Multiple records |
| --- | --- | --- | --- | --- |
| Inputs | `in` | records | Yes | Yes |
| Outputs | `out` | records | Yes | Yes |

## Effects, testing, and recovery

Reads an external source.

The declared preview behaviour is to execute this step. Reads, processing, or model usage can therefore be real. Read [dry runs](/docs/workflows/dry-runs) before using a preview with live connections.

No duplicate-prevention key is declared for this step. Do not assume that manually repeating the step is free of repeated effects.

When step caching is available, the declared cache lifetime is 3600 seconds. Eligible successful results can be reused; bypass caching when the task requires a fresh read.

## Example: Latest news about each record's company

Step settings:

```json
{
  "max_results": 5,
  "query_template": "${company} latest news",
  "time_range": "week",
  "topic": "news"
}
```

## Example: One literal query through a bound Platform Search connection

Step settings:

```json
{
  "catalog_slug": "platform_search",
  "connection_id": "77777777-7777-4777-8777-777777777777",
  "language": "en",
  "query": "workflow engines comparison"
}
```

## Check the result

Inspect the selected run’s status, counts, errors, and output records. An empty collection can be a valid result, and a completed step can contain per-record failures where the step defines that behaviour. Check the next step’s expected record shape before publishing or delivering the result.
