AbuseZero

REST API errors

The AbuseZero REST API error envelope, error types and every error code.

Every error from the AbuseZero REST API uses the same envelope, on every endpoint. Your code can branch on type, act on code, and show message to your team.

Error envelope

{
  "error": {
    "type": "conflict",
    "code": "IDEMPOTENCY_CONFLICT",
    "message": "Use the original payload with this key, or a new key for a new evaluation.",
    "retryable": false
  },
  "request_id": "7d0e5c2a-1f4b-4e8a-b6c3-9a2d5e0f1b74"
}
FieldTypeDescription
error.typestringThe error's category. See Error types.
error.codestringA stable, machine-readable code. Codes never change meaning within v1.
error.messagestringA readable explanation with the next step. Messages can be reworded at any time, so don't parse them.
error.fieldstringThe request field that caused the error, as a dotted path such as identifiers.device_token. Present only when one field caused it.
error.retryablebooleantrue when the same request can succeed if you retry it unchanged.
request_idstringThe request's ID. It matches the X-Request-ID response header.

Error types

typeHTTP statusMeaning
invalid_request400, 413, 422The request can't be accepted as sent. Fix it before retrying.
authentication401The credential is missing, invalid or expired.
permission403The credential is valid but can't do this.
not_found404, 410The endpoint or object doesn't exist in this workspace, or is no longer available.
conflict409The request conflicts with the current state of an object.
rate_limit429The request went over a traffic limit.
unavailable503, 504AbuseZero couldn't finish the request. Retry it.

New codes can be added within v1. Handle an unknown code by its type.

Handling errors

  • retryable: true: retry the same request with the same Idempotency-Key. Back off between attempts. When the response has a Retry-After header, wait that many seconds first.
  • invalid_request: fix the request. Retrying it unchanged returns the same error.
  • authentication and permission: fix the credential, its scopes or the member's permissions.
  • conflict: read the object's current state, then decide what to send.
  • Evaluations: never treat an error as an allow. Use the Node.js SDK's outage setting to decide what your code receives when AbuseZero can't be reached. See Handle outages and retries.
import { AbuseZero, AbuseZeroError, type EvaluationRequest } from "abusezero/server";

const abusezero = new AbuseZero({
  key: process.env.ABUSEZERO_SECRET_KEY!,
  outage: "throw",
});

export async function evaluateClaim(request: EvaluationRequest, idempotencyKey: string) {
  try {
    return await abusezero.evaluate(request, idempotencyKey);
  } catch (error) {
    if (error instanceof AbuseZeroError) {
      console.error(error.code, error.message, error.requestId);
      if (error.retryable) {
        // Retry later with the same idempotency key.
      }
    }
    throw error;
  }
}

Error codes

Invalid request

StatusCodeMeaningWhat to do
400MALFORMED_JSONThe body isn't valid JSON, or isn't sent as JSON.Send a JSON object with Content-Type: application/json.
413PAYLOAD_TOO_LARGEThe body is over the size limit.Keep the body under the limit given in the message.
422INVALID_FIELDA field is missing or has an invalid value.Fix the field named in error.field.
422UNSUPPORTED_FIELDThe request includes a field the endpoint doesn't define, a rule uses an unsupported condition, or a custom identifier isn't registered.Remove the field, choose a supported condition, or register the custom identifier and key version in Developers → Custom identifiers first.
422IDEMPOTENCY_KEY_REQUIREDA write was sent without a valid Idempotency-Key header.Send 1 to 128 printable characters with no spaces.
422CURSOR_INVALIDThe page cursor was changed, or belongs to another list or workspace.Clear the cursor and request the first page again.
422INVALID_EMAILAn email address isn't in a supported form. Quoted and international local parts aren't supported. field names where it was sent: subject.email on an evaluation, value on an allow or block list.Send an address such as name@example.com.
422INVALID_IPAn IP address isn't a valid IPv4 or IPv6 address. field names where it was sent: context.ip on an evaluation, value on an allow or block list.Send a valid address, or leave the IP out.
422IP_NOT_ROUTABLEcontext.ip is a private, loopback, documentation or other non-routable address.Send the user's public IP address, or leave the IP out.
422DEVICE_TOKEN_INVALIDidentifiers.device_token isn't a value the browser SDK returned.Send the browser SDK's deviceToken unchanged, or unavailable:not_loaded when your consent tool kept the script from loading.
422DEVICE_TOKEN_SCOPEThe device token was collected for a different claim_id.Collect browser data with the same claim ID you evaluate.
422BROWSER_SDK_UPGRADE_REQUIREDThe device token came from an outdated browser SDK.Update the browser SDK and collect new browser data.
422BOT_EVIDENCE_REQUIREDThe benefit requires a bot check, and the evaluation has none that can be used.Collect browser data with prepareBotObservation when the person submits, and evaluate within 2 minutes.
422AGENT_EVIDENCE_SCOPEagent_evidence was produced for a different claim.Verify the agent's request with this evaluation's claim ID.
422AGENT_EVIDENCE_OUTDATEDagent_evidence came from a Node.js SDK before 0.11.0.Update the Node.js SDK to 0.11.0 or later and send the token verifyAgentRequest() returns, unchanged.
422REASON_REQUIREDA not_granted or reversed outcome report has no reason.Add a reason of 3 to 500 characters.
422POLICY_NOT_FOUNDA benefit names a policy key that doesn't exist, or a policy builds on an unavailable protection level.Choose an existing policy key or protection level.
422ORIGIN_NOT_ALLOWEDA site in your site list isn't HTTPS.List only HTTPS sites.
422INVALID_DOMAINA list entry's domain isn't valid. field is value.Use a domain such as example.com.
422INVALID_TIMEZONEA benefit's calendar eligibility names a time zone AbuseZero doesn't recognize. field is config.eligibility.timezone.Use an IANA time zone such as America/New_York.

