Request Outcomes
Every request to the FourA API is classified into exactly one outcome, and so is every tunnel through the proxy port. The outcome is computed once, at the end of the call, and recorded against the credential that made it. Your dashboard, activity feed, and billing all read the same field.
Only success costs credits. Premium traffic is counted apart from credits and doesn't follow the outcome: see Billing Implications.
The Seven Outcomes
These are the seven a request can end in. A tunnel uses five of them: see Tunnels Use the Same Vocabulary below.
| Outcome | Layer | What it means |
|---|---|---|
success |
n/a | A valid response was delivered. Counts against your billable quota. |
application_error |
target | The target returned HTTP 200, but the body carried an error field, or the body is a bot-check page FourA recognises. |
application_fail |
target | The target returned a non-2xx that your validate rules did not accept, or no response at all, including a target host name that can't be resolved. |
client_error |
caller | Your request was rejected before it left FourA. Bad parameters, malformed proxy value, SSRF-guarded URL. |
rate_limit |
FourA | The request was refused before it ran: by one of your plan's limits (a 403 for an endpoint or parameter the plan doesn't include, a 429 for a spent allowance), or by the platform's shared RPM or concurrency allowance. |
service_error |
FourA | The engine answered with a server error, or its body wasn't valid JSON. |
service_fail |
FourA | FourA's own network failed: its engine didn't answer in time or the connection dropped, or you disconnected. |
The layer column tells you who's responsible:
- target outcomes are about the site you called. Your request reached FourA fine, and FourA reached the target fine. The target itself returned an error.
- caller outcomes mean your request never had a chance. Fix the request shape.
- FourA outcomes are on us. Retry, and check the status page if they persist.
A target site returning 403 is application_fail, not client_error. Your call was well-formed. The site just said no.
Success Is validate-Aware
Without validate, the API marks a request success only when the target returns HTTP 200.
With validate, success follows the rules you declared. If you tell the API that 200 and 403 are both acceptable for a given request, a 403 comes back as success. The body still reaches you unchanged.
curl -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "GET",
"url": "https://target.example/feed",
"validate": {
"status": { "accept": [200, 403] }
}
}'
In this call, a 403 response counts as success and bills as one request. A 500 response counts as application_fail and is not billed.
The same logic applies to validate.headers and validate.data. Any response the engine accepts against your rules comes back as success regardless of HTTP status.
One answer is never success, with or without validate: an HTTP 200 whose body is a bot-check page FourA recognises, such as a visual verification task or a page that only asks the browser to run JavaScript. That request is application_error and isn't billed. The body still reaches you unchanged, and the X-FourA-Check-Page header names the check page.
Billing Implications
| Outcome | Billable | Counts toward quota |
|---|---|---|
success |
Yes | Yes |
application_error |
No | No |
application_fail |
No | No |
client_error |
No | No |
rate_limit |
No | No |
service_error |
No | No |
service_fail |
No | No |
Only requests that delivered the data you asked for are billed. Failures on FourA's side, the target's side, or your own side are all free.
The table is about credits. Premium traffic is counted apart from them: a request that tried a premium exit counts the traffic that attempt carried, whatever the outcome, because the exit was used either way. An attempt that was still running when another exit answered is stopped at once, and the traffic it carried until then counts too.
Standard traffic doesn't follow the outcome either: on a plan with a bandwidth cap, every request's traffic counts toward it. A request refused by one of your own plan's limits counts no traffic.
Tunnels Use the Same Vocabulary
A tunnel through the proxy port ends in one of these outcomes too, so one set of labels covers both products. Only five of the seven can happen, because the two target outcomes need FourA to have seen the target's answer, and a tunnel's answer is your own encrypted traffic.
| Outcome | On a tunnel, this means |
|---|---|
success |
The tunnel opened and your tool got it. |
client_error |
FourA won't open that tunnel: a private or reserved address, or a port it doesn't serve. |
rate_limit |
One of your plan's numbers was reached (tunnels open at once, tunnel openings a minute, the standard traffic for the period, premium traffic you don't have), or the port itself was at its capacity or opening rate. |
service_error |
FourA had no exit for what you asked. Usually temporary. |
service_fail |
The target couldn't be reached through any exit FourA tried: DNS, timeout, connection refused. |
application_error |
Never occurs on a tunnel. |
application_fail |
Never occurs on a tunnel. |
A refusal also carries a short reason, and the dashboard shows it in your own terms rather than ours. An option FourA can't honour is answered 400 on the connection itself and writes no row, so it never shows up here at all.
| Reason on screen | What ran out |
|---|---|
| port not in plan | Your plan doesn't include the proxy port |
| tunnels at once | Every tunnel your plan allows at once was in use |
| openings per minute | Your plan's tunnel openings for this minute were used up |
| traffic used up | Your plan's traffic for this period is used up |
| premium not available | Premium traffic isn't available on your plan right now |
| port was full | The port itself was at capacity or opening rate. Try again in a moment. |
| port not served | FourA doesn't open tunnels to that port |
| private address | Private and reserved addresses can't be reached |
Nothing about a tunnel is billed in credits, because a tunnel has no request to charge one to. The port meters bytes instead. See How Your Plan Is Metered.
Reading Outcomes in the Dashboard
Every request your API key makes shows up on the Activity feed with its outcome label. The Metrics and Overview pages aggregate the same field for donut charts and timelines.
When you filter Activity by outcome, you can also focus on a single endpoint (Auto, Single, Proxy Finder, Browser) to see whether a class of failure is specific to one of them. Switch the page's Product to Proxy and the same outcome pills filter your tunnels.
Retry Heuristics
A first-pass retry policy keyed on outcomes:
| Outcome | Retry safe? | When |
|---|---|---|
success |
n/a | You have the response. |
application_error |
Sometimes | Read the target's error body. Some are transient, most aren't. If X-FourA-Check-Page is set, the site served a check page: send the URL to Auto, which treats a check page as a step to pass, not as the answer. |
application_fail |
Sometimes | If the target is rate-limiting you, slow down. If it's blocking you, switch to the Proxy or Browser endpoint. |
client_error |
No | The request will fail again the same way. Fix the input. |
rate_limit |
Depends | Honor the wait the response gives you: Retry-After, retry_after_seconds, or retryAfter. On plan_limit_browser_daily, stop until midnight UTC; on plan_limit_credits or plan_limit_bandwidth, stop until resets_at; on plan_limit_feature or plan_limit_premium, change the request. |
service_error |
Yes | Short exponential backoff. |
service_fail |
Yes | Same as service_error. |
Related
- API Errors: HTTP-level error responses
- Proxy Port: The status codes a tunnel's refusal arrives as
- Rate Limits: What triggers
rate_limit, and the two shapes it comes back in - Metrics: Where you see outcomes broken down
- Activity Log: Per-request outcome history