Authentication
Every metered programmatic endpoint accepts a single API key, sent in one of three ways. This page covers where to get the key, how to send it, and how the server ties it to your account.
Sending your key
The server checks three locations, in this order. The first non-empty value wins.
| Where | Example | Notes |
|---|---|---|
X-API-Key header |
X-API-Key: wh_… |
Preferred. Case-insensitive header name. |
Authorization header |
Authorization: Bearer wh_… |
Standard Bearer scheme. Anything else (e.g. Basic) is ignored. |
api_key query param |
?api_key=wh_… |
Fallback only. Avoid it for anything sensitive — it ends up in URLs, server logs, browser history. |
curl -sS \
-H "X-API-Key: $WH_API_KEY" \
"{origin}/api/v1/tiktok-shop/credits"
curl -sS \
-H "Authorization: Bearer $WH_API_KEY" \
"{origin}/api/v1/tiktok-shop/credits"
curl -sS "{origin}/api/v1/tiktok-shop/credits?api_key=$WH_API_KEY"
All three are equivalent for routing; pick whichever is easiest in your HTTP client.
Where the key comes from
Keys are managed exclusively from the in-app API page:
GET /api— view your current key, copy it, regenerate it.POST /api/regenerate— programmatic regeneration (session login required).
A key looks like wh_ followed by 48 hex characters. Treat it like a password: it grants access to your full monthly API quota.
Regenerating
Regeneration is immediate and destructive. The previous key stops working the moment you regenerate, and any clients still using it will get 401 Unauthorized. Rotate when:
- You suspect a leak.
- A teammate or contractor with access leaves.
- You committed a key to source control by accident.
There is no expiry on a key otherwise — they keep working until you regenerate or your plan downgrades.
Plan requirement
Once a key resolves to an account, the server checks that API access is enabled for that account. If not, you receive HTTP 403 even when the key format is valid. Downgrades or cancellations can remove access immediately.
Team and organization accounts
Keys are issued per user. On team setups, usage and access follow your organization’s billing rules in the product—use the in-app API page and dashboard for the authoritative view for your seat.
Session vs API-key auth
WinningHunter routes split into three flavors. Make sure you are talking to the right one.
| Route prefix | Auth | When to use |
|---|---|---|
/api/v1/tiktok-shop/* |
API key (X-API-Key) |
All programmatic / external integrations. Goes through credits + rate limit. |
/api/tiktok-shop/*, /api/product-detail/*, etc. |
Logged-in browser session (cookies) | Used by the web app only. These are not the API-key surface — use /api/v1/tiktok-shop/* for integrations. |
/api/v1/adlibrary, /api/v1/magic-ai, /api/v1/store-tracker, /api/v1/store-explorer, /api/v1/brands |
API key | The non-TikTok programmatic surface. Same metering as /api/v1/tiktok-shop/*. The un-versioned /api/<x> forms are kept as backward-compat aliases for adlibrary, store-tracker, and store-explorer only — new integrations should call the v1 paths. /api/magic-ai and /api/brands (no v1) are dashboard session routes, not the API-key surface, because the dashboard pages still POST/GET those URLs; key clients must use /api/v1/magic-ai and /api/v1/brands. |
If you are writing a script or backend integration, you almost always want /api/v1/tiktok-shop/... plus the few non-TikTok routes above. The full surface is documented in the API reference and the topic guides (TikTok Shop, Meta ad library, Brands, etc.).
Verifying the key works
The cheapest way to smoke-test is GET /api/v1/tiktok-shop/credits — it returns the current credit balance and costs 1 credit:
curl -i \
-H "X-API-Key: $WH_API_KEY" \
"{origin}/api/v1/tiktok-shop/credits"
A 200 with JSON means: key valid, plan OK, rate limit and credits both healthy. Any other status, see Errors.
Security checklist
- Store keys in environment variables or a secure credential store — never in client-side code, mobile apps, or browser bundles.
- Use
X-API-KeyorAuthorization: Bearer, not the query param, whenever possible. - Rotate after any incident, on any team membership change, and at least once a year.
- Don't share keys between environments — generate one per service account and rotate independently.