---
title: discover
description: Free lexical search over up to 5 eligible endpoints, scored by relevance, evidence, availability, price and freshness.
---

<WorksIn />

Search up to 5 eligible endpoints by task, capability, category, provider, endpoint,
input-schema, output-schema, schema, or hybrid mode (`auto` infers one). Free and read-only. Each
result carries bounded relevance, evidence, availability, price and freshness components, plus
its category; unknown evidence stays distinct from zero and is never scored as bad. Never
returns a mock endpoint. For more than 5 results, or a whole category, use
[`search_catalog`](/mcp-tools/search-catalog) instead.

## Inputs

| Argument | Type | Required | Default | Limits | Meaning |
| --- | --- | --- | --- | --- | --- |
| `mode` | string | No | `"auto"` | `auto`, `task`, `capability`, `category`, `provider`, `endpoint`, `input-schema`, `output-schema`, `schema`, `hybrid` | How to interpret `query`/`taskDescription`. |
| `ranking` | string | No | - | `relevance`, `price`, `reliability`, `community`, `balanced` | Alias of `prefer`. |
| `prefer` | string | No | - | `cheapest`, `reliable`, `fastest`, `balanced` | Orders providers inside a job. |
| `query` | string | No | - | 1-500 chars | Search text. |
| `capability` | string | No | - | pattern `^[a-z][a-z0-9-]*(?:\.[a-z0-9-]+)+$` | A job id, for `capability` mode. |
| `category` | string | No | - | pattern `^[a-z][a-z0-9-]*$` | A category id, for `category` mode. |
| `taskDescription` | string | No | - | 1-500 chars | Task text, for `task` mode. |
| `provider` | string | No | - | min 1 char | Provider id or name. |
| `endpointId` | string | No | - | min 1 char | An exact endpoint id, for `endpoint` mode. |
| `maxPrice` | number | No | - | 0+ | Drop candidates priced above this. |
| `allowedProviders` | string[] | No | - | - | Only these providers. |
| `blockedProviders` | string[] | No | - | - | Never these providers. |
| `eligibilities` | string[] | No | - | `internal-validation`, `byok`, `partner-required`, `prohibited` | Restrict by eligibility. |
| `executionModes` | string[] | No | - | `sync`, `async` | Restrict by execution mode. |
| `minimumScore` | number | No | - | 0-1 | Applied before `resultLimit`. |
| `resultLimit` | integer | No | 5 | 1-5 | Candidates returned. |
| `detail` | string | No | `"full"` | `title` \| `full` | `title` returns rank, endpointId, provider, name, capability, category, estimatedPrice, priceBasis, costPerSuccessUsd, async, works and sourceCapability. |
| `includeUnavailable` | boolean | No | - | - | Include candidates with no route to run right now. |

`works` is `{rate, runs, p50Ms, thin}`: the measured success rate, decided runs, p50 latency, and
`thin` when under 5 runs. `credential` (full detail only) says whose key a run uses.
`sourceCapability` is the raw slug an endpoint was registered under; `capability` is the job it
does. No endpoint for the named job returns an empty `candidates` array with a
[`no_supply_for_job`](/errors/job-refusals#no_supply_for_job) warning in `meta.warnings`.

## Example call

```json
{
  "mode": "capability",
  "capability": "web.search",
  "resultLimit": 3
}
```

## Example answer

Abridged: a `full` candidate also carries `reliability`, `reason`, `match`, `ranking` and `score`.

```json
{
  "candidates": [
    {
      "rank": 1,
      "endpointId": "context-dev-web-search",
      "provider": "Context.dev",
      "name": "Context API / Web Search",
      "capability": "web.search",
      "category": "search",
      "estimatedPrice": 0.00025,
      "priceBasis": "perResult",
      "eligibility": "byok"
    },
    {
      "rank": 2,
      "endpointId": "octen-web-search",
      "provider": "Octen",
      "name": "Octen / web search",
      "capability": "web.search",
      "category": "search",
      "estimatedPrice": 0.006,
      "priceBasis": "perCall",
      "eligibility": "byok"
    }
  ],
  "meta": {
    "requestedMode": "capability",
    "resolvedMode": "capability",
    "ranking": "balanced",
    "resultCount": 2
  }
}
```

## Errors

Free and read-only; no `runs.execute` needed. A bad `mode` or enum value returns
[`validation_error`](/errors/rest-errors#validation_error) naming the field and the accepted values, for example
`Invalid option: expected one of "auto"|"task"|... at mode`. An argument `discover` does not
accept is refused with `acceptedArguments` listing what it does take. No supply for the named job
is not an error: `candidates` is empty and `meta.warnings` carries `no_supply_for_job: <jobId>`.

## REST and CLI

- REST: [`GET /v1/discover`](/reference/catalog/get-v1-discover)

<Related />
