Authentication
Watch-IP uses two key types depending on which endpoint you're calling — a browser-safe publishable key for client-side calls, and a server-only secret key for backend calls. Sending the wrong type returns 401 or 403, never a partial response.
Publishable keys (browser-safe)
Used for GET /v1/geo and POST /v1/email/validate — both designed to be called directly from a visitor's browser. Send it as the X-Api-Key header (GET /v1/geo also accepts a key query parameter as a fallback). It's not a secret: it ships in your page's JavaScript, and the control that matters is the allowed-origins list configured for the key, checked against the request's Origin/Referer header. A request from an origin not on that list gets a 403 with no CORS header set — the browser blocks the response before your code ever sees it, which is the actual enforcement, not the JSON error body.
Publishable key
curl https://api.watch-ip.com/v1/geo \
-H "X-Api-Key: YOUR_PUBLISHABLE_KEY"Secret keys (server-only)
Used for GET /v1/lookup/{ip}, POST /v1/lookup, and POST /v1/risk/check — all server-to-server endpoints with no browser Origin to check. Send it as Authorization: Bearer YOUR_SECRET_KEY from your own backend only; never embed a secret key in a page, mobile app bundle, or any client you don't control. Using a publishable key on a secret-key route, or a secret key on a publishable-key route, returns 403.
Secret key
curl https://api.watch-ip.com/v1/lookup/203.0.113.1 \
-H "Authorization: Bearer YOUR_SECRET_KEY"Rate limiting
Every key is rate-limited per customer account on a fixed one-minute window, shared across every endpoint you call rather than tracked per route. Exceeding it returns 429 — see errors and rate limits for the response shape and how to back off. The per-minute rate limit counts HTTP calls, not items: a batch of up to 100 IPs or email addresses is one request toward it, while each item still counts separately toward the monthly request cap.
Custom domains
Growth and Scale plans include a custom-domain setup path in the dashboard, so requests can go to a hostname on your own domain instead of api.watch-ip.com. Availability depends on account eligibility and successful DNS/SSL setup — point your integration at whichever base URL your dashboard confirms is active.