AbuseZero

AbuseZero REST API

Base URL, versioning, authentication and the conventions shared by every AbuseZero REST API endpoint.

The AbuseZero REST API is a JSON API over HTTPS. One evaluation call decides a benefit claim. The rest of the API configures benefits and policies, records outcomes, and shows what AbuseZero decided and why.

Every endpoint on these pages follows the conventions below.

REST API base URL

https://api.abusezero.com

Every path starts with the API version, /v1. All requests use HTTPS.

REST API versioning

The current version is v1. Within v1, AbuseZero only makes additive changes:

  • new endpoints;
  • new optional request fields;
  • new response fields;
  • new values for codes and enums, such as reason codes, skip reasons and error codes.

Write your integration so it ignores fields it doesn't recognize and handles unknown enum values as a generic case. Breaking changes ship only in a new version.

Authentication

Send a secret key, a restricted key or an OAuth access token as a bearer token:

Authorization: Bearer <credential>

Requests with an OAuth access token also choose a workspace with the AbuseZero-Workspace header. See REST API authentication for credential types, scopes and permissions.

The Node.js samples on these pages call a client named abusezero, created from abusezero/server as shown in Authentication.

Requests

  • Send request bodies as JSON with Content-Type: application/json. A write that takes no fields, such as a delete or an import step, can send {} or no body at all.
  • GET endpoints take their parameters in the query string.
  • Path parameters are the prefixed IDs AbuseZero returned, such as eval_… or ben_….
  • Request bodies are limited to 16 KiB for evaluations and outcome reports, 1 MiB for imports sent as JSON, and 256 KiB for every other endpoint. A larger body returns PAYLOAD_TOO_LARGE.
  • A request that includes a field the endpoint doesn't define is rejected with UNSUPPORTED_FIELD or INVALID_FIELD.

Responses

Every successful response is a JSON object with an object field that names its type, such as evaluation, benefit or list.

StatusWhen
200Reads, updates, deletions, evaluations and outcome reports.
201Other POST requests that create or run something, such as a benefit, policy, preview or replay.
202Accepted work that finishes in the background: imports, exports and data deletions. Their response includes the ID to check later.

Timestamps are ISO 8601 strings in UTC, such as 2026-10-29T14:05:12.000Z. Responses are never cached.

Object IDs

Every object ID carries a type prefix. Send IDs back exactly as you received them.

PrefixObject
eval_Evaluation
ben_Benefit
pol_Policy
out_Outcome
lst_Allow or block list entry
cid_Custom identifier
imp_Import
exp_Export
del_Data deletion
req_Request log
aud_Audit event
ws_Workspace

An ID with the wrong prefix for an endpoint is rejected with INVALID_FIELD.

Idempotency

Every write requires an Idempotency-Key header. Writes are POST requests that create or change something, and every PATCH and DELETE.

Idempotency-Key: 0b8f5c1e-4d2a-4c7b-9e3f-6a1d8b2c5e70
  • Use 1 to 128 printable characters with no spaces. A UUID works well.
  • Create one key per attempt and reuse it for every retry of that attempt.
  • A retry with the same key and the same body returns the original response instead of repeating the write. A claim is never evaluated or recorded twice, a CSV import is never created twice, and a delete that already succeeded returns its original response. A retried CSV import returns a fresh upload link.
  • The same key with a different body returns IDEMPOTENCY_CONFLICT.
  • A write without a key returns IDEMPOTENCY_KEY_REQUIRED.

Each endpoint's page says whether it needs the header.

Pagination

List endpoints return one page at a time.

ParameterTypeDescription
limitinteger, 1 to 100Items per page. Defaults to 50.
cursorstringThe next_cursor from the previous page. Leave it out for the first page.
{
  "object": "list",
  "data": [],
  "next_cursor": null
}

next_cursor is null on the last page. Cursors are sealed and bound to your workspace and to the list they came from. Pass them back unchanged. A changed cursor, or one from another list, returns CURSOR_INVALID.

Rate limits

Traffic limits depend on your plan. When a request goes over a limit, AbuseZero returns 429 with the code RATE_LIMITED and a Retry-After header that gives the wait in seconds. Wait that long, then retry with the same Idempotency-Key.

Previews and Test console runs have their own limit, separate from evaluations.

The Node.js SDK never turns a rate limit into a local allow or deny, so traffic spikes can't switch protection off.

Request IDs

Every response includes an X-Request-ID header. Error responses repeat it in the body as request_id. Include it when you contact support about a specific request.

Time limits

Every endpoint runs within a fixed time limit. An evaluation that can't finish in time returns DEADLINE_EXCEEDED with retryable: true. Retry it with the same Idempotency-Key: if the first attempt finished, you get its result.

Errors

Errors use one envelope across the whole API:

{
  "error": {
    "type": "invalid_request",
    "code": "CURSOR_INVALID",
    "message": "Clear the page cursor and try again.",
    "field": "cursor",
    "retryable": false
  },
  "request_id": "7d0e5c2a-1f4b-4e8a-b6c3-9a2d5e0f1b74"
}

See REST API errors for every type and code.

Resources

How is this guide?

Last updated on

On this page