Response Headers
Всеки response от FourA API съдържа малък набор от персонализирани headers. Те са полезни за трасиране, поддръжка, равняване на сметки и последващ анализ.
Headers, които FourA задава
| Header | Задава се при | Описание |
|---|---|---|
X-FourA-Request-Id |
Всеки /api/* response, включително грешки и 401s, с изключение на body, което FourA изобщо не може да прочете (400 Invalid JSON in request body, 413), което бива отказано преди да бъде присвоен ID |
UUID, идентифициращ този request. Логвайте го от ваша страна. |
X-FourA-Credits |
Всеки /api/* response, достигнал до backend-а |
Изразходени кредити за това извикване. Връща се при успех и при неуспех (работата е била извършена и в двата случая). |
X-FourA-Limit |
Всеки 403 или 429, предизвикан от някой от лимитите на вашия план |
Кой лимит е отказал извикването: plan_limit_, следван от feature, premium, concurrency, rate, browser_daily, credits или bandwidth. |
Retry-After |
429 при лимит на плана, които се изчистват след изчакване: concurrency, rate, кредити, bandwidth |
Секунди за изчакване като цяло число. Съответства на retry_after_seconds в тялото. |
X-FourA-Exit-Class |
Всяко /api/proxy/ извикване, което посочва exitClass и доставя страница, както и всяко Single или Browser извикване, обслужено през premium изходна точка |
premium или standard: класът на изходната точка, доставила съдържанието. Неуспешно Proxy извикване не доставя нищо и не носи такъв header. |
X-FourA-Check-Page |
Single, Proxy Finder и Browser responses, чието HTTP 200 body е страница за проверка за ботове, разпозната от FourA | Името на страницата за проверка, например amazon-captcha. Такъв request не се таксува: вижте Request Outcomes. |
Content-Type |
Всеки response | Винаги application/json за обвивката. Content-type на целевия ресурс се връща в полето headers на обвивката. |
X-FourA-Request-Id
Всяко извикване към POST /api/auto/, POST /api/single/, POST /api/proxy/ или POST /api/browser/ се маркира с UUID. Този header се задава дори когато автентикацията се провали, за да можете да свързвате и неправилно конфигурирани извиквания.
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/1.1 200 OK
X-FourA-Request-Id: 9f1c4e6c-7b2a-4d3e-8a1f-2c9d8e4a3b15
X-FourA-Credits: 2
Content-Type: application/json
...
Кога да се използва
- Запитвания за поддръжка: включете ID на заявката (request ID) и ние можем да намерим точното извикване в нашите записи.
- Вашите собствени логове: запазете го до съответния ред в лога на вашето приложение. Ако клиент подаде оплакване, че „данните бяха грешни в 14:32“, можете да повторите точния request.
- Проследяване в таблото: същото ID се появява в Activity feed за ключове, които управлявате, така че можете да отворите съответния ред и да прегледате записаните request и response.
Пример: логване от ваша страна
import logging
import requests
log = logging.getLogger(__name__)
def fetch(url, api_key):
resp = requests.post(
"https://eu.api.foura.ai/api/single/",
headers={"X-API-Key": api_key, "Content-Type": "application/json"},
json={"method": "GET", "url": url},
)
request_id = resp.headers.get("X-FourA-Request-Id", "no-id")
credits = resp.headers.get("X-FourA-Credits", "0")
log.info("foura request_id=%s url=%s status=%s credits=%s", request_id, url, resp.status_code, credits)
resp.raise_for_status()
return resp.json()
async function fetchPage(url, apiKey) {
const resp = await fetch('https://eu.api.foura.ai/api/single/', {
method: 'POST',
headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' },
body: JSON.stringify({ method: 'GET', url })
});
const requestId = resp.headers.get('X-FourA-Request-Id') || 'no-id';
const credits = resp.headers.get('X-FourA-Credits') || '0';
console.log(`foura request_id=${requestId} url=${url} status=${resp.status} credits=${credits}`);
return resp.json();
}
X-FourA-Credits
X-FourA-Credits отчита цената в кредити на заявката, която току-що сте направили. Това е брояч, а не сметка: този header отразява изразходваното за обработката, независимо от крайния резултат. Системата за таксуване в таблото отчита към вашия план само подлежащите на таксуване резултати (вижте Резултати от заявки за информация кои резултати се таксуват).
Справка за цените
| Engine | Базова | С unblocker |
|---|---|---|
| Single | 1 | 2 |
| Proxy | 2 | 4 |
| Browser | 5 | 10 (когато е преодоляна защита) |
/api/auto/ се брои като една заявка във вашето табло, като цената в кредити е сборът от подзаявките, направени вътрешно (едно повторно изпълнение към готов таргет може да струва 2; пълно преодоляване на труден сайт може да струва много повече). Стойността на X-FourA-Credits в автоматичния отговор е равна на meta.credits в тялото на отговора и проследява пълната цена по веригата.
Защо има и header, и поле в тялото?
Header-ът е удобен: можете да го прочетете преди парсване на тялото, да го запишете в логовете до реда на заявката или да го сумирате през множество повиквания без JSON парсване. Полето meta.credits в тялото (Auto) или метаданните за конкретния engine (таблата за Single, Proxy, Browser) съдържат същото число, но достъпно в рамките на самия response envelope.
X-FourA-Limit
X-FourA-Limit се появява само когато лимит от вашия план е отказал заявката. Споделените rate limits на платформата никога не го задават, така че този header е най-бързият начин да различите "планът ми спря това" от "FourA е зает", без да се налага да парсвате тялото на отговора.
HTTP/1.1 429 Too Many Requests
X-FourA-Limit: plan_limit_concurrency
Retry-After: 1
X-FourA-Request-Id: 9f1c4e6c-7b2a-4d3e-8a1f-2c9d8e4a3b15
Content-Type: application/json
Две от седемте стойности се връщат с 403 вместо с 429: plan_limit_feature (endpoint-ът или параметърът exitCountries не е включен във вашия план) и plan_limit_premium (exitClass: premium не е включен във вашия план). Нито една от двете не задава Retry-After, тъй като изчакването няма да промени отговора.
STOP_ON = {
"plan_limit_feature", "plan_limit_premium",
"plan_limit_browser_daily", "plan_limit_credits", "plan_limit_bandwidth",
}
resp = requests.post(url, headers=headers, json=payload)
limit = resp.headers.get("X-FourA-Limit")
if limit in STOP_ON:
stop_the_run(limit) # hours or days away, not seconds
elif limit:
time.sleep(int(resp.headers.get("Retry-After", 1)))
Седемте стойности и body полетата, които идват с всяка от тях, са в Rate Limits.
X-FourA-Exit-Class
X-FourA-Exit-Class посочва класа на изхода, който е доставил тялото: premium, когато е използван premium изход, и standard, когато е използван стандартният пул. Появява се в POST /api/proxy/ response, който е доставил страница, винаги когато в заявката е посочен exitClass, където тялото съдържа същата стойност, и в Single или Browser response, винаги когато фиксираният от вас proxy е бил premium изход, където тялото няма поле за това. Неуспешно Proxy повикване не връща съдържание, така че не съдържа нито хедъра, нито полето.
HTTP/1.1 200 OK
X-FourA-Exit-Class: premium
X-FourA-Credits: 2
X-FourA-Request-Id: 2c1d0f9e-4a7b-4c3e-9d2a-8b1f6e5c4d3a
Content-Type: application/json
Трафикът през premium exit се зачита както към вашия premium трафик, така и към общия ви трафик. Той се измерва на ниво мрежа и включва неуспешните premium опити, които не са върнали вашата страница, така че заявка, завършила с standard, все пак може да е изразходвала известен premium трафик при опит, пропаднал преди отговор от стандартния пул. Този header посочва класа, извършил доставката, а не дали е бил използван premium трафик: маркерът premium на ред в Activity и страницата Usage & Limits показват какво е отчетено. Какво прави exitClass и кога се използва premium exit: exitClass.
Cache Behavior
API не задава Cache-Control или ETag в отговорите. Всяко извикване достига до бекенда. Ако се нуждаете от кеширане, добавете го от ваша страна.
Target Response Headers
Заглавните части (headers), върнати от целевия сайт, не присъстват директно в отговора на FourA API. Те се връщат вътре в JSON структурата като поле headers. За крайните точки Single и Proxy това е масив от обекти с headers за всяко пренасочване (по един запис за всяка стъпка на пренасочване). За крайната точка Browser това е плосък обект с headers от финалния response.
{
"status": 200,
"headers": [
{ "Content-Type": "text/html; charset=utf-8", "Server": "..." }
],
"data": "<!doctype html>...",
"total_time": 0.42
}
Ако се нуждаете от конкретен целеви header, прочетете го от полето headers на обвивката, а не от самия HTTP response на API извикването.
Свързани
- API Endpoints: Формати на request и response обвивката
- API Errors: Как са структурирани response съобщенията за грешка
- Request Outcomes: Кои резултати се таксуват
- Activity Log: История за всяка заявка по request ID
- Rate Limits: Какво означава всяка стойност на
X-FourA-Limit