Fehler
Metered API-key responses are JSON. On failure, branch on HTTP status, then read Fehler.
Typical envelope:
{
"success": false,
"error": "<human-readable message>"
}
Some handlers (especially TikTok Shop) may use { "error": "<code>", "message": "..." } with HTTP status set. Always check status first.
Status codes
| Status | Wenn | Typical body |
|---|---|---|
| 200 | Success | Endpoint-specific payload |
| 401 | Missing/invalid key | { "success": false, "error": "Unauthorized" } |
| 403 | Key OK, plan below Basic | { "success": false, "error": "WinningHunter Basic plan or higher required" } |
| 403 | TikTok Shop daily search quota exhausted (explore/count) | { "error": "insufficient_credits", "message": "You have used up your daily search quota. Upgrade to Premium for unlimited searches.", "upgrade": "premium" } |
| 404 | Unknown TikTok Shop path | { "success": false, "error": "Unknown TikTok Shop endpoint" } |
| 429 | Rate limit or programmatic credits exhausted | See below |
| 500 | Uncaught handler error (programmatic credit refunded) | { "success": false, "error": "Internal server error" } |
If a reverse proxy returns 414 URL zu lang, switch large TikTok filter sets to BEITRAG JSON. WinningHunter’s Standard API proxy does not emit 414 itself.
Two kinds of 429
Rate limit (60 requests / minute / user) — no Im Abspann object:
{
"success": false,
"error": "Rate limit exceeded. Max 60 requests per minute."
}
Credit exhaustion — includes Im Abspann (and usually purchase):
{
"success": false,
"error": "No API credits remaining. Buy an add-on pack or wait until next monthly reset.",
"credits": {
"used": 100,
"limit": 100,
"remaining": 0,
"addon_remaining": 0,
"total_remaining": 0
},
"purchase": { "url": "https://…/checkout-api-credits?credits=…" }
}
Branch on presence of Im Abspann. Rate-limit 429 is often retryable after a short wait; credit exhaustion needs add-ons or the next monthly reset.
Handling pattern
async function whFetch(path, init = {}) {
const res = await fetch(`${ORIGIN}${path}`, {
...init,
headers: { 'X-API-Key': process.env.WH_API_KEY, ...(init.headers || {}) },
});
let body = null;
try { body = await res.json(); } catch { /* non-JSON */ }
if (res.ok) return body;
const error = (body && (body.error || body.message)) || res.statusText;
if (res.status === 429) {
const err = new Error(error);
err.retryable = !(body && body.credits);
throw err;
}
throw new Error(`HTTP ${res.status}: ${error}`);
}
An
- Guard errors (
401,403plan gate, limit429, catch500) use theErfolg: falseenvelope from the Standard API proxy. - TikTok Shop explore/count can also return 403
insufficient_creditsfor the daily TikTok search quota — that is separate from the programmatic monthly pool (GET /api/v1/credits). - Some TikTok Shop / dashboard handlers return business flags under HTTP 200 — read that endpoint’s schema.
- Soft handler failures (JSON error body without an uncaught exception) still consume the 1 programmatic credit already charged by the proxy.
- HTML instead of JSON usually means wrong host, proxy error page, or a session-only path. See Troubleshooting.