Solución de problemas
A symptom-first reference. Find the response you're seeing on the left, follow the fix on the right.
401 Acceso no autorizado — {"success": false, "error": "Unauthorized"}
The proxy could not resolve your request to a user.
- Confirm the header name. It must be
Clave X-API(case-insensitive) oAuthorization: Bearer <key>. Custom names (Api-Key,X-Auth, etc.) are not parsed. - If you are using
Autorización, the value must start withBearer(with a space).Authorization: <key>alone does no match. - Whitespace, quoting, and stray newlines in the key value will all fail. Print the key just before the request to confirm it's clean.
- The key may have been regenerated since you last copied it. Old keys stop working immediately on regeneration. Fetch a fresh value from
/api. - Query-param fallback
?api_key=works, but be sure your HTTP client URL-encodes it correctly.
403 Prohibido — subscription / access
The key was recognized, but API access is not enabled for the billing account tied to that key.
- Sign in to WinningHunter and confirm plan / billing and that API access is included for your organization.
- If access was just purchased, wait a moment and retry; cached session data in the browser does not affect API-key calls the same way.
- On team accounts, ask your admin to confirm the seat or org has API access.
404 — Punto final desconocido de TikTok Shop
Path is registered, but the underlying handler isn't in the public allowlist.
- Make sure you're calling
/api/v1/tiktok-shop/...(el/api/v1/prefix matters). The bare/api/tiktok-shop/...is the dashboard's session route and won't accept API keys. - Cross-check the path in the API reference and the relevant topic guide (TikTok Shop, Meta ad library, Brands, …).
- Trailing slashes matter — match exactly what the docs show (no trailing slash unless documented).
404 — No encontrado (HTML or generic)
The router never matched the request.
- Check verb: many endpoints accept only
OBTENERor onlyPUBLICAR; a few accept both (GET or POST). Wrong verb on the right path returns 404, not 405. - Path parameters:
/api/v1/tiktok-shop/videos/{id}requires{id}to match[A-Za-z0-9_-]+. IDs with:o.won't route.
429 — rate limit vs credit exhaustion
Two distinct cases share the same status.
error text contains |
Significado | Fix |
|---|---|---|
Se ha superado el límite de solicitudes. Máximo: 60 solicitudes por minuto. |
Per-minute burst limit. | Back off ~1s and retry; reduce concurrency. |
Se ha alcanzado el límite de crédito mensual (20 000). Se restablecerá el mes que viene. |
Quota exhausted. | Wait for the calendar month to roll over, or contact support about higher limits. See Credits & billing. |
You can disambiguate programmatically by checking for the créditos object in the JSON body — only credit-exhaustion 429s include it.
414 URI demasiado largo
You sent a OBTENER with a very large query string (e.g. dozens of category IDs).
- Switch to
PUBLICARJSON. Explore/count TikTok Shop routes that accept POST merge the same parameters from a JSON body with the query string (see Filtros de TikTok Shop).
curl -X POST \
-H "X-API-Key: $WH_API_KEY" \
-H "Content-Type: application/json" \
"{origin}/api/v1/tiktok-shop/products/explore" \
-d '{"country":"US","period":"30d","category_ids":["..."],"limit":100}'
Error 500 del servidor interno
The proxy caught an uncaught exception and responds with {"success": false, "error": "Internal server error"}.
- Credits: that failure does not consume your monthly credit (it is refunded automatically). Still use backoff — repeated 500s usually mean bad input or an upstream bug.
- Retry with exponential backoff; if the same payload 500s every time, capture the request (key redacted) and contact support.
- Malformed JSON, bad
paíscodes, or invalid numerics sometimes surface as 500 from deep handlers — sanity-check the body against Filtros de TikTok Shop or the relevant guide.
"I get HTML back, not JSON"
You aren't hitting the application — there's an intermediary returning an error page.
- Verify your origin (
{origin}in the docs). A typo, missing scheme, or a CDN with a regional outage will all serve HTML. - Check that
/api/v1/tiktok-shop/credits(or any other endpoint) returns JSON when called from the same machine viacurl -iso you see the headers. - If a corporate proxy is rewriting
Autorizaciónheaders, switch toClave X-API(less commonly mangled).
Empty or surprising results
- Products / shops have very few rows. You probably mixed
períodoconfecha_de_inicio/fecha de finalización. Véase Intervalos de tiempo — pass soloperíodoon TikTok Shop endpoints. paísdefaults toEE. UU.. Always set it explicitly for non-US queries; otherwise you'll see US data even when filters look right.- Filter aliases.
ingresos_mínimos_30_díasyingresos mínimosmean the same thing on shops;min_gmv_30dyingresos mínimosare aliases on creators/shops. The filters reference lists the canonical name and aliases per entity. undefinedcadenas. A few client SDKs serialize undefined values as the literal«sin definir»— the server strips these out, so a missing filter won't crash, but it also won't apply anything. Check the request your client actually sent.
"I'm calling /api/tiktok-shop/... and getting redirected to /login"
That path is the session route — it requires browser cookies. With an API key you must call /api/v1/tiktok-shop/... en su lugar.
| Superficie | Autor |
|---|---|
/api/v1/tiktok-shop/* |
Clave API |
/api/tiktok-shop/* |
Logged-in session |
"My team can't use my key"
Each teammate can create a key from /api while signed in. Usage follows your organization’s rules in the product—if someone still gets 403, have your admin verify plan and API access for that seat.
Sanity-checking your integration
Run this checklist when something doesn't add up:
- Auth:
curl -i -H "X-API-Key: $WH_API_KEY" {origin}/api/v1/tiktok-shop/creditsdevoluciones200. - Plan: the account shows API access in the dashboard (plan / billing).
- Quota: el
credits.remainingfrom above is > 0. - Rate: you are not running more than ~50/min — leave 10/min of headroom.
- Path: the URL is in the API reference or the matching topic guide.
- Verb: GET vs POST matches the docs.
- Filters: dates use the correct mechanism per Time windows; filter names use the canonical / alias forms documented per entity.
If all seven pass and behavior still looks wrong, capture a request/response pair (with the key redacted) and send it to support.