Authentication

StatusCodeMeaningWhat to do
401AUTHENTICATION_REQUIREDThe request has no credential.Send Authorization: Bearer with a key or access token.
401INVALID_API_KEYThe key is unknown or revoked.Create a new key in Developers.
401API_KEY_EXPIREDThe key passed its expiry.Create a new key in Developers and replace the old one.
401INVALID_ACCESS_TOKENThe OAuth access token is invalid or expired. A value that isn't a complete API key is read as an access token.Sign in again, then retry. If you meant to send an API key, check that it was copied in full.

Permission

StatusCodeMeaningWhat to do
403KEY_TYPE_NOT_ALLOWEDThe wrong kind of key was used: a publishable key on a server endpoint, or a server key in the browser.Use a secret or restricted key on your server, and the publishable key in the browser.
403KEY_PERMISSION_DENIEDThe API key lacks the endpoint's scope.Use a key with the scope named in the message.
403OAUTH_SCOPE_REQUIREDThe access token lacks the endpoint's scope.Authorize the scope named in the message.
403WORKSPACE_REQUIREDAn OAuth request has no valid AbuseZero-Workspace header.Send a ws_ ID from GET /v1/workspaces.
403WORKSPACE_ACCESS_DENIEDThe credential can't reach that workspace.Choose a workspace the credential belongs to.
403PERMISSION_REQUIREDThe signed-in member lacks a permission the scope needs.Ask the workspace owner for the permission.
403EVIDENCE_SCOPE_REQUIREDAn export with evidence needs the evaluation_evidence:read scope.Add the scope, or export without evidence.
403ONBOARDING_REQUIREDThe workspace hasn't finished setup.Ask the workspace owner to finish onboarding in the dashboard.
403ORIGIN_NOT_REGISTEREDThe browser SDK ran on a site that isn't in your site list.Add the site in Developers → Browser setup. Only HTTPS sites can send browser data.
403WORKSPACE_DELETION_EXCLUDEDA data deletion tried to delete the whole workspace.Delete workspaces in the dashboard.

Not found

StatusCodeMeaningWhat to do
404ENDPOINT_NOT_FOUNDNo endpoint matches the method and path.Check the method and path.
404RESOURCE_NOT_FOUNDNo object with this ID exists in the workspace.Check the ID and the workspace.
404EVALUATION_NOT_FOUNDNo evaluation with this ID exists in the workspace.Check the evaluation ID.
404BENEFIT_NOT_FOUNDNo benefit with this key or ID exists in the workspace.Check the benefit key or ID, or create the benefit.
404POLICY_NOT_FOUNDNo policy with this ID or key exists in the workspace.Check the policy ID or key.
404POLICY_VERSION_NOT_FOUNDThe policy has no such version.List the policy's versions and choose one.
404IDENTIFIER_NOT_FOUNDNo custom identifier with this ID exists.Check the custom identifier's ID.
404IMPORT_NOT_FOUNDNo import with this ID exists in the workspace.Check the import ID.
404EXPORT_NOT_FOUNDThe export doesn't exist or has expired.Request a new export.
410IMPORT_REPORT_EXPIREDThe import's error report is no longer available.Upload the corrected CSV again.

