Skip to main content

Errors

HTTP status codes

StatusMeaning
200Success
201Created (domain, payment)
204No content (logout, delete)
400Bad request
401Unauthorized
402Payment required — domain weight exhausted
403Forbidden
404Not found
409Conflict (e.g. email registered)
429Rate limit (login attempts, email cooldown)
500Internal server error
503REST gateway busy (concurrency limit)

Error response format

{ "error": "description of the problem" }
Pub API unauthorized: { "error": "invalid credentials" }

Common errors

401 Unauthorized (Dashboard)

JWT expired. Refresh:
POST https://account.shieldlabs.ai/api/auth/refresh
Returns { "token": "..." }. Refresh token is in HTTP-only cookie.

404 on domain endpoint

Use the domain’s UUID (id from GET /api/domains), not the hostname:
GET https://account.shieldlabs.ai/api/domains
PATCH https://account.shieldlabs.ai/api/domains/{uuid}

Webhook not received

  1. Endpoint returns 2xx within 1 second
  2. Endpoint is publicly reachable over HTTPS
  3. Webhook URL set via Dashboard or PUT /api/domains/{id}/webhook
  4. Domain has remaining weight (not 402)
  5. Check server logs for incoming POST

Score always 0

  • Legitimate clean session (residential IP, matching OS, STUN OK)
  • VPN 2-of-3 not triggered (only 1 signal)
  • Check CSP: connect-src blob: *.shieldlabs.ai, cdn.jsdelivr.net
  • Verify snippet loads without console errors

Two webhooks for one check

Normal when WebRTC completes — first Phase: "initial", then Phase: "update" with recalculated score. Handle both or prefer the update.