Référence des endpoints API
Une référence pour tous les endpoints de l'API FourA avec les paramètres de request et les formats de response.
Base URL
https://eu.api.foura.ai/api
Authentification
Chaque request nécessite votre clé API dans le header X-API-Key :
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://example.com"}'
Créez et gérez vos clés API dans le Dashboard. Les clés utilisent le préfixe pk_live_.
Response Headers
Les réponses de /api/* comportent deux headers de corrélation :
| Header | Value | Description |
|---|---|---|
X-FourA-Request-Id |
UUID | ID unique attribué à la requête. Renvoyé sur chaque réponse, y compris les 4xx et 5xx, sauf si le corps ne peut pas être lu par FourA : 400 Invalid JSON in request body et 413 sont refusés avant qu'un ID ne soit attribué. Enregistrez-le de votre côté. |
X-FourA-Credits |
integer | Crédits dépensés pour cette requête. Renvoyé sur chaque réponse ayant atteint un moteur, qu'elle soit un succès ou un échec (le traitement a eu lieu dans les deux cas). Un appel refusé par FourA avant qu'un moteur ne l'exécute (clé manquante ou invalide, limite de forfait ou de plateforme, cible ou ID de proxy refusé) n'en comporte aucun. Consultez Request Outcomes pour savoir quels résultats sont facturables. |
Le même ID de requête sert de clé pour prévisualiser les payloads de requête et de réponse dans le Activity Log du Dashboard (conservés 24 heures, 200 derniers par clé), ce qui vous permet de retrouver la requête exacte plus tard et de la rejouer depuis l'Activity Log directement dans le Playground. Fournissez-le lorsque vous contactez le support afin d'identifier la requête en quelques secondes.
$ curl -i -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://example.com"}'
HTTP/2 200
content-type: application/json
x-foura-request-id: 8f3e2a14-7b6c-4d1a-9e2f-5a3b8c1d4e7f
x-foura-credits: 2
...
Consultez Response Headers pour la liste complète et des conseils d'utilisation.
Endpoints
Vous utilisez ces endpoints via MCP ? Le serveur
@fouradata/mcpencapsule les quatre endpoints sous forme d'outils MCP natifs (foura_auto,foura_single,foura_proxy,foura_browser) avec les mêmes formats d'entrée, plus une optionoffload_largepour une gestion des réponses volumineuses optimisée en tokens.
FourA fournit quatre endpoints de requête, chacun optimisé pour un scénario différent :
| Endpoint | Idéal pour |
|---|---|
POST /auto/ |
Smart fetch. Vous transmettez une URL, FourA choisit le chemin le moins coûteux qui fonctionne (direct, proxy rotatif ou navigateur) et mémorise ce qui fonctionne par hôte. |
POST /single/ |
Requêtes HTTP rapides, pages statiques, API |
POST /proxy/ |
Sites protégés avec rotation automatique des proxies, ciblage par pays visible par la cible en option |
POST /browser/ |
Pages rendues en JavaScript, SPA |
GET /profiles |
Le catalogue de profils de navigateur pour single et proxy. Public, sans clé API. |
Pour une analyse plus détaillée afin de choisir le bon endpoint, consultez Choosing the Right Endpoint et le guide Smart Fetch.
Target URL Restrictions
Les cibles qui résolvent vers des plages d'adresses IP privées, de bouclage ou réservées (RFC 5735, RFC 6598, blocs réservés IPv6) sont refusées avec une erreur 400 avant que la requête ne quitte FourA. Seuls les noms d'hôtes et les IP publics sont transmis.
{ "error": "Refusing to fetch <target>: target resolves to a private or reserved IP range. The FourA scraping API only forwards requests to public internet hosts." }
Smart Fetch (Auto)
POST /api/auto/
Vous transmettez une URL ainsi que des regles validate optionnelles. FourA parcourt une echelle optimisee en couts (sonde directe economique, proxy avec rotation, navigateur complet) et s'arrete au premier niveau qui renvoie une response acceptee par vos regles. Lors des appels suivants vers le meme hote, une session active est rejouee, rendant la deuxieme requete peu couteuse.
Vous n'avez pas a ajuster les retries, la taille des pools ou le nombre de proxys. FourA les optimise automatiquement par hote.
Request Body
| Parametre | Type | Requis | Valeur par defaut | Description |
|---|---|---|---|---|
url |
string | Oui | - | URL cible |
method |
string | Non | "GET" |
Methode HTTP |
headers |
[string, string][] | Non | - | Headers personnalises sous forme de paires [name, value] |
data |
any | Non | - | Request body pour les requetes autres que GET |
validate |
object | Non | - | Criteres de succes, meme structure que validate de Single Request (voir ci-dessous). Indiquez au mode auto a quoi ressemble une vraie page afin qu'il puisse distinguer le contenu reel d'une page de challenge. |
returnSession |
boolean | Non | true |
Inclure la session gagnante (proxy, cookies, userAgent) dans la response afin de pouvoir la rejouer via /api/single/ ou /api/browser/. |
forceProxy |
boolean | Non | true |
Toujours router via un proxy avec rotation. Definissez false pour autoriser le chemin direct plus economique lorsque la cible le permet (certaines protections etant plus strictes sur le trafic issu de proxys). |
timeout_ms |
integer | Non | 120000 |
Budget de temps total pour l'ensemble de l'appel, en millisecondes. Toutes les sous-tentatives s'executent dans cette limite. Min 5000, max 180000. |
ignoreProxies |
string[] | Non | - | ID de proxys a eviter sur chaque sous-tentative. Utilisez les ID renvoyes par les responses precedentes de /api/auto/ ou /api/proxy/. |
followRedirects |
integer | Non | 5 |
Nombre maximal de redirections a suivre sur les niveaux economiques de l'echelle. 0 pour desactiver. Max 20. |
Response
{
"status": 200,
"data": "<!doctype html>...",
"headers": [{"content-type": "text/html"}],
"meta": {
"rung": "cache",
"solved": false,
"attempts": 1,
"credits": 2
},
"session": {
"proxy": "A1B2C3",
"cookies": [{"name": "session", "value": "abc", "domain": "example.com"}],
"userAgent": "Mozilla/5.0..."
}
}
| Champ | Type | Description |
|---|---|---|
status |
number | Statut HTTP renvoyé par la cible. |
data |
string | Corps de la réponse au format texte, quel que soit l'échelon utilisé. Une page JSON est renvoyée sous forme de texte JSON, vous devez donc la parser vous-même. |
headers |
array or object | Headers de réponse de la cible. Les échelons direct et proxy renvoient un tableau d'objets d'en-têtes par saut; les échelons de navigateur renvoient un objet plat. |
meta.rung |
string | Échelon de l'échelle ayant délivré la réponse. Valeurs possibles: probe (requête directe économique), proxy (proxy rotatif), browser (rendu complet dans le navigateur), cache (session active rejouée), warmup (la page d'accueil du site a d'abord été récupérée et ses cookies ont débloqué l'URL profonde), ou fail (aucun échelon n'a produit de réponse valide). |
meta.solved |
boolean | Indique si la page a nécessité une étape supplémentaire (page de défi/CAPTCHA) et si elle a été résolue pendant cet appel. |
meta.attempts |
number | Nombre de sous-tentatives effectuées avant le succès. |
meta.credits |
number | Total des crédits consommés pour cet appel. Correspond à X-FourA-Credits. |
session.proxy |
string | Identifiant encodé du proxy ayant délivré la réponse. Réutilisez-le sur une requête Single ou Browser. Présent lorsque returnSession vaut true. |
session.cookies |
array | Cookies issus de la tentative réussie. Présent lorsque returnSession vaut true. |
session.userAgent |
string | User-Agent utilisé lors de la tentative réussie. Présent lorsque returnSession vaut true. |
error |
string | Message d'erreur si l'appel a échoué. |
Exemple
curl -X POST https://eu.api.foura.ai/api/auto/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product/42",
"validate": {"data": {"accept": ["Add to cart"]}}
}'
Notes
- Auto est un coordinateur. Il appelle Single, Proxy ou Browser en interne et transmet votre clé API à chaque sous-appel. L'appel Auto représente une seule request dans votre Activity Log et sur votre Overview, avec la somme des crédits de ses sous-appels; les sous-appels sont listés sous celui-ci en tant que tentatives, et ils ne comptent jamais comme des requests distinctes.
- Passez
validate.data.acceptavec une sous-chaîne que seule la vraie page contient. Sans cela, auto ne peut pas distinguer un vrai 200 d'un interstitiel de challenge renvoyé avec un statut 200. timeout_msplafonne l'ensemble de l'appel. Un premier accès à froid sur un site protégé peut prendre plusieurs dizaines de secondes; les sessions réutilisées à chaud se terminent généralement en moins d'une seconde.
Single Request
POST /api/single/
Envoie une request HTTP avec des caractéristiques réseau réalistes similaires à celles d'un navigateur, sans lancer de véritable navigateur. C'est l'endpoint le plus rapide.
Request Body
| Paramètre | Type | Requis | Par défaut | Description |
|---|---|---|---|---|
method |
string | Oui | - | Méthode HTTP : GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
url |
string | Oui | - | URL cible. Utilisez {ts} n'importe où dans l'URL pour insérer le timestamp actuel pour contourner le cache. |
headers |
[string, string][] | Non | - | Headers personnalisés sous forme de paires [nom, valeur] |
unblocker |
boolean | Non | true |
Envoyer des headers de navigateur réalistes (User-Agent, Sec-Ch-Ua, Sec-Fetch-*, Accept-Encoding). Activé par défaut. Définissez false pour envoyer une signature client simple. |
timeout_ms |
number | Non | 15000 | Timeout global en ms (max : 120000) |
connect_timeout_ms |
number | Non | 5000 | Timeout de connexion en ms |
accept_timeout_ms |
number | Non | 5000 | Timeout d'acceptation en ms (temps d'attente pour l'acceptation de la connexion) |
server_response_timeout_ms |
number | Non | 15000 | Timeout de réponse du serveur en ms (temps d'attente pour le premier octet) |
dns_cache_timeout_sec |
number | Non | 120 | TTL du cache DNS en secondes (max : 240) |
followRedirects |
number | Non | disabled | Nombre maximal de redirections à suivre (0-20). Omettre pour désactiver. |
tryJsonData |
boolean | Non | false | Parser le corps de la réponse en JSON si possible |
returnBuffer |
boolean | Non | false | Renvoyer un buffer brut au lieu d'une chaîne décodée |
data |
any | Non | - | Corps de la requête (string ou objet, sérialisé automatiquement en JSON) |
proxy |
string | Non | - | Identifiant de proxy d'une réponse précédente, pour épingler la même sortie. Transmettez la chaîne opaque telle quelle. Une adresse proxy brute est rejetée avec 400 Invalid proxy format. Certains identifiants ne peuvent pas être épinglés : voir Épingler une sortie. |
browser |
string | Non | Chrome | Navigateur à présenter : Chrome, Edge, Safari, Firefox ou Tor. Voir Profils de navigateur. |
os |
string | Non | - | Système d'exploitation à présenter : Windows, macOS, Android ou iOS. Un nom de famille accepte n'importe laquelle de ses versions. |
version |
string | Non | newest | Version du navigateur à présenter, telle que répertoriée dans le catalogue. La correspondance la plus récente l'emporte lorsque plusieurs correspondent. |
profile |
string | Non | - | Identifiant exact du profil issu de GET /api/profiles, au lieu des trois champs ci-dessus. |
validate |
object | Non | - | Règles de validation de la réponse (voir ci-dessous) |
Profils de navigateur
Par défaut, une requête présente la dernière version de Google Chrome. Certaines cibles acceptent un navigateur et en refusent un autre, ainsi browser, os et version permettent de filtrer un catalogue de profils mesurés, et profile en sélectionne un par son identifiant.
{
"method": "GET",
"url": "https://example.com",
"browser": "Firefox",
"os": "Windows"
}
Règles :
- La sélection nécessite
unblocker(activé par défaut). Avecunblockerdésactivé, aucun header de navigateur n'est envoyé, donc la request est refusée plutôt que partiellement appliquée. - Lorsque plusieurs profils correspondent, la version la plus récente est retenue.
- Une combinaison que le catalogue ne peut pas fournir renvoie une erreur précisant les options disponibles. La request n'est jamais envoyée sous l'identité d'un autre navigateur.
- Les quatre mêmes champs sont disponibles dans l'objet
requestdePOST /proxy/.
GET /api/profiles renvoie le catalogue complet et ne nécessite aucune clé API :
{
"profiles": [
{ "id": "...", "browser": "Chrome", "version": "...", "os": "...", "osFamily": "macOS" }
],
"default": "..."
}
osFamily est la valeur sur laquelle filtrer lors de la création d'un sélecteur; os conserve le nom de la version pour l'affichage.
Règles de validation
L'objet validate vous permet de définir des conditions de succès et d'échec. Si une condition fail correspond, la requête est considérée comme ayant échoué. Si des conditions accept sont définies, seules les réponses correspondantes sont considérées comme réussies.
{
"validate": {
"status": { "accept": [200, 201], "fail": [403, 503] },
"headers": { "accept": {"content-type": "application/json"} },
"data": { "accept": ["product"], "fail": ["captcha", "blocked"] }
}
}
| Champ | Type | Description |
|---|---|---|
validate.status.accept |
number[] | Codes de statut HTTP à accepter |
validate.status.fail |
number[] | Codes de statut HTTP à rejeter |
validate.headers.accept |
object | Paires clé-valeur de header qui doivent être présentes |
validate.headers.fail |
object | Paires clé-valeur de header qui déclenchent un échec |
validate.data.accept |
string[] | Chaînes qui doivent apparaître dans le corps de la response |
validate.data.fail |
string[] | Chaînes dans le corps de la response qui déclenchent un échec |
Exemple
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://example.com/products",
"timeout_ms": 10000
}'
Response :
{
"status": 200,
"headers": [{"result": {"version": "HTTP/2", "code": 200, "reason": ""}, "content-type": "text/html", "server": "...", "set-cookie": ["session=abc", "tracker=xyz"]}],
"data": "<!doctype html>...",
"total_time": 0.342,
"proxy": "A1B2C3"
}
Lorsque la cible exécute une vérification de bot avant d'atteindre le body, la response contient également un objet defense indiquant le fournisseur et si la vérification a été validée :
{
"status": 200,
"data": "<!doctype html>...",
"total_time": 3.61,
"defense": {
"vendor": "sgcaptcha",
"solved": true,
"present": ["sgcaptcha"],
"ms": 3412,
"cookie": "_I_=<clearance>"
}
}
| Champ | Type | Description |
|---|---|---|
status |
number | Code de statut HTTP de la cible |
headers |
array | Un objet par saut de redirection. Chacun possede un champ result avec la ligne de statut ainsi que chaque header de reponse. Les headers a valeurs multiples (Set-Cookie, Link, WWW-Authenticate) sont renvoyes sous forme de tableaux de chaines. |
data |
string/object | Corps de la reponse (JSON si tryJsonData est true) |
total_time |
number | Duree totale de la requete en secondes |
proxy |
string | Identifiant encode du proxy par lequel la requete a transite (uniquement si un proxy a ete fourni dans la requete). Reutilisez-le lors d'un appel suivant pour fixer la meme sortie. |
defense |
object | Present lorsque la cible a execute une verification de bot sur cette requete, ou lorsqu'une nouvelle tentative avec les propres cookies du site a produit le corps. defense.solved indique si une verification a ete validee, defense.retry indique si une nouvelle tentative vous a permis d'obtenir le contenu. Consultez Site checks pour chaque champ et la liste complete des systemes. |
error |
string | Message d'erreur en cas d'echec de la requete |
Proxy Request
POST /api/proxy/
Achemine votre requete via des proxies tournants avec nouvelle tentative automatique en cas d'echec. Permet facultativement de limiter la selection a un ensemble de pays de sortie visibles par la cible.
Request Body
| Parametre | Type | Requis | Par defaut | Description |
|---|---|---|---|---|
request |
object | Oui | - | Un corps de requete unique (memes champs que Single Request ci-dessus) |
timeout_ms |
number | Non | 45000 | Delai d'expiration global pour toutes les tentatives en ms (max : 120000) |
maxTries |
number | Non | 5 | Nombre maximal de tentatives de rotation de proxy (max : 90) |
ignoreProxies |
string[] | Non | - | Identifiants de proxy a exclure de la rotation (utilisez les identifiants renvoyes par les reponses precedentes) |
exitCountries |
string[] | Non | - | Liste d'autorisation stricte de codes pays a deux lettres visibles par la cible (par exemple ["CZ", "GB"]). Les valeurs sont nettoyees, passees en majuscules et dedupliquees. Les proxies avec des sorties inconnues sont exclus et la requete ne se rabat jamais sur un pays non demande. |
exitClass |
string | Non | - | standard ou premium. premium permet a la requete de basculer vers une sortie premium lorsque le pool standard rencontre des difficultes sur une cible protegee. Necessite un forfait incluant les sorties premium. |
Portee de exitCountries
La selection utilise les dernieres metadonnees de pays visibles par la cible disponibles, generalement actualisees en une dizaine de minutes. Il ne s'agit pas d'une recherche de geolocalisation en direct pendant la requete. Ne deduisez pas le pays de distribution a partir de l'adresse de l'hote proxy.
Si le pool actuel n'a aucune correspondance pour les pays demandes, la reponse renvoie un code HTTP 200 avec une enveloppe d'erreur :
{
"error": "No eligible proxy found for exit countries: CZ, GB",
"code": "no_eligible_proxy",
"details": { "exitCountries": ["CZ", "GB"] },
"total": 0.084
}
Conservez le scope demandé et réessayez plus tard. Ne le modifiez ou ne l'élargissez que si l'exigence de pays de votre workflow change explicitement.
Exemple
curl -X POST https://eu.api.foura.ai/api/proxy/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"maxTries": 3,
"exitCountries": ["CZ", "GB"],
"request": {
"method": "GET",
"url": "https://example.com/prices"
}
}'
Response :
{
"status": 200,
"headers": [{"result": {"code": 200}, "content-type": "text/html", "set-cookie": ["a=1", "b=2"]}],
"data": "<!doctype html>...",
"total_time": 1.204,
"proxy": "A1B2C3",
"exitCountry": "CZ",
"total": 2.341
}
| Champ | Type | Description |
|---|---|---|
proxy |
string | Identifiant encode du proxy utilise. Reutilisez-le sur une requete Single ou Browser en le transmettant dans le champ proxy, ou ignorez-le lors de la prochaine requete Proxy via ignoreProxies. |
exitCountry |
string | Code pays a deux lettres visible par la cible pour le proxy ayant traite la requete. Present uniquement lorsque la requete a defini exitCountries. Verifiez toujours qu'il correspond a l'un des codes demandes avant de faire confiance a la reponse. |
exitClass |
string | Classe de sortie ayant traite cette requete, presente sur une reponse reussie lorsque la requete en a specifie une. premium indique qu'une sortie premium a renvoye le corps; standard indique que le pool standard l'a fait. Un appel en echec n'a rien traite, il ne contient donc aucun exitClass; consultez son attemptReport pour savoir ce que les tentatives ont rencontre. |
total |
number | Duree totale d'horloge reelle en secondes (float). Inclut la selection du proxy, les nouvelles tentatives et la tentative reussie. total_time concerne uniquement la requete interne; total est toujours >= total_time. |
profile |
string | Profil de navigateur choisi par la rotation, present uniquement lorsqu'il differe de celui que vous avez demande. Son absence signifie que la requete a ete envoyee exactement comme specifie. Renvoyez l'id dans profile lors des appels suivants pour conserver le navigateur fonctionnel. |
error |
string | Message d'erreur en cas d'echec de la requete. Lors d'un ecart de perimetre, code vaut no_eligible_proxy et details.exitCountries reflete le perimetre normalise. |
attemptReport |
object | Present sur chaque appel Proxy en echec. Comptabilise les problemes rencontres par les tentatives, afin qu'un pool bloque, un pool hors service et une regle validate sans correspondance n'apparaissent pas comme la meme erreur. Voir ci-dessous. |
Tous les champs de reponse de Single Request sont egalement inclus, dont defense : une tentative de proxy rencontrant une verification bot le signale de la meme maniere que Single.
Pourquoi un appel Proxy a echoue
Download maxTry limit reached a la meme valeur quelle que soit la maniere dont les tentatives se sont deroulees, donc chaque reponse Proxy en echec inclut un attemptReport a cote de l'erreur :
{
"error": "Download maxTry limit reached",
"attemptReport": {
"total": 25,
"noResponse": 0,
"defense": 0,
"contentRejected": 25,
"statusRejected": 0,
"other": 0,
"vendors": [],
"profilesTried": ["default"],
"summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
},
"total": 34.812
}
| Champ | Type | Description |
|---|---|---|
total |
integer | Tentatives effectuées |
noResponse |
integer | La sortie n'a jamais répondu, le site n'a donc jamais été atteint |
defense |
integer | Le site a répondu et une vérification de bot a été détectée sur cette réponse |
contentRejected |
integer | HTTP 200, aucune vérification de bot, rejeté uniquement par votre validate.data |
statusRejected |
integer | Le site a répondu, aucune vérification de bot, rejeté par votre validate.status |
other |
integer | A répondu, et aucun des cas ci-dessus |
vendors |
string[] | Fournisseurs de vérification de bot détectés au cours de la tâche |
profilesTried |
string[] | Profils de navigateur envoyés par la tâche, dans l'ordre de première utilisation. default signifie que votre requête a été envoyée sans modification. |
summary |
string | Une phrase générée à partir des compteurs, prête pour les logs |
La chaîne error reste inchangée, ainsi un client qui effectue une correspondance dessus continue de fonctionner. Actions à mener pour chaque compteur : Pourquoi une requête proxy a épuisé ses tentatives.
exitClass
Certaines cibles refusent les sorties du pool standard quel que soit le nombre de tentatives. exitClass: premium indique à Proxy qu'il peut faire monter cette requête vers une sortie premium en plus du pool standard, au lieu de simplement effectuer une rotation au sein de celui-ci.
{
"exitClass": "premium",
"request": { "method": "GET", "url": "https://example.com/report" }
}
Trois éléments sont à connaître avant de l'envoyer.
Il s'agit d'une autorisation, pas d'une instruction. Le pool standard tente toujours de répondre en premier, et l'emporte généralement. Une sortie premium intervient uniquement lorsque le pool a consommé un court budget sur la request ou que la cible l'a explicitement refusée. Une request traitée avec succès par le pool standard avant toute tentative de sortie premium constitue un succès normal et ne consomme aucun trafic premium. Dès qu'une sortie premium a été tentée, son trafic est comptabilisé, comme décrit ci-dessous.
La response vous indique ce qui vous a réellement servi. Lorsque vous spécifiez une classe, la response renvoie exitClass :
{
"status": 200,
"exitClass": "premium",
"proxy": "Y2QXVK",
"data": "..."
}
premium signifie qu'une sortie premium a renvoyé le corps de la réponse. standard signifie que le pool standard l'a fait, ce qui correspond aussi à la réponse obtenue lorsqu'une sortie premium n'a pas pu être obtenue, et lorsque le trafic premium inclus dans votre forfait (ainsi que les volumes supplémentaires achetés) est épuisé pour la période de facturation. Aucun des deux cas n'est une erreur, et vous pouvez rapprocher votre trafic premium à partir de ces informations par request plutôt que sur un chiffre mensuel. La même valeur transite dans le header de response X-FourA-Exit-Class (voir Response Headers).
Le trafic premium est mesuré sur le réseau. Une tentative premium comptabilise ce qu'elle a envoyé et reçu lors de son transit sur le réseau, compressé et chiffré au passage, qu'elle ait ou non renvoyé votre page. Une tentative qui était encore en cours d'exécution lorsqu'une autre sortie a répondu est arrêtée immédiatement et n'est pas prise en compte. Le trafic premium est décompté de votre quota premium et figure également dans votre bande passante totale: les mêmes octets, rapportés deux fois, ne sont jamais additionnés. Lorsqu'une sortie premium a délivré la page, son trafic constitue l'intégralité du trafic de la request, de sorte que la page n'est pas recomptabilisée comme trafic standard. Votre page Usage & Limits affiche le trafic total, la part premium de celui-ci, ainsi que le quota premium auquel vous êtes soumis.
Omettre ce champ n'est pas équivalent à envoyer standard. L'omettre laisse la décision indéterminée; envoyer standard indique explicitement que cette request ne doit jamais faire l'objet d'une escalade, ce qui permet d'exclure totalement une tâche spécifique du trafic premium.
L'épuisement du forfait n'est pas une erreur. Une request spécifiant premium après épuisement du quota continue de fonctionner: le pool standard la traite et la response indique standard. Aucune tâche ne s'interrompt en raison d'un quota épuisé.
exitClass: premium nécessite un forfait incluant des sorties premium. Avec un forfait sans sorties premium, la request ne consomme jamais de sortie premium: elle est soit refusée avec un code 403 contenant X-FourA-Limit: plan_limit_premium (voir Rate Limits), soit traitée par le pool standard avec exitClass: standard dans la response. Gérez les deux cas.
Browser Profile Rotation
Proxy assure la rotation des sorties. Lorsqu'un site refuse le navigateur présenté par FourA plutôt que la sortie dont il provient, Proxy bascule également vers une autre famille de navigateurs du catalogue. Cela n'ajoute aucune tentative: la rotation modifie ce qu'envoie une nouvelle tentative, mais ne détermine jamais si elle a lieu.
Proxy mémorise également, pendant un certain temps, la famille qu'un site a acceptée en dernier, afin qu'un appel ultérieur vers le même site puisse démarrer sur cette famille au lieu de celle par défaut. La response l'indique dans profile, comme elle le fait pour toute famille choisie par la rotation.
Une valeur explicite de profile, browser, os, ou version sur votre request interne n'est jamais écrasée, pas plus qu'une request portant son propre header User-Agent ou Cookie, car une autorisation d'accès est liée à la signature qui l'a obtenue.
Browser Request
POST /api/browser/
Ouvre votre URL dans une instance de navigateur Chrome. La page se charge, le JavaScript s'exécute, et vous obtenez le HTML entièrement rendu ainsi que le cookie jar.
Corps de la requête
| Paramètre | Type | Requis | Valeur par défaut | Description |
|---|---|---|---|---|
url |
string | Oui | - | URL cible |
headers |
object | Non | - | Headers personnalisés sous forme de paires clé-valeur |
cookies |
array | Non | - | Cookies à définir : [{name, value, domain?}] |
userAgent |
string | Non | - | Chaîne User-Agent personnalisée |
unblocker |
boolean | Non | true |
Valide la vérification demandée par une page avant son chargement (page de challenge ou barrière similaire). Activé par défaut. Définissez false pour afficher ce que la page renvoie tel quel, y compris une page de challenge. |
proxy |
string | Non | - | ID de proxy d'une réponse précédente, pour conserver la même sortie. Renvoyez la chaîne opaque telle quelle. Une adresse de proxy brute est rejetée avec 400 Invalid proxy format. |
exitCountry |
string | Non | - | Code pays à deux lettres (ISO 3166-1 alpha-2) du pays par lequel la requête sort. Règle l'horloge du navigateur sur le fuseau horaire correspondant. Voir Faire correspondre l'horloge du navigateur à la sortie. |
timeout_ms |
number | Non | 30000 | Délai d'expiration du chargement de la page en ms (max : 120000) |
checkStatus |
number | Non | - | Code de statut HTTP attendu (la requête échoue s'il est différent) |
checkText |
string | Non | - | Texte qui doit apparaître dans la page rendue |
Faire correspondre l'horloge du navigateur à la sortie
Une page peut lire le fuseau horaire du navigateur et le comparer au pays de l'IP détectée. Une non-concordance est l'un des signaux les plus simples qu'un détecteur de bots puisse utiliser, et l'éliminer ne vous coûte rien.
Définissez exitCountry sur le pays par lequel votre trafic sort et le navigateur transmettra un fuseau horaire correspondant :
{
"url": "https://example.com",
"proxy": "A1B2C3",
"exitCountry": "BR"
}
Règles :
- La valeur correspond au pays de sortie, c'est-à-dire le pays que la cible voit, et non l'endroit où le proxy est hébergé. Les deux diffèrent suffisamment souvent pour que cela ait de l'importance.
- Si vous l'omettez, FourA utilise le pays de sortie lorsqu'il le connaît, et conserve l'horloge du navigateur telle quelle au lieu de deviner.
- Un code de pays non reconnu par FourA est traité comme une omission du champ. Cela ne génère pas d'erreur.
- Seule l'horloge s'adapte au pays.
Accept-Languageet le contenu fourni par le site restent inchangés, de sorte qu'une page ne changera pas de langue de manière inattendue.
Le paramètre userAgent
Envoyez userAgent et cette chaîne exacte correspondra à ce que la page, ses workers et la cible recevront. FourA en déduit également les client hints correspondants (sec-ch-ua, sec-ch-ua-platform, navigator.platform, ainsi que les valeurs à haute entropie demandées par un détecteur), afin que la requête n'indique pas un navigateur dans l'en-tête et un autre dans JavaScript.
Le userAgent dans la réponse est celui qui a été présenté. C'est important lorsque vous rejouez un clearance : un cookie cf_clearance est lié au point de sortie et au User-Agent qui l'ont obtenu, renvoyez donc la chaîne indiquée dans la réponse, et non celle que vous pensez avoir utilisée. Voir Site checks.
Si vous envoyez une chaîne non-Chromium (par exemple, un User-Agent Firefox), elle est transmise telle quelle, sans liste de marques Chromium associée.
Exemple
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/spa-app",
"timeout_ms": 15000,
"checkText": "product-list"
}'
Response :
{
"status": 200,
"headers": {"content-type": "text/html"},
"body": "<!doctype html>...",
"cookies": [{"name": "session", "value": "abc123", "domain": "example.com", "path": "/", "expires": 1735689600, "httpOnly": true, "secure": true, "sameSite": "Lax"}],
"userAgent": "Mozilla/5.0...",
"defenseSolved": true,
"defenses": {"present": ["cloudflare"], "cleared": ["cloudflare"]},
"proxy": "A1B2C3"
}
| Champ | Type | Description |
|---|---|---|
status |
number | Code de statut HTTP de la cible |
headers |
object | Headers de réponse |
body |
string or object | Contenu de la page entièrement rendu. Chaîne HTML lorsque le content-type est HTML ; objet lorsque la page a renvoyé du JSON et a été automatiquement analysée. |
cookies |
array | Objets cookie complets de la page. Chaque cookie inclut name, value, domain, path, expires, httpOnly, secure, sameSite et d'autres propriétés de cookie. |
userAgent |
string | User-Agent du navigateur utilisé |
defenseSolved |
boolean | true si une protection anti-bot a été rencontrée et réellement contournée lors de cet appel. Absent dans le cas contraire. Détermine si l'appel coûte 5 ou 10 crédits. |
defenses |
object | present liste chaque fournisseur reconnu pendant le chargement de la page, cleared liste ceux dont la page finale conserve l'autorisation. Un fournisseur peut apparaître dans present et jamais dans cleared. Voir Site checks. |
proxy |
string | ID encodé du proxy par lequel la request a transité (uniquement lorsqu'un proxy a été fourni dans la request). Réutilisez-le lors des appels de suivi pour conserver la même sortie. |
error |
string | Message d'erreur si la request a échoué |
Épingler une sortie
Une valeur proxy sur une request Single ou Browser épingle la sortie utilisée par un appel précédent. Renvoyez l'ID opaque exactement tel qu'il a été reçu, jamais une adresse de proxy.
Trois valeurs sont refusées, toutes avec une erreur 400 :
| Erreur | Signification |
|---|---|
Invalid proxy format |
La valeur n'est pas un ID émis par FourA. Une adresse de proxy brute aboutit ici. |
Proxy not found |
L'ID a été décodé, mais il ne correspond plus à une sortie active. Obtenez-en un nouveau via un nouvel appel. |
Managed exit: this proxy id cannot be pinned to a request |
La sortie existe, mais FourA ne la maintiendra pas ouverte pour une request nommée. L'ID d'une sortie premium aboutit ici lorsque votre forfait n'a plus de trafic premium disponible. Réutilisez la session avec laquelle il a été renvoyé, ou exécutez l'appel via POST /api/proxy/ et acceptez la sortie sélectionnée. |
Une sortie premium épinglée est comptabilisée comme du trafic premium. La réponse contient X-FourA-Exit-Class: premium afin que vous puissiez le voir par request, et le trafic acheminé par la sortie est décompté du trafic premium sur votre page Usage & Limits ainsi que de votre bande passante totale, que le site ait renvoyé la page souhaitée ou non. L'épinglage nécessite des sorties premium dans votre forfait et un solde disponible ; sinon, l'ID est refusé avec l'erreur 400 managed-exit ci-dessus.
Codes de statut HTTP
| Code | Signification |
|---|---|
| 200 | Requête terminée (vérifiez le champ interne status pour la réponse cible) |
| 400 | Corps de requête ou paramètres non valides, IP cible dans une plage privée/réservée, ou proxy ID impossible à épingler |
| 401 | Clé API manquante ou non valide |
| 403 | L'endpoint ou un paramètre n'est pas inclus dans votre forfait. X-FourA-Limit l'indique : plan_limit_feature ou plan_limit_premium. |
| 404 | Not Found : aucun endpoint n'existe sur ce chemin. |
| 413 | Le corps de la requête JSON dépasse 100 Ko. La réponse n'est pas en JSON et ne contient aucun X-FourA-Request-Id. |
| 429 | Limite de forfait (X-FourA-Limit défini) ou quota partagé par minute de la plateforme (aucun header) |
| 500 | Erreur interne du serveur |
| 502 | Upstream unavailable. FourA a contacté son moteur mais la réponse était inutilisable. Réessayez. |
| 503 | Service temporairement désactivé ou saturé, ou Backend service unavailable pendant le redémarrage d'un moteur |
| 504 | Upstream timeout. Le moteur n'a pas terminé dans le délai imparti pour cette requête. Augmentez timeout_ms ou réessayez. |
Prochaines étapes
- Smart Fetch (Auto) : Quand laisser FourA choisir la méthode pour vous
- Choisir le bon endpoint : Quand sélectionner manuellement Single, Proxy ou Browser
- Authentification : Gérer vos clés API
- Gestion des erreurs : Gérer les erreurs de manière appropriée
- Vérifications du site : Lire le champ
defenseet rejouer une autorisation - Pourquoi une requête proxy a épuisé ses tentatives : Lire
attemptReportet réagir en conséquence - Rate Limits : Comprendre les limites de requêtes
- Démarrage rapide : Votre première requête en 30 secondes