Troubleshooting
Find and fix common integration problems, from authentication to browser data to retries.
Start with the evaluation itself. Open it in Evaluations in the dashboard, or read it with GET /v1/evaluations/{id}. The evaluation shows which inputs it received, the browser data status, the policy version it ran under and the reason for its result. Most integration problems are visible there.
Every response carries an X-Request-ID header, and every error repeats it as request_id. Record it with your own logs for every failed request. Evaluation requests appear in request logs (GET /v1/request-logs, or abusezero request-logs list with the AbuseZero CLI), including failed ones with their status and error code, with the X-Request-ID as the log ID after req_. Requests that never authenticated and rate-limited requests aren't logged.
Authentication and access
Requests fail with INVALID_API_KEY or API_KEY_EXPIRED (401)
Check: the key in your server's environment is complete and current. Keys start with sk_ or rk_ and are sent as Authorization: Bearer <key>.
Fix: if the key was revoked or has expired, create a new one in Developers → API keys and replace it. A key's expiry can't be extended. See Secret and restricted keys and authentication errors.
Requests fail with KEY_PERMISSION_DENIED (403)
Check: the message names the scope the request needs. Restricted keys carry only the scopes chosen for them.
Fix: add the scope to the restricted key in Developers → API keys, or use a key that has it. See Scopes for the scope each endpoint needs, and permission errors.
Requests fail with KEY_TYPE_NOT_ALLOWED (403)
Check: a publishable key (pk_) was sent to a server endpoint.
Fix: publishable keys work only for browser collection. Use a secret or restricted key on your server. See Choosing a credential.
OAuth requests fail with WORKSPACE_REQUIRED or WORKSPACE_ACCESS_DENIED (403)
Check: requests made with an OAuth token must name a workspace in the AbuseZero-Workspace header, using a ws_ ID the token can access.
OAuth requests fail with OAUTH_SCOPE_REQUIRED or PERMISSION_REQUIRED (403)
Check: the app wasn't granted the scope the request needs, or the signed-in member's role doesn't allow the action.
Fix: sign in again and approve the scope, or ask the workspace owner for the permission. See Member permissions for OAuth.
Requests fail with ONBOARDING_REQUIRED (403)
Fix: the workspace owner needs to finish setting up the workspace in the dashboard.
Evaluation requests
BENEFIT_NOT_FOUND (404)
Check: benefit must be the key of a benefit in this workspace, such as pro_trial. It is not the benefit's ben_ ID.
Fix: copy the key from Benefits, or list benefits with GET /v1/benefits. See not-found errors.
INVALID_FIELD, UNSUPPORTED_FIELD or MALFORMED_JSON
Check: field in the error names the field. UNSUPPORTED_FIELD means the request contains a field the endpoint doesn't accept. MALFORMED_JSON means the body isn't valid JSON, or Content-Type: application/json is missing.
Fix: compare the request with Create an evaluation and the invalid request errors. When the field is a custom identifier, register its key and key version first, in Developers → Custom identifiers or with POST /v1/custom-identifiers.
IP_NOT_ROUTABLE (422)
Check: context.ip is a private, loopback, documentation or other non-routable address, such as your own server's or a load balancer's.
Fix: send the visitor's public IP address from your proxy's forwarded headers, or leave context.ip out. See Send the IP address.
IDEMPOTENCY_KEY_REQUIRED (422)
Fix: every write needs an Idempotency-Key header of 1 to 128 printable characters with no spaces. Use a value tied to the attempt, such as evaluate-<claim ID>, so a retry sends the same key.
IDEMPOTENCY_CONFLICT (409)
Check: the same idempotency key was sent with a different request body.
Fix: a retry must send the original body with the original key. A new evaluation needs a new key. See conflict errors.
CLAIM_CONFLICT (409)
Check: the claim ID was already used for a different user.
Fix: a claim ID identifies one award to one user. Use a new claim ID for each award, such as the ID of the trial or credit grant in your system. See Re-evaluating a claim_id.
CLAIM_PERIOD_ENDED (409)
Check: the benefit's eligibility resets by period, and this claim ID belongs to an earlier period.
Fix: use a new claim ID for the new period's award.
BOT_EVIDENCE_REQUIRED (422)
Check: the benefit requires a bot check, and the evaluation didn't carry a usable one in identifiers.device_token.
Fix: call prepareBotObservation when the person submits, and send its deviceToken in the evaluation within 2 minutes. See Add a bot check.
AGENT_EVIDENCE_OUTDATED (422)
Check: agent_evidence came from a version of the AbuseZero Node.js SDK before 0.11.0.
Fix: update the abusezero package to 0.11.0 or later, and send the opaque token verifyAgentRequest() returns, unchanged. See Verify AI agents.
Evaluations return "status": "skipped"
No result was decided, and your outage setting doesn't apply. See Skipped evaluations.
reason | What to do |
|---|---|
insufficient_credits | The workspace owner adds credits or changes plan in Workspace settings → Billing & Subscriptions. |
billing_overdue | The workspace owner settles the overdue payment in Workspace settings → Billing & Subscriptions. |
benefit_paused | The workspace is over its plan's limits. The owner reduces usage or changes plan. |
service_inactive | The workspace can't run evaluations right now, for example while it's being deleted. |
Decide in advance what your application does with a skipped claim. See Handle skipped evaluations.
Browser data
Evaluations show inputs.device: missing or browser_data: not_sent
Check: the evaluation didn't include identifiers.device_token.
Fix: pass the deviceToken from observe or prepareBotObservation to your server, then send it unchanged as identifiers.device_token. Send it whatever its status. When there's no browser data, it carries the reason. See Send the device token with the evaluation.
browser_data shows one of these statuses
| Status | What it means | Fix |
|---|---|---|
collected | Browser data reached the evaluation. | Nothing to fix. |
not_passed_on | The browser collected data for this claim, but your server didn't send its device token. | Pass deviceToken through to identifiers.device_token. |
site_not_listed | The page isn't in your site list. | Add the site in Developers → Browser setup. Only HTTPS sites are accepted. |
sdk_outdated | The page runs a browser SDK version that's no longer supported. | Update the abusezero package or the standalone script address. |
expired | The device token reached the evaluation too late. | Send the token in the evaluation soon after the browser returns it. |
not_loaded | Your consent tool kept the script from loading, and you reported it. | Nothing to fix. |
consent_declined | The visitor declined consent. | Nothing to fix. |
blocked, timed_out, failed | The browser couldn't complete collection, for example because of a blocker or a poor connection. | Nothing to fix for a single evaluation. If it happens often, check Developers → Browser setup. |
The evaluation still runs in every case. It uses everything else it received. See Browser data statuses.
Browser setup shows script_missing
Check: AbuseZero hasn't heard from the AbuseZero browser SDK on any of your sites recently, while evaluations are still arriving.
Fix: confirm that init runs on every page that leads to a claim, with your publishable key, and that the page is in your site list. If your site sets a Content Security Policy, copy the sources shown in Developers → Browser setup into it. See Browser setup issues.
Results
Unexpected denials
- Read
reasonon the evaluation. Reason codes explains each one and what you can do. - Check the policy version the evaluation ran under. A recent policy change may have decided it.
- Check
inputs. A missing input changes what AbuseZero can see. - For a prior-claim reason, open the evaluation's association graph to see the earlier outcomes behind it.
- To let this person through, add an allow list entry.
- To change how the benefit treats claims like this, adjust its protection level or custom rules, and test against past traffic before you save.
To review results without affecting any user, put the benefit in observe mode.
previously_authorized on a repeat claim
Check: the same claim ID was evaluated again for the same user. See Repeat requests.
Fix: nothing, if it's a retry of the same award. A new award needs a new claim ID.
Outcomes
Reporting an outcome fails with OUTCOME_CONFLICT (409)
Check: the message says why. A denied evaluation can't be confirmed as granted. A newer evaluation may have replaced this one. The change may not be one the outcome's current state accepts, such as reversing an outcome reported as not_granted. Or the external_outcome_id already belongs to another outcome.
Fix: report against the claim's most recent allowed evaluation, with a change its current state accepts. See allowed changes for the accepted changes and Report outcomes.
An evaluation fails with OUTCOME_CONFLICT (409)
Check: the benefit reports outcomes, and an earlier evaluation of this claim ID passed its due_at without a report.
Fix: report that claim's outcome first, with POST /v1/evaluations/{id}/outcome, then evaluate again.
REASON_REQUIRED (422)
Fix: reporting not_granted or reversed needs a reason of 3 to 500 characters. See invalid request errors.
Retries and availability
RATE_LIMITED (429)
Fix: wait for the number of seconds in the Retry-After header, then retry with the same idempotency key. Limits depend on your plan. The AbuseZero Node.js SDK never turns a rate limit into a local allow or deny. See Rate limits and rate limit errors.
TEMPORARILY_UNAVAILABLE (503), DEADLINE_EXCEEDED (504) or EVALUATION_PENDING (409)
Fix: these errors are retryable (retryable: true). Retry with the same idempotency key. AbuseZero returns the original result if the first attempt finished. See unavailable errors and Retry retryable errors.
CURSOR_INVALID (422)
Fix: a page cursor was changed or belongs to another list. Pass next_cursor back exactly as you received it, or start again from the first page. See Pagination.
Contacting support
Include the X-Request-ID of the request, the evaluation ID if there is one, and the time it happened. Never send secret keys or client secrets.
Related
How is this guide?
Last updated on