---
name: firecrawl-build-search
description: Integrate Firecrawl `/search` into product code and agent workflows. Use when an app needs discovery before extraction, when the feature starts with a query instead of a URL, or when the system should search the web and optionally hydrate result content.
license: ISC
metadata:
  author: firecrawl
  version: "0.1.0"
  homepage: https://www.firecrawl.dev
  source: https://github.com/firecrawl/skills
inputs:
  - name: FIRECRAWL_API_KEY
    description: Firecrawl API key for hosted Firecrawl requests.
    required: true
  - name: FIRECRAWL_API_URL
    description: Optional base URL for self-hosted Firecrawl deployments.
    required: false
---

# Firecrawl Build Search

Use this when the application starts with a query, not a URL.

## Onboarding — start here

### 1. What this does

Turns a query into a ranked shortlist of real URLs, optionally with their
content hydrated in the same call. It is the discovery step that runs *before*
extraction: query → URLs → (`/scrape` or `/interact`) → data.

### 2. Firecrawl or Exa? — the routing rule

This is the decision people get wrong most often, and it costs both money and
result quality. **The split is about how well-specified the target is:**

| Situation | Tool | Why |
| --- | --- | --- |
| You know the URL | **Firecrawl** `/scrape` | Precise and cheap. No search needed at all. |
| You know the domain, want many pages | **Firecrawl** `crawl` / `map` | Enumerates and reads a site you can already name. |
| You know the site *type* — "pricing pages of these 40 companies", "this docs site" | **Firecrawl** `/search` (this skill) | Keyword-shaped, target well-specified. |
| You do **not** know where the answer lives | **Exa** | Semantic discovery. Finds the source before anything can read it. |
| "Who else does X?", obscure topics, look-alike companies | **Exa** | Firecrawl will return the obvious pages; Exa finds the non-obvious ones. |

Said plainly: **Firecrawl is superior once you know the website. Exa excels at
finding hard-to-find websites.** Firecrawl is precise and cheap on a known
target; ask it to go hunting for an obscure source and it returns the popular
answer, not the right one.

The two compose, and that is usually the best pipeline: **Exa to find the
sources, Firecrawl to read them thoroughly.** Reach for Exa first only when the
target genuinely has to be located. If you can already name the site, skipping
Exa saves a step and a charge.

See `exa-search` for the other half of this split.

### 3. Which Firecrawl skill?

| You have | You want | Skill |
| --- | --- | --- |
| A query | Find the pages | **`firecrawl-build-search`** (this one) |
| A URL | Read that page | `firecrawl-build-scrape` |
| A URL + the page needs clicks, forms, pagination, login | Drive the page | `firecrawl-build-interact` |
| Nothing set up yet | Key + SDK into the project | `firecrawl-build-onboarding` |
| A programming question | Issues, PRs, real docs | `firecrawl-developer-index` |
| A research question | Papers | `firecrawl-research-index` |

### 4. What it can't do

It finds and ranks pages — it is not a crawler (a whole site → `crawl`/`map`),
not a browser (clicks, forms, auth → `firecrawl-build-interact`), and not an
answer engine: it returns sources, not a synthesized conclusion. It also will
not reliably surface a source that is semantically related but keyword-distant
from your query — that is the Exa case above.

### 5. Setup

```bash
echo 'FIRECRAWL_API_KEY=your_key_here' >> local.env
```

```bash
set -a && . ./local.env && set +a
```

Self-hosted deployments set `FIRECRAWL_API_URL` as well. Never hardcode the key
in a script. If nothing is set up yet, run `firecrawl-build-onboarding` first —
it handles the auth flow and SDK install.

### 6. Verify it works

```bash
curl -sS -X POST "https://api.firecrawl.dev/v2/search" -H "Content-Type: application/json" -H "Authorization: Bearer $FIRECRAWL_API_KEY" -d '{"query":"firecrawl docs","limit":3}'
```

Expect JSON with a result list. A `401` means the key is wrong or not loaded;
an empty `$FIRECRAWL_API_KEY` means step 5 did not take.

### 7. Cost

Firecrawl bills per request, and hydrating result content costs more than
returning URLs alone. Prefer selective follow-up extraction over broad
hydration. Before running search in a loop over many rows, estimate the call
count and tell the user what the run costs.

### 8. Read next

[Default Recommendations](#default-recommendations) for the shape of a good
integration, [Escalation Rules](#escalation-rules) for when to hand off, and
your language's page under [Docs (Source of
Truth)](#docs-source-of-truth) before writing integration code.

## Use This When

- the user asks a question and the product must discover sources first
- the feature needs current web results
- you want to turn a search query into a shortlist of pages for later scraping

## Default Recommendations

- Use `/search` first when URL discovery is part of the product behavior.
- Keep search and extraction conceptually separate unless scraping search results is clearly required.
- Prefer selective follow-up extraction over broad hydration when cost or latency matters.

## Common Product Patterns

- answer generation with cited sources
- company, competitor, or topic discovery
- research workflows that produce a shortlist before deeper extraction
- query-to-URL pipelines for later `/scrape` or `/interact`

## Escalation Rules

- If you already have the URL, use [firecrawl-build-scrape](../firecrawl-build-scrape/SKILL.md).
- If the result page then requires clicks or form interaction, escalate to [firecrawl-build-interact](../firecrawl-build-interact/SKILL.md).

## Implementation Notes

- Treat `/search` as discovery, ranking, and source selection.
- Be explicit about whether the product needs snippets, URLs, or full result content.
- Keep the query contract stable so downstream scraping logic stays predictable.

## Docs (Source of Truth)

Read the source-of-truth page for your project language before writing integration code:

- **Node / TypeScript**: [docs.firecrawl.dev/agent-source-of-truth/node](https://docs.firecrawl.dev/agent-source-of-truth/node)
- **Python**: [docs.firecrawl.dev/agent-source-of-truth/python](https://docs.firecrawl.dev/agent-source-of-truth/python)
- **Rust**: [docs.firecrawl.dev/agent-source-of-truth/rust](https://docs.firecrawl.dev/agent-source-of-truth/rust)
- **Java**: [docs.firecrawl.dev/agent-source-of-truth/java](https://docs.firecrawl.dev/agent-source-of-truth/java)
- **Elixir**: [docs.firecrawl.dev/agent-source-of-truth/elixir](https://docs.firecrawl.dev/agent-source-of-truth/elixir)
- **cURL / REST**: [docs.firecrawl.dev/agent-source-of-truth/curl](https://docs.firecrawl.dev/agent-source-of-truth/curl)

## See Also

- [firecrawl-build](../firecrawl-build/SKILL.md)
- [firecrawl-build-scrape](../firecrawl-build-scrape/SKILL.md)
- [firecrawl-build-interact](../firecrawl-build-interact/SKILL.md)
