# Data provider fallback: automatic fallback for data APIs

How data provider fallback works when a data API returns nothing or fails: the order, the cost cap, what stops a route and who pays for a miss.

## Summary

Automatic provider fallback means that when a data API returns nothing or fails, the call moves to the next provider that does the same job, without your agent writing the retry logic. This is data provider fallback, not LLM routing: tools like LiteLLM or OpenRouter switch language models, while this switches the API that answers a lookup. For a lookup such as an email finder this is a plain loop: try one, check the answer, try the next, stop at a hit.

The loop is easy to describe and easy to get wrong in the details. Who decides the order? What counts as a miss? What stops a route before it burns your balance? This post answers those for looot, where a run with `fallback` on is a live route. looot publishes this post, and we describe our own system, so test the claims on your own account.

## What triggers a fallback?

A miss or an error on the first provider. A miss is an empty answer: `found: false`, a null body, an empty list, or a profile with no key field. An error is a provider failure or timeout. Either one moves the route to the next candidate of the same job.

The judgment uses the job's data, not the provider's wrapper. A provider can answer with HTTP 200 and an empty body, and looot still counts that as a miss. This matters because many finder APIs return success with no email in it.

Some things do not trigger fallback. A caller fault such as "not a valid address" stops the route, because the next provider would fail the same way. A fault where an input is missing only skips that candidate, since another provider may accept the fields you do have.

## How does the route pick the order?

The endpoint you named runs first. The candidates after it are the other catalog endpoints of the same job, ordered by your `prefer` setting: cheapest, reliable, fastest or balanced. Candidates that cannot run are left out and listed with a reason. That covers endpoints that reject your input, endpoints without a credential and providers whose own account ran out of credit.

Only lookups fall through. An action that changes data, such as sending a message, runs once on the endpoint you named. Fallback never repeats a write.

After a guessed answer, the rest of the walk tries the endpoints that do not bill a miss first. That keeps the cost of a long route down.

## What stops it?

Four limits, all set per run.

| Limit | Default | What it does |
|---|---|---|
| `maxAttempts` | 3, range 1 to 10 | Caps the number of providers tried |
| `maxCostUsd` | none unless you set it | Skips any candidate that would pass the cap |
| `stopAtFirstMiss` | off | Ends the route on the first miss |
| Third error | fixed | Stops after the first failure plus two fallbacks |

The route reserves one hold at the start, the sum of the first attempts' prices, lowered by your cap. Only attempts that ran are charged, and the rest of the hold is released. A route that runs out of balance mid-walk skips the candidates it cannot afford.

## Who pays for a miss?

It depends on the provider, and the run tells you. Each attempt in the route record carries a `billed` flag, true when that provider billed it. A miss is free unless the provider itself bills for one.

This is not theoretical. The catalog entry for the Hunter email finder says a search that finds no email is charged the same as one that does, and its saved runs include misses billed at full price. Hunter's own [pricing page](https://hunter.io/pricing), read on 2026-10-13, says Email Finder counts 1 credit per email found and nothing on a miss. The two billing models differ, and the catalog note is the one that applies to a call through looot.

That is why the cheapest provider is not always the cheapest per found email. See [what 1000 lookups cost](https://looot.ai/blog/what-1000-lookups-cost) for the arithmetic.

Price per call, email finders. Prices read on 2026-10-13 from the live looot catalog. They change when a provider changes its price.

| Option | Cheapest provider | Price per call |
|---|---|---|
| Find a work email | Tomba | $0.0089 per call |
| Verify an email | Icypeas | $0.0019 per call |

## Fallback by hand, and why it is worse

You can write the loop yourself. You pick the providers, hold a key for each, handle each provider's error shape and decide what a miss means. Every provider says "no result" differently, so the miss check is the part that rots.

A gateway moves that logic into one place, and the [claude code email finder](https://looot.ai/blog/claude-code-email-finder-without-signups) shows it in a real setup. The agent sends one request with `fallback` set and reads one record back. [Waterfall enrichment explained](https://looot.ai/blog/waterfall-enrichment-explained) covers the same pattern from the data side.

## What it does not do

- It does not retry on a timer. Scheduled runs are not available yet.
- It does not guarantee a hit. If every provider misses, the run ends as a miss and says so.
- It does not make providers return the same fields. Check the fields you need on each endpoint.
- It does not fall through on actions that change data.
- We did not run a live route for this post. The behavior comes from the looot skill file and the routing notes in our repository, last checked 2026-10-13.

## Try it: read a route

Last checked 2026-10-13. Author: the looot team.

## Questions

### What is data provider fallback?

It is a loop that tries the next provider of the same job when the first returns nothing or errors. The agent sends one request, and the gateway walks the providers and stops at a hit or a limit.

### What happens when a data API fails?

With fallback on, looot moves to the next provider of the same job. After the first failure and two fallbacks, a third error stops the route.

### How do I cap the cost of a fallback?

Set `maxCostUsd` on the run, and `maxAttempts` for the number of providers. The route holds one reserve and skips any provider that would pass the cap.

### Does a miss cost money?

Only if that provider bills for a miss. Each attempt carries a `billed` flag so you can see which ones did.

### Does fallback work for every endpoint?

No. Only lookups fall through. Actions that change data run once on the endpoint you named.

### Is this the same as LiteLLM or OpenRouter fallback?

No. LiteLLM and OpenRouter switch between language models when one fails. Data provider fallback switches between data APIs that do the same lookup, such as two email finders, and judges a miss by the data that came back. See [the LLM router post](/blog/llm-router-for-agents) for the model side.

### Is fallback on by default?

No, you turn it on per run with `fallback`. A kill switch can turn every route off, and then only the named endpoint runs.

### Do I need my own keys for each provider?

No. Most endpoints run on looot's keys from one prepaid balance. You can use your own provider key where you have one.

## For agents

### Run a lookup with fallback

```text
Use looot to find a work email with fallback.
1. Set up https://looot.ai/skill.md.
2. Run job people.email.find with fallback true, maxAttempts 3 and maxCostUsd 0.10, for Jane Doe at example.com.
3. Print the outcome, then every attempt in the route with its provider, whether it billed and what it cost.
```
