Handle limits and errors
Know when to correct an input, wait and retry, or check workspace access.
Request sizes and pacing
| Limit | Value |
|---|---|
| JSON body | At most 1 MiB |
| Profiles per import | 1–100; report creation allows 0–100 |
| List page | Default 50, maximum 100 |
| Read requests per minute | Default 60 per key / 300 per workspace |
| Write requests per minute | Default 10 per key / 50 per workspace |
| Submitted profile rows per minute | Default 1,000 per workspace; shared by creation and imports |
Request ceilings are operational defaults and can vary by workspace. Validation previews count toward admission limits. On 429, wait for the response’s Retry-After delay before retrying. Use backoff with jitter for transient failures; retain the same idempotency key for writes.
Common responses
| HTTP | Meaning | Next action |
|---|---|---|
| 400 | Invalid query, cursor, JSON or retry key | Correct the request; keep collection filters unchanged when paging |
| 401 | Missing, invalid or inactive key | Check the credential and environment |
| 403 | Permission, subscription/trial eligibility or email verification denial | Follow next_action; correct account access before retrying |
| 404 | Resource is unavailable to this caller | Check the report/receipt/run ID and workspace |
| 405 | Unsupported method | Use the method in the reference |
| 409 | Retry conflict, archived report, inactive access or plan capacity/allowance limit | Read error.code and retryable; results_changed permits a bounded pagination restart |
| 410 | Receipt has expired | Reconcile the report before starting new work |
| 413 / 415 | Body too large / wrong content type | Reduce the batch / send application/json |
| 422 | Invalid report/profile batch or identity conflict | Correct the input; import error.details identifies rows |
| 429 | Admission limit reached | Respect Retry-After |
| 500 | Unexpected failure | Bounded retries with the same idempotency key; contact support if persistent |
| 503 | API access paused or not configured | Check configuration/access; do not retry automatically |
Analysis response limits and errors
Profile results default to 10/max 25 per page; activity defaults to 25/max 100. Pages stay below 2 MiB with complete records; cursors last 15 minutes. Screenshots support JPEG, PNG and WebP up to 10 MiB.
| HTTP / code | Next action |
|---|---|
| 409 results_changed | Retryable: discard unfinished pages and restart with bounded backoff |
| 404 evidence_unavailable | Not retryable: use text/source evidence or retrieve current references; contact support if unexpected |
| 422 result_too_large | Not retryable: one stored record is too large; contact support with request ID |
An awaiting-results or failed-scan state returns 200 when the read itself succeeds. Readiness, freshness and polling guide.
Keep the request ID
Responses include request_id and the matching X-Request-ID header. Errors include error.code, a readable message, error.retryable and error.next_action. Automate using the code and retryable flag; guidance text is for people. Share the request ID when requesting help; do not share your API secret. Validation errors additionally include safe row/field details.
{
"error": {
"code": "platform_subscription_or_trial_required",
"message": "Scanning is not authorized for this workspace’s current account access. No changes were made or scans queued.",
"retryable": false,
"next_action": "Ask a workspace owner or admin to review subscription/trial eligibility and account verification. If access should be active, contact support with request_id. Retry only after access is corrected."
},
"request_id": "77777777-7777-4777-8777-777777777777"
}{
"error": {
"code": "internal_error",
"message": "The request could not be completed.",
"retryable": true,
"next_action": "Retry with bounded exponential backoff and jitter. For writes, keep the same Idempotency-Key and request body. If failures persist, stop and contact support with request_id."
},
"request_id": "77777777-7777-4777-8777-777777777777"
}Account access and atomic writes
A 403 platform_subscription_or_trial_required means the current account is not authorized to queue scans. Ask an owner or admin to review subscription/trial eligibility and account verification. A 403 email_verification_required requires the owner to verify their work email. Existing plan/API permissions and capacity limits still apply; a payment alone does not guarantee that every access requirement is met.
When initial scan authorization fails, report creation saves no report or initial profiles. A failed profile addition saves no additions or restorations. Neither operation leaves partial scans or a successful retry receipt. After access is corrected, retry the same body with the same idempotency key.
When to retry
retryable: false means stop automatic retries and follow next_action. Account, permission, input, capacity and disabled-configuration failures require a change first. For retryable: true, limit attempts and use exponential backoff with jitter. Respect Retry-After on 429. For write requests, keep the same idempotency key and body even after a timeout or 500: a lost response can occur after a commit. Reconcile report data if the retry window has expired.
HTTP success and scan success
A 201 import can be followed by a failed scan. Customer usage displays request success separately from scan outcomes. A pause on new API work does not cancel work already admitted or disable ordinary product access.