Fallback strategies
Some sites refuse a request because of how it looks, not because they're down: a bot User-Agent or fingerprint, a missing header, the wrong cookies. Retrying the same request won't help. A fallback is a different way to ask, tried only if the main request fails.
{
"target_url": "https://example.com",
"fields": ["h1"],
"options": {
"fallback": [
{ "headers": { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" } }
]
}
}See it work
The demo page below answers 403 Forbidden to anything that doesn't look like a browser.
Requests look like a browser by default, so to see a refusal, the main request below drops its fingerprint (fingerprint: false sends the API's own User-Agent) and turns off the automatic escalation to a browser, which would otherwise get the page by itself.
Without fallback, the request is refused:
Actions
Data
With a fallback that looks like a browser again, the main request is refused, then the fallback gets the page. meta.strategy tells you which one worked:
Actions
Data
{
"status": 200,
"data": ["Welcome, browser"],
"meta": { "attempts": 2, "strategy": 1, … }
}How it works
- The API sends the main request, with its retries if you set any.
- If it still can't get the page, it tries
fallback[0], with that strategy's own retries. - Then
fallback[1], and so on, up to 3 strategies. The first one that gets the page wins.
A fallback is used when a strategy ends with an HTTP error (any non-2xx status, 403 and 404 included), a network error, a timeout, too many redirects, no proxy available, a browser that can't start, or a failed action. It isn't used for errors another strategy can't fix: an invalid URL or selector, a redirect to another domain, a page over the size limit.
What a strategy contains
A strategy accepts the same options as the main request, except cache_ttl: method, headers, cookies, body, timeout, follow_redirects, max_redirects, proxy, fingerprint, browser, actions, retry, retry_on and backoff (see Custom requests, Timeouts & redirects and Automatic retries).
It starts from the main options and changes only what it sets:
headersandcookiesare merged: set just aUser-Agentand every other main header is still sent.backoffis merged too.- Everything else replaces the main value: a strategy with
"retry": 3retries 3 times even if the main request doesn't retry.
"options": {
"headers": { "Accept-Language": "fr" },
"retry": 1,
"fallback": [
{ "headers": { "User-Agent": "Mozilla/5.0" } },
{
"headers": { "User-Agent": "Mozilla/5.0" },
"cookies": { "consent": "yes" },
"retry": 3
}
]
}Here the first fallback sends Accept-Language: fr with a browser User-Agent and retries once. The second one adds a cookie and retries up to 3 times.
Drop what you don't want to inherit
Set an option to false in a strategy to stop inheriting it:
"options": {
"method": "POST",
"body": "q=shoes",
"headers": { "X-Api-Version": "2" },
"proxy": true,
"fallback": [
{ "method": "GET", "body": false, "headers": false, "proxy": false }
]
}The fallback sends a plain GET: no body, none of the main headers, no proxy. "cookies": false and "retry": false work the same way.
A strategy can't contain its own fallback.
In the response
| Property | Description |
|---|---|
meta.strategy | Which strategy got the page: 0 for the main request, 1 for fallback[0], 2 for fallback[1]… |
meta.attempts | Requests made across all strategies, retries included |
When every strategy fails, the error has the same two properties, for the last strategy tried:
{
"target_url": "https://example.com",
"error": {
"code": "HTTP_ERROR",
"message": "HTTP 403 for https://example.com",
"status": 403,
"attempts": 3,
"strategy": 2
}
}