Request Outcomes
Every request to the FourA API is classified into exactly one outcome. The outcome is computed once at request time and recorded against your API key. Your dashboard, activity feed, and billing all read the same field.
Only success is billable.
The Seven Outcomes
| 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. |
application_fail |
target | The target returned a non-2xx that your validate rules did not accept, or no response at all. |
client_error |
caller | Your request was rejected before it left FourA. Bad parameters, malformed proxy value, SSRF-guarded URL. |
rate_limit |
FourA | Your RPM or concurrency cap was hit. |
service_error |
FourA | The backend returned a 5xx, or its body wasn't valid JSON. |
service_fail |
FourA | Network failure: timeout, connection refused, DNS error, client disconnect. |
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.
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.
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 product (Single, Proxy, Browser) to see whether a class of failure is specific to one endpoint.
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. |
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 |
Yes | Honor retryAfter from the response body. |
service_error |
Yes | Short exponential backoff. |
service_fail |
Yes | Same as service_error. |
Related
- API Errors: HTTP-level error responses
- Rate Limits: What triggers
rate_limit - Metrics: Where you see outcomes broken down
- Activity Log: Per-request outcome history