AbuseZero

Custom identifiers

Add identifiers from your own business to AbuseZero's claim history, without ever sending their raw values.

Custom identifiers add identifiers from your own business to AbuseZero's claim history: a tax ID, a company registration number, a loyalty number, a hardware serial number. Anything that identifies one person or company in your product can become part of every evaluation.

Why it matters

The strongest link between two accounts is often something only your business knows. When a second account presents the same tax ID or the same hardware serial number as an earlier claim, that connection is decisive. Custom identifiers put that knowledge to work on every claim, next to the identifiers AbuseZero already checks.

Key capabilities

  • Raw values never leave your systems. You send each value as a keyed hash made with a secret only you hold. AbuseZero matches hashes against your claim history without ever receiving the value behind them.
  • Full history on every call. Each custom identifier is checked against the benefit's complete claim history on every evaluation, exactly like the built-in identifiers.
  • Conditions in custom rules. Every registered key becomes a condition you can use in your policies.
  • Key rotation built in. Each hash names the key version that made it, so you can introduce a new hashing secret without breaking requests in flight.
  • Strict registration. An evaluation that sends an unregistered key or key version is refused with UNSUPPORTED_FIELD before anything is recorded.

Register a key

Register each identifier once with POST /v1/custom-identifiers, or in the dashboard under Developers → Custom identifiers:

{
  "key": "tax_id",
  "key_version": "2026-10",
  "description": "Customer tax ID from the billing profile"
}
FieldValues
keyLowercase letters, digits and underscores, starting with a letter, up to 64 characters.
key_versionYour label for the hashing secret, 1 to 128 printable characters with no spaces.
descriptionWhat the identifier is, 3 to 200 characters.

Send it with an evaluation

Hash each value on your server with createCustomIdentifier from abusezero/server, and send the result in identifiers.custom. One evaluation can carry up to 10 custom identifiers.

Node.js
import { createCustomIdentifier } from "abusezero/server";

const evaluation = await abusezero.evaluate(
  {
    benefit: "pro_trial",
    claim_id: "signup_8f2d41",
    subject: { email: "jordan@example.com" },
    identifiers: {
      custom: [
        createCustomIdentifier({
          secret: process.env.ABUSEZERO_IDENTIFIER_SECRET!,
          keyVersion: "2026-10",
          key: "tax_id",
          value: taxId.trim().toUpperCase(),
        }),
      ],
    },
  },
  "claim:signup_8f2d41",
);

If your server doesn't run Node.js, compute the same hash yourself. Send identifiers gives the exact format.

  • Normalize before you hash. Trim spaces and use one letter case, the same way every time. A different input makes a different hash.
  • Keep the secret stable. Hashes made with different secrets never match. Earlier claims hashed with an old secret don't connect to claims hashed with a new one.
  • Rotate with a new version. Register the same key with a new key_version, then switch your hashing to it. Each key and key_version pair registers once: registering it again returns IDENTIFIER_ALREADY_REGISTERED.

Phone numbers travel as keyed hashes too, in identifiers.phone_hash, made with createPhoneHash. See Send identifiers.

Use it in rules

Each registered key adds a condition that counts earlier claims with that identifier:

{ "signal": "custom.tax_id.prior_outcomes", "operator": "gte", "value": 1 }

See Policies and rules. A custom identifier can't be deleted while a policy uses it.

Response data

{
  "object": "custom_identifier",
  "id": "cid_4d8a2f17-9c3e-4b60-a5d1-7e2b9f0c6a84",
  "key": "tax_id",
  "key_version": "2026-10",
  "description": "Customer tax ID from the billing profile",
  "created_at": "2026-10-20T13:05:00.000Z",
  "updated_at": "2026-10-20T13:05:00.000Z"
}

Programmatic access

Next steps

How is this guide?

Last updated on

On this page