AbuseZero

Export and delete data

Export your evaluations to CSV, and permanently delete one user's claim history.

You can take your evaluation history out of AbuseZero at any time, and delete a single user's history when you need to. Both run in the background and report their progress. This guide covers both from the AbuseZero REST API and the AbuseZero Node.js SDK. In the dashboard, Export CSV on the Evaluations page exports the same file.

Before you begin

  • For exports, a server key with the scopes exports:create and exports:read. To include evidence columns, the key also needs evaluation_evidence:read.
  • For deletions, a server key with data_deletions:read and data_deletions:write.

Export your evaluations

Request the export

Request it with POST /v1/exports, abusezero exports create in the AbuseZero CLI, or abusezero_request_export on the AbuseZero MCP server. Choose how many days back to export, from 1 to 90. The default is 30.

import { abusezero } from "./lib/abusezero";

const requested = await abusezero.requestExport({ days: 30 }, "export-2026-10-29");
Response
{
  "object": "export",
  "id": "exp_5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
  "status": "pending",
  "status_url": "/v1/exports/exp_5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170"
}

An export holds up to 10,000 evaluations. When the range holds more, the export's state becomes failed and its failure.code is too_many_rows. Request a new export with fewer days.

Check export status

Read status_url (GET /v1/exports/{id}) until state is complete or failed. A failed export's failure says why; The export object lists every field.

curl https://api.abusezero.com/v1/exports/exp_5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170 \
  -H "Authorization: Bearer $ABUSEZERO_SECRET_KEY"
Response
{
  "object": "export",
  "id": "exp_5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
  "state": "complete",
  "rows": 4210,
  "include_evidence": false,
  "completed_at": "2026-10-29T15:22:09.000Z",
  "expires_at": "2026-10-30T15:21:58.000Z"
}

Download the file

Download the file before the export's expires_at. Ask for a download address with GET /v1/exports/{id}/download, here through the SDK's call(), then fetch the file from it straight away. The address is temporary. Request a new one if it expires.

import { writeFile } from "node:fs/promises";

const download = await abusezero.call(
  "/v1/exports/exp_5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170/download",
) as { url: string; expires_at: string };

const file = await fetch(download.url);
await writeFile("evaluations.csv", Buffer.from(await file.arrayBuffer()));

The file is a CSV with one row per evaluation (file columns):

ColumnValue
evaluation_idThe evaluation's ID (eval_…).
created_atWhen the evaluation ran.
benefitThe benefit's key.
resultallow or deny.
reason_code and reasonThe reason code and its message.
risk_score and risk_bandThe AbuseZero Risk Score and its band.
policy_versionThe policy version the evaluation ran under.
claim_idYour claim ID.
outcome_stateThe outcome's current state.

With include_evidence: true, the file adds one column per signal family (identity, device, network, automation and benefit_history) with its assessment, plus device_profile_status and device_profile_expires_at.

Delete a user's history

Deleting a user's history removes their claims and outcomes from your workspace. Because export files and uploaded import files can hold that user's data, the deletion also removes every export file and uploaded import file stored in the workspace. Afterwards, the user can qualify for your benefits again. Shared devices and networks that other users also used are kept.

A deletion is permanent and can't be undone. Preview it first.

Preview the deletion

Preview with POST /v1/data-deletions/preview, abusezero data-deletions preview in the AbuseZero CLI, or abusezero_preview_data_deletion on the AbuseZero MCP server. Identify the user the way your evaluations did, with a selector. If they sent subject.external_id, use that ID with email: false. If they sent only an email address, send the address as user with email: true.

const preview = await abusezero.previewDataDeletion({
  selector: { kind: "subject", user: "user_4821", email: false },
});
Response
{
  "object": "deletion_preview",
  "counts": { "claims": 3, "outcomes": 3, "files": 0 },
  "confirmation": "9b1f0c7e2a4d6b8f1e3c5a7d9b0f2e4c6a8d0b2f4e6c8a0d2b4f6e8c0a2d4b6f"
}

Check counts before you continue. files is the number of finished export files and uploaded import files the deletion removes.

Request the deletion

Send the same selector to request the deletion with POST /v1/data-deletions, abusezero data-deletions create, or abusezero_request_data_deletion.

const deletion = await abusezero.requestDataDeletion({
  selector: { kind: "subject", user: "user_4821", email: false },
}, "delete-user-4821");
Response
{
  "object": "deletion",
  "id": "del_0c9b8a7f-6e5d-4c3b-a291-807f6e5d4c3b",
  "status": "pending",
  "status_url": "/v1/data-deletions/del_0c9b8a7f-6e5d-4c3b-a291-807f6e5d4c3b"
}

A deletion can't start while an import is unfinished (IMPORTS_IN_PROGRESS) or while the same user's history is already being deleted (DELETION_IN_PROGRESS). Both are conflict errors. The API deletes users' histories only. The workspace owner deletes a whole workspace in the dashboard.

Check deletion status

Read status_url (GET /v1/data-deletions/{id}) until state is complete. While the deletion runs, new claims for that user return DELETION_IN_PROGRESS.

curl https://api.abusezero.com/v1/data-deletions/del_0c9b8a7f-6e5d-4c3b-a291-807f6e5d4c3b \
  -H "Authorization: Bearer $ABUSEZERO_SECRET_KEY"

Verify the result

  • The export's state is complete, and the CSV's row count matches rows.
  • The deletion's state is complete. A new preview for the same user returns zero claims and outcomes.

How is this guide?

Last updated on

On this page