---
title: search
description: Free catalog search. Describe a job in plain words or pass filters and get back endpoints to inspect and run.
---

<WorksIn />

Find endpoints for a job. Describe the task in plain words ("verify an email", "backlinks for a
domain"), or pass `filters` alone; `query` is optional once a filter is set. Free, read-only, and
needs no scope beyond a valid token. Use it as the first step of a run: pick an `endpointId` from
the rows it returns, then call [`inspect`](/mcp-tools/inspect) on it.

## Inputs

| Argument | Type | Required | Default | Limits | Meaning |
| --- | --- | --- | --- | --- | --- |
| `query` | string | No | - | max 500 chars | Plain-English description of the job. |
| `limit` | integer | No | 10 | 1-200 | Rows per page. |
| `offset` | integer | No | 0 | 0+ | Row offset for paging past `limit`. |
| `detail` | string | No | - | `title` \| `full` | `full` adds summary, stats, facts and fees; `title` is the cheap first pass. |
| `prefer` | string | No | `"balanced"` | `cheapest` \| `reliable` \| `fastest` \| `balanced` | Orders providers inside a job. |
| `filters.category` | string | No | - | - | Restrict to a catalog category. |
| `filters.platform` | string | No | - | - | Restrict to a platform. |
| `filters.provider` | string | No | - | - | Restrict to a provider. |
| `filters.capability` | string | No | - | - | A job id from [`catalog_overview`](/mcp-tools/catalog-overview). |
| `filters.keyless` | boolean | No | - | - | Only endpoints that need no key at all. |
| `filters.verified` | boolean | No | - | - | Only endpoints verified against a saved provider answer. |
| `filters.mock` | boolean | No | - | - | Include fixture/demo endpoints. |
| `filters.maxPriceMicros` | number | No | - | 0+ | Drop rows priced above this, in micros of a dollar. |
| `filters.hidden` | boolean | No | - | - | Include hidden endpoints. |
| `filters.includeUnavailable` | boolean | No | - | - | Include endpoints with no route to run right now. |

Every row has `endpointId`, `provider`, `capability` (the job id), `estimatedPrice`,
`priceBasis`, `costPerSuccessUsd` (price divided by `works.rate`; a thin row fills missing runs
at the job average), `works` `{rate, runs, p50Ms, thin}`, `access`, `async` and `credential`.
When no endpoint does the job, `items` is empty and `warnings` names it. When
`filters.maxPriceMicros` removes every match, `priceHint` names the cheapest one instead.

## Example call

```json
{
  "query": "verify an email address",
  "limit": 5,
  "prefer": "cheapest"
}
```

## Example answer

Abridged: full rows also carry `works`, `access`, `async` and `credential`.

```json
{
  "query": "verify an email address",
  "total": 7,
  "offset": 0,
  "nextOffset": 5,
  "items": [
    {
      "endpointId": "icypeas-email-verify",
      "provider": "Icypeas",
      "capability": "people.email.verify",
      "estimatedPrice": 0.0019,
      "priceBasis": "perCall",
      "costPerSuccessUsd": 0.0021
    },
    {
      "endpointId": "zerobounce-guessformat",
      "provider": "ZeroBounce",
      "capability": "people.email.verify",
      "estimatedPrice": 0.01,
      "priceBasis": "perCall",
      "costPerSuccessUsd": 0.0104
    }
  ]
}
```

## Errors

`search` is free and read-only; it does not spend credit or need `runs.execute`. A bad argument
returns [`validation_error`](/errors/rest-errors#validation_error) naming the field. No matching job returns an empty `items` array with
a `warnings` entry, not an error, so check `items.length` before assuming a job exists.

## REST and CLI

- REST: [`GET /v1/catalog/search`](/reference/catalog/get-v1-catalog-search)
- CLI: `looot search "<query>"`

<Related />
