---
title: find-and-run skill
description: How the looot plugin's find-and-run skill searches by job, runs with fallback, and reads the outcome and receipt.
sidebar:
  label: Find and run
---

`find-and-run` is the plugin's core skill. It loads automatically whenever a task needs external
or live data: SEO and SERP data, keyword volume, backlinks, people and company enrichment, email
finding and verification, social profiles, or web scraping.

## What it does

The skill uses [`search`](/mcp-tools/search), [`inspect`](/mcp-tools/inspect), [`run`](/mcp-tools/run), [`runs_get`](/mcp-tools/runs-get), [`runs_list`](/mcp-tools/runs-list), [`runs_evidence`](/mcp-tools/runs-evidence) and [`balance`](/mcp-tools/balance).
Searching and inspecting are free. [`discover_smart`](/mcp-tools/discover-smart) costs a small fee, so the skill asks before
using it.

1. **Search by the job, not the vendor.** It calls `search` with a plain-words query, for example
   "find a work email from a name and domain". Each row has an `endpointId`, `provider`, the job
   id in `capability`, `estimatedPrice`, `priceBasis`, and `costPerSuccessUsd` (price divided by
   success rate). `works` holds `rate`, `runs` and `p50Ms`; `thin: true` means fewer than 5 runs
   back the rate. `access` is `runs_now`, `needs_your_account` or `coming_soon`.
2. **Read [`jobInputs`](/concepts/job-inputs).** The search answer's top-level `jobInputs` lists each job's inputs with
   coverage, so the agent knows which field name gets accepted by the most providers.
3. **Run the job.** It sends `endpointId: "job:<job id>"` with the shared input names from
   `jobInputs`, plus a new [`idempotencyKey`](/concepts/idempotency) for every run and, usually, a [`fallback`](/concepts/fallback) object
   (`maxAttempts`, [`maxCostUsd`](/money/cost-cap), `prefer`). looot tries providers of that job in order, free ones
   first, inside one hold.
4. **Read the answer.** It checks `status` and `error` first, since a call can succeed and still
   carry `status: "failed"`. Then it reads [`outcome`](/concepts/outcomes) (`hit`, `weak`, `miss`, `error`, `rejected`,
   `skipped` or `pending`), `normalized.fields` when the job has one, `servedEndpointId` and
   [`servedProviderId`](/concepts/served-provider) (who actually answered, which can differ from `endpointId` after a
   fallback), `requestedJob` for what was asked, and `route` for the fallback trail
   (`servedBy`, `outcome`, `chargedUsd`, `attempts`, `skipped`, `summary`).
5. **Get the receipt.** `runs_evidence` for every attempt with its cost, or `runs_list` for
   history.

If `search` comes back empty with a [`no_supply_for_job`](/errors/job-refusals#no_supply_for_job) warning, the skill tells the user no
endpoint does that job, and can call [`capability_request`](/mcp-tools/capability-request) to ask looot to add one.

## Worked example

**User:** "Find the work email of Jane Doe at example.com."

The agent searches, then runs the job with fallback:

```json
{"tool": "search", "input": {"query": "find a work email from a name and domain"}}
```

```json
{
  "tool": "run",
  "input": {
    "endpointId": "job:people.email.find",
    "input": {"first_name": "Jane", "last_name": "Doe", "domain": "example.com"},
    "idempotencyKey": "jane-doe-example-find-01",
    "fallback": {"maxAttempts": 3, "maxCostUsd": 0.1, "prefer": "cheapest"}
  }
}
```

The run comes back completed, with `outcome: "hit"`, `normalized.fields.email` set,
`servedProviderId` naming the provider that answered, and `route.summary` reading something like
"hunter: found ($0.0245). Charged $0.0245."

**Agent's answer:** "Found jane.doe@example.com, served by [provider from `servedProviderId`].
Charged [`actualCost`]. Verify it before sending anything important; see the money and
troubleshooting skills for what a `weak` or `guessed` result means."

See [money](/plugin/skills/money) for cost rules, [recipes](/plugin/skills/recipes) for ready-made
flows, and [troubleshooting](/plugin/skills/troubleshooting) for error codes.

<Related />