Conflict

StatusCodeMeaningWhat to do
409IDEMPOTENCY_CONFLICTThe Idempotency-Key was already used with a different body.Send the original body again with this key, or use a new key for a new request.
409EVALUATION_PENDINGAn evaluation with this key is still running.Retry with the same Idempotency-Key.
409CLAIM_CONFLICTThe claim_id already belongs to a different user.Use a new claim ID for a different award.
409CLAIM_PERIOD_ENDEDThe claim_id belongs to an earlier eligibility period.Use a new claim ID for the new period's award.
409OUTCOME_ALREADY_RECORDEDAn imported outcome already exists for this claim.Reconcile the claim in your application.
409OUTCOME_CONFLICTThe outcome can't move to the requested state, the evaluation was denied or replaced, the claim's earlier approval expired, or the external outcome ID belongs elsewhere.Read the evaluation and outcome, then report the correct state. See Outcomes.
409DEVICE_TOKEN_USEDThe device token was already used for another claim.Collect new browser data for this claim.
409DELETION_IN_PROGRESSThe user's history, or the workspace, is being deleted.Retry after the deletion finishes.
409POLICY_UNAVAILABLEThe benefit's policy isn't available.Assign an available policy to the benefit.
409BENEFIT_CONFLICTThe benefit changed since you read it.Read the benefit again and send its current revision.
409BENEFIT_SCOPE_FIXEDThe update changes the benefit's eligibility.Create a separate benefit for a different eligibility period.
409POLICY_CONFLICTThe policy changed since you read it.Read the policy again and send its current revision.
409BENEFIT_KEY_TAKENAnother benefit already uses this key. field is key.Choose a different benefit key.
409POLICY_KEY_TAKENAnother policy already uses this key.Choose a different key.
409POLICY_IN_USEBenefits still use the policy.Move those benefits to another policy first.
409PROTECTION_LEVEL_READ_ONLYProtection levels can't be edited or deleted.Duplicate the level and change the copy.
409IDENTIFIER_ALREADY_REGISTEREDThis custom identifier key and key version are already registered. field is key_version.Register a new key version.
409IDENTIFIER_IN_USEA policy still uses the custom identifier.Remove it from your policies first.
409REVISION_CONFLICTYour site list changed since you read it.Read browser setup again and send its current revision.
409EXPORT_NOT_READYThe export hasn't finished.Wait until its state is complete, then download it.
409IMPORT_STATEThe import isn't in a state that allows this step.Read the import and follow its current state.
409IMPORT_NOT_UPLOADEDValidation was requested before the CSV file was uploaded.Upload the file to the import's upload URL, then validate.
409IMPORT_COMPLETEThe import already finished, so it can't be cancelled.To remove its history, delete the affected users' data.
409IMPORTS_IN_PROGRESSActive imports block a data deletion.Finish or cancel them first.

Rate limit

StatusCodeMeaningWhat to do
429RATE_LIMITEDThe request went over a traffic limit.Wait for the number of seconds in Retry-After, then retry with the same Idempotency-Key.

Unavailable

StatusCodeMeaningWhat to do
503TEMPORARILY_UNAVAILABLEAbuseZero couldn't finish the request.Retry with the same Idempotency-Key.
503LIMIT_CONFIGURATION_UNAVAILABLEAbuseZero couldn't confirm the workspace's traffic limits.Retry shortly.
503BOT_EVIDENCE_UNAVAILABLEThe bot check couldn't be completed for this evaluation.Collect new browser data with prepareBotObservation, then retry.
504DEADLINE_EXCEEDEDThe request reached its time limit.Retry with the same Idempotency-Key. If the first attempt finished, you get its result.

Skipped evaluations are not errors

When a workspace can't run an evaluation, for example because it has run out of credits, POST /v1/evaluations returns 200 with status: "skipped" instead of an error. No allow or deny was decided. See Evaluations.

How is this guide?

Last updated on

On this page