Errors and limits
Errors come in a single envelope shape; the status code says what happened. Lists are paginated and requests are rate limited.
Error envelope
Every failed response has the same shape:
{
"success": false,
"message": "Not found",
"error": { "type": "NotFoundError", "code": 404 }
}Another firm’s record returns 404 even if it exists; its existence is not leaked. A client error (invalid field, conflict) is 4xx, and internal server detail is not returned.
Responses
| Code | Meaning |
|---|---|
| 400 | Invalid request (malformed id, missing or invalid field) |
| 401 | Key missing, invalid, expired or revoked |
| 402 | The watched target limit of your tier is reached or your credit balance is too low; the target was not added |
| 403 | Insufficient scope, no API access in plan, or product not enabled |
| 404 | Record not found or not owned by this key’s firm |
| 408 | The request exceeded its maximum response time |
| 409 | A scan is already running for the firm; wait for it to finish |
| 429 | Rate limit exceeded; retry after a minute |
| 503 | Threat Investigation is temporarily unavailable; do not retry automatically, try again later yourself |
Rate limit
| Rate limit | Response limits |
|---|---|
| Rate limits and pagination | 500 requests per 15 min · per IP |
| Threat Investigation | 20 requests per 1 min · per firm |
Response limits
| Endpoints | Page size | default | max |
|---|---|---|---|
| GET /v1/leaks | limit | 50 | 100 |
| GET /v1/leaks/{reportId}/credentials | limit | 50 | 100 |
| GET /v1/leak-events | limit | 50 | 100 |
| GET /v1/scans | limit | 50 | 100 |
| GET /v1/scans/{scanId}/findings | limit | 50 | 100 |
| GET /v1/inventory | limit | 50 | 100 |
| GET /v1/analyses | limit | 25 | 100 |
| GET /v1/protection-resources | limit | 50 | 100 |
| GET /v1/requests | limit | 50 | 100 |
| GET /v1/webhooks/{groupId}/deliveries | limit | 100 | 100 |
| GET /v1/watch/assets | pageSize | 20 | 200 |
| GET /v1/watch/findings | pageSize | 20 | 200 |
| GET /v1/hunter/search | limit | 50 | 200 |
| GET /v1/hunter/audit | limit | 100 | 500 |
| GET /v1/hunter/targets | pageSize | 50 | 200 |
| GET /v1/hunter/findings | pageSize | 50 | 200 |
Retrying
On 429, wait a moment and try again. Do NOT retry Threat Investigation searches automatically: blind retries use up the per-minute limit.