> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paywithlocus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Capability routing

> Search, research, or compare flights across providers through one metered Locus Pro request.

Capability routing lets you ask for an outcome instead of selecting a provider. The system-managed `router` and `locus-travel` providers plan eligible calls, use the same billing and refund path as direct calls, and return normalized results with durable receipts.

## Choose an endpoint

| Slug                         | Use it for                                                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `router/web-search`          | Parallel search, URL canonicalization, deduplication, rank fusion, images, and per-result source provenance         |
| `router/web-research`        | Outcome-oriented research that can choose an exact structured catalog source and fall back to multi-provider search |
| `locus-travel/flight-search` | Normalized flight comparison with provenance, confidence, and bookability                                           |

All three endpoints are variable-cost. You pay the exact sum of successful underlying provider calls. A failed provider call follows the normal refund path, and an idempotent replay creates no new charge.

## Configure the eligible pool

In an enterprise workspace with capability routing available, open **Agent tools**, then **Multi-Provider Web Search**, to choose the default mode, maximum results, balanced-mode provider limit, image behavior, and provider allowlist. The allowlist is a hard boundary. A provider must also have a configured, enabled catalog access path before the router can use it. In a personal account where routing is available, the router appears enabled and system-managed. You cannot toggle it or manage the enterprise provider pool and settings APIs.

| Mode            | Breadth                                          |
| --------------- | ------------------------------------------------ |
| `fast`          | Up to two eligible engines                       |
| `balanced`      | Up to `maxProviders` eligible engines; default 4 |
| `comprehensive` | Every eligible engine                            |

Tenant secret keys can read the same configuration with `GET /api/credits/router/settings`, change it with `PUT /api/credits/router/settings`, enable an eligible provider with `POST /api/credits/router/providers/{providerId}/enable`, and preview the saved plan with `POST /api/credits/router/preview`. Reads require `tenant:read`; changes require `catalog:write`.

## Preview without calling providers

The execution routes also expose a free preview at the same path plus `/preview`:

```bash theme={null}
curl -X POST "$LOCUS_API/api/wrapped/credits/router/web-search/preview" \
  -H "Authorization: Bearer $LOCUS_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "latest agent payment infrastructure",
    "mode": "balanced",
    "maxProviders": 4,
    "maxResults": 10
  }'
```

Preview returns the planned distinct providers and the current tenant-aware estimate. It makes no provider calls and burns no credits. Provider selection can change between preview and execution as availability and price change; use `maxCredits` as the execution-time hard boundary.

## Run a routed search

```bash theme={null}
curl -X POST "$LOCUS_API/api/wrapped/credits/router/web-search" \
  -H "Authorization: Bearer $LOCUS_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "latest agent payment infrastructure",
    "mode": "balanced",
    "maxResults": 10,
    "includeImages": true,
    "maxCredits": "500"
  }'
```

The request accepts these controls:

| Field                              | Meaning                                                                                                                                       |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`                            | Required search or research request                                                                                                           |
| `mode`                             | `fast`, `balanced`, or `comprehensive`                                                                                                        |
| `maxResults`                       | 1–20 normalized results; default 10                                                                                                           |
| `maxProviders`                     | Distinct-provider ceiling in balanced mode; default 4                                                                                         |
| `topic`                            | `general` or `news`                                                                                                                           |
| `recencyDays`                      | Restrict results to the last 1–365 days                                                                                                       |
| `country`                          | Two-letter country code                                                                                                                       |
| `includeDomains`, `excludeDomains` | Domain filters                                                                                                                                |
| `includeImages`                    | Merge normalized image results when supported                                                                                                 |
| `providers`                        | Request-level allowlist that narrows the saved tenant pool                                                                                    |
| `maxCredits`                       | Exact decimal-string hard ceiling for the aggregate estimated charge                                                                          |
| `strategy`                         | Legacy v1 selector: `balanced`, `cost`, `quality`, or `speed`; accepted for compatibility, but new clients should use `mode`                  |
| `rails`                            | Legacy v1 list containing `api-key`, `mpp`, or `x402`; accepted but ignored because Locus now chooses each provider's payment path internally |
| `externalUserId`                   | Charge and attribute the request to one end user; the `X-Locus-End-User` header wins if both are present                                      |
| `attribution`                      | Your ledger metadata object                                                                                                                   |

If the tenant-aware estimate exceeds `maxCredits`, Locus rejects the plan before dispatch and charges nothing.

## Read the result and receipt

`router/web-search` returns normalized `results`, optional `images`, each provider's outcome, and aggregate billing:

```json theme={null}
{
  "object": "locus.web_search",
  "capability": "web.search",
  "mode": "balanced",
  "partial": false,
  "providers": [
    { "providerId": "tavily", "status": "succeeded", "chargedCredits": "90" }
  ],
  "results": [
    {
      "title": "Example",
      "url": "https://example.com",
      "sourceCount": 1,
      "sources": [{ "providerId": "tavily", "providerName": "Tavily", "rank": 1 }]
    }
  ],
  "billing": {
    "chargedCredits": "90",
    "successfulProviders": 1,
    "attemptedProviders": 1
  }
}
```

`partial: true` means at least one planned provider failed while others produced a useful result. Treat the returned evidence and `billing.chargedCredits` as authoritative; do not reconstruct the charge from a preview.

Agents can discover all three routes through `search_apis`, the server SDK's `searchTools()`, or the catalog. The ordinary Agent Connection tool allowlist and per-call/per-loop limits still apply.

## Compare flights with Locus Travel

Enable `locus-travel/flight-search`, then preview the current plan without calling providers:

```bash theme={null}
curl -X POST "$LOCUS_API/api/wrapped/credits/locus-travel/flight-search/preview" \
  -H "Authorization: Bearer $LOCUS_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "origin": "SFO",
    "destination": "JFK",
    "departureDate": "2026-10-15",
    "adults": 1,
    "cabinClass": "economy",
    "maxStops": 1,
    "maxResults": 5,
    "maxCredits": "500"
  }'
```

Execute the same body at `POST /api/wrapped/credits/locus-travel/flight-search` with an idempotency key. `origin`, `destination`, and `departureDate` are required. Optional controls cover return date, passengers, cabin, currency, optimization, airline and airport preferences, stops, schedule, price, result count, provider count, and `maxCredits`. A `202` response means the search is still running: retry the same request with the same `Idempotency-Key` to collect the result — do not abandon the flight or start a new key.

The result includes normalized itineraries, provider outcomes, warnings, provenance, confidence, bookability, exact billing, `partial`, and a durable `runId`. A partial result can still be useful; inspect its warnings and provider outcomes.

Submit feedback to the `feedback` route returned with the result. It keeps the route paired with the correct `runId`.
