Szybka odpowiedź
Które błędy SERP API ponawiać i czy nieudane wyszukiwania są płatne?
SerpCrypto nigdy nie pobiera opłaty za błąd: tylko udane wyszukiwanie zużywa 1 kredyt. Ponów 429 concurrency_limit, 502 search_failed i 504 search_timeout z wykładniczym backoff. Nie ponawiaj 400, 401 ani 402: najpierw popraw parametr, klucz lub saldo. Kredyty kosztują od 0,30 USD/1K wyszukiwań i nigdy nie wygasają; płatność kryptowalutą, bez KYC.
Co oznacza każdy kod błędu?
Żaden wiersz tej tabeli nie zużywa kredytu. 1 kredyt = 1 udane zapytanie wyszukiwania, które zwraca jedną stronę wyników na dowolnym obsługiwanym silniku. Nieudane zapytanie nie jest rozliczane.
| HTTP | code | Przyczyna | Co zrobić | Ponowić? |
|---|---|---|---|---|
| 400 | invalid_parameter | Brakuje q lub wartość jest poza dozwoloną listą | Popraw zapytanie; komunikat wskazuje parametr | Nie |
| 401 | invalid_api_key | Brak klucza, literówka w kluczu lub unieważniony klucz | Sprawdź nagłówek lub api_key; w razie potrzeby utwórz nowy klucz | Nie |
| 402 | insufficient_credits | Konto ma 0 kredytów | Kup pakiet ze swojego salda | Po zakupie |
| 429 | concurrency_limit | Więcej wyszukiwań naraz, niż pozwala Twoje konto | Poczekaj, zmniejsz równoległość lub poproś pomoc techniczną o wyższy limit | Tak, z backoffem |
| 502 | search_failed | Silnik lub kolekcja zawiodły dla tego zapytania | Ponów to samo zapytanie | Tak, z backoffem |
| 504 | search_timeout | Brak odpowiedzi w czasie | Ponów to samo zapytanie | Tak, z backoffem |
Jak wygląda odpowiedź z błędem?
Każdy błąd ma to samo małe ciało JSON ze stabilnym code i czytelnym dla człowieka message. Rozgałęziaj się po code w swoim programie i loguj message dla ludzi. Status HTTP odpowiada tabeli powyżej.
{
"error": {
"code": "insufficient_credits",
"message": "Your account has no search credits left."
}
}Dlaczego dostaję 400 invalid_parameter?
Brakuje wymaganej wartości lub jedna wartość jest poza listą akceptowaną przez API. Typowe przyczyny to pusty q, nazwa silnika z literówką, np. google-news zamiast google_news, page powyżej 10 lub device inne niż desktop czy mobile.
message wskazuje parametr, który jest problemem. Porównaj swoje zapytanie z dokumentacją API; nic nie jest naliczane, więc możesz poprawić i od razu wysłać ponownie.
Dlaczego dostaję 401 invalid_api_key?
Klucz nie dotarł do API lub jest nieprawidłowy. Sprawdź, czy nagłówek to dokładnie Authorization: Bearer YOUR_KEY, ze spacją po Bearer. Sprawdź też, czy Twoja zmienna środowiskowa jest ustawiona w powłoce lub usłudze uruchamiającej kod, a nie tylko w terminalu. Unieważniony klucz nadal będzie zawodzić: utwórz nowy w panelu.
Co zrobić z 402 insufficient_credits?
Kup pakiet kredytów ze swojego salda, a następnie wyślij ponownie. Jeśli saldo jest zbyt niskie, najpierw doładuj kryptowalutą; minimalne doładowanie to 25 USD. Odczytaj credits_remaining z GET https://serpcrypto.com/api/v1/credits przed dużym zadaniem, aby nie zatrzymać się w połowie: to wywołanie jest darmowe.
Jak obsłużyć 429 concurrency_limit?
Zwolnij, zamiast się zatrzymywać. Limit liczy wyszukiwania działające w tym samym czasie, a nie wyszukiwania na dzień. Każde konto może wykonywać określoną liczbę wyszukiwań jednocześnie; limit jest widoczny w panelu i podwyższany na żądanie. Odczytaj concurrency_limit z endpointu kredytów i dopasuj do niego pulę workerów; strony Python i Node.js pokazują pulę, która nigdy go nie przekracza.
Kiedy zwracane są 502 i 504?
502 search_failed oznacza, że wyszukiwania nie udało się ukończyć dla tego zapytania; 504 search_timeout oznacza, że nie ukończyło się w czasie. Oba są darmowe i oba warto ponowić. Poczekaj trochę dłużej przed każdą nową próbą, jak robi to poniższy kod, i odpuść po pięciu próbach, żeby zawieszone zadanie nie zapętlało się w nieskończoność.
import os
import random
import time
import requests
API_URL = "https://serpcrypto.com/api/v1/search"
RETRYABLE = {429, 502, 504}
def search(params, max_attempts=5):
headers = {"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]}
for attempt in range(1, max_attempts + 1):
r = requests.get(API_URL, params=params, headers=headers, timeout=90)
if r.status_code == 200:
return r.json()
error = r.json().get("error", {})
if r.status_code not in RETRYABLE or attempt == max_attempts:
raise RuntimeError(f"{r.status_code} {error.get('code')}: {error.get('message')}")
# exponential backoff with jitter: about 1 s, 2 s, 4 s, 8 s
time.sleep(2 ** (attempt - 1) + random.random())
raise RuntimeError("unreachable")
print(search({"q": "solar panel installers", "gl": "au", "hl": "en"})["search_metadata"])// retry.mjs — Node.js 18+
const API_URL = "https://serpcrypto.com/api/v1/search";
const RETRYABLE = new Set([429, 502, 504]);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
export async function search(params, maxAttempts = 5) {
const url = `${API_URL}?${new URLSearchParams(params)}`;
const headers = { Authorization: `Bearer ${process.env.SERPCRYPTO_API_KEY}` };
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const res = await fetch(url, { headers });
if (res.ok) return res.json();
const body = await res.json().catch(() => ({}));
const code = body.error?.code ?? "unknown";
if (!RETRYABLE.has(res.status) || attempt === maxAttempts) {
throw new Error(`${res.status} ${code}: ${body.error?.message ?? ""}`);
}
// exponential backoff with jitter: about 1 s, 2 s, 4 s, 8 s
await sleep(1000 * 2 ** (attempt - 1) + Math.random() * 1000);
}
throw new Error("unreachable");
}
console.log((await search({ q: "solar panel installers", gl: "au", hl: "en" })).search_metadata);Czy mój timeout HTTP powinien być krótki czy długi?
Wystarczająco długi, by wyszukiwanie się zakończyło: wyszukiwanie działa na żywo, więc ustaw timeout klienta na 60 do 90 sekund, a nie kilka sekund. Klient, który poddaje się zbyt wcześnie, wysyła drugie zapytanie, gdy pierwsze wciąż trwa, co marnuje slot równoległości i, jeśli oba się powiodą, dwa kredyty.
Pytania o błędy
Czy wyszukiwanie jest płatne, jeśli mój program zawiesi się przed odczytaniem odpowiedzi?
Tak, jeśli API ukończyło wyszukiwanie i zwróciło 200: kredyt jest zużywany, gdy wyszukiwanie się powiedzie, a nie gdy je odczytasz. To kolejny powód, by ustawić długi timeout po stronie klienta.
Czy ponowne próby kosztują dodatkowo?
Tylko udana próba zużywa kredyt. Nieudane próby z 429, 502 lub 504 są darmowe, więc zapytanie, które uda się za trzecim razem, kosztuje łącznie 1 kredyt.
Gdzie zgłosić błąd, który ciągle powraca?
Napisz na [email protected], podając search_metadata.id udanego wyszukiwania albo czas, silnik i parametry tego, które się nie powiodło. Odpowiedzi e-mail w ciągu 12 godzin, 7 dni w tygodniu, w tym pomoc przy integracji API.