Report a banned user
Report users you banned to the Shared Registry, list your reports, and revoke them
When your team bans a user for a registry category, report the user so that
other members can stop them signing up again. Reporting needs a key with the registry:submit scope
and a membership that includes the category.
Before you report#
- A person on your team reviewed the evidence and upheld the ban.
- The ban is for
payment_fraud,prohibited_contentorban_evasion, and your membership allows that category. - You keep the evidence under a case reference in your own system.
Send a report#
POST /api/v1/registry/entries
| Field | Type | Description |
|---|---|---|
identifier |
object | { "type": "email", "sha256": "<digest>" }. See Hash an email. |
category |
string | payment_fraud, prohibited_content or ban_evasion. |
member_case_ref |
string | Your own case or ticket ID, 1 to 200 characters. Never put personal data or content details in it. |
attest_human_review |
boolean | Must be true. Confirms that a person reviewed the evidence and upheld the ban. |
curl -X POST https://api.omnifence.ai/api/v1/registry/entries \
-H "Authorization: Bearer $OMNIFENCE_REGISTRY_KEY" \
-H "Content-Type: application/json" \
-d '{
"identifier": { "type": "email", "sha256": "d6117306485ed0e50afab3ac871e98f81699151f30281527d63ff5f233656c69" },
"category": "payment_fraud",
"member_case_ref": "TS-48213",
"attest_human_review": true
}'
import { registryDigest } from './registry-hash.mjs';
export async function reportToRegistry({ email, category, caseRef }) {
const sha256 = registryDigest(email);
if (sha256 === null) return null;
const response = await fetch('https://api.omnifence.ai/api/v1/registry/entries', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.OMNIFENCE_REGISTRY_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier: { type: 'email', sha256 },
category,
member_case_ref: caseRef,
attest_human_review: true,
}),
});
if (!response.ok) {
const body = await response.json().catch(() => ({}));
throw new Error(`Registry report failed: ${response.status} ${body.error ?? ''}`.trim());
}
return response.json(); // the entry: store entry_id with your case
}
The response#
The API returns the entry. The status code tells you whether the entry is new:
| Status | Meaning |
|---|---|
201 Created |
A new entry. |
200 OK |
You already reported this identifier in this category. The registry refreshed that entry. |
{
"entry_id": "4f01b81e-6ccb-4cb4-8dcc-b5e9b52bf72a",
"identifier_type": "email",
"category": "payment_fraud",
"member_case_ref": "TS-48213",
"status": "active",
"has_open_dispute": false,
"created_at": "2026-10-02T09:30:00.000Z",
"updated_at": "2026-10-02T09:30:00.000Z",
"expires_at": "2028-10-01T09:30:00.000Z",
"revoked_at": null,
"revoke_reason": null
}
Store entry_id with your case. You need it to revoke the report.
Refreshing a report#
When you report the same identifier in the same category again, the registry updates your existing
entry instead of creating a second one. It takes the new member_case_ref, restarts the retention
period, and reactivates the entry if it was revoked or expired. A refresh never ends an open dispute:
a disputed entry stays disputed until Omnifence resolves it.
Users with more than one email#
Report each email the user used, one request per email. Each becomes its own entry, and a check on any of them matches.
Ban evasion#
When a user you banned opens a new account to get around the ban, report the new account's email as
ban_evasion, and also report it in the original category. See
Ban evasion.
List your reports#
GET /api/v1/registry/entries returns the entries your account reported, newest first.
| Parameter | Description |
|---|---|
limit |
Entries per page, 1 to 200. Default 50. |
cursor |
Omit for the first page. For the next page, send the next_cursor of the last page. |
status |
Only entries with this status: active, disputed, revoked or expired. |
curl "https://api.omnifence.ai/api/v1/registry/entries?status=disputed&limit=100" \
-H "Authorization: Bearer $OMNIFENCE_REGISTRY_KEY"
{
"entries": [
{
"entry_id": "4f01b81e-6ccb-4cb4-8dcc-b5e9b52bf72a",
"identifier_type": "email",
"category": "payment_fraud",
"member_case_ref": "TS-48213",
"status": "disputed",
"has_open_dispute": true,
"created_at": "2026-10-02T09:30:00.000Z",
"updated_at": "2026-10-02T09:30:00.000Z",
"expires_at": "2028-10-01T09:30:00.000Z",
"revoked_at": null,
"revoke_reason": null
}
],
"next_cursor": null
}
next_cursor is null on the last page. The cursor is an opaque string: send it back unchanged,
and do not parse it or build one yourself. The list never includes the identifier hash, and it only
ever contains your own entries.
List your disputed entries regularly. A disputed entry means that the person named challenged
your report, and Omnifence will ask you for the evidence. See Disputes.
Revoke a report#
When you overturn a ban, on appeal or for any other reason, revoke the report at once. Other members may be refusing the person because of it.
POST /api/v1/registry/entries/{id}/revoke
| Field | Type | Description |
|---|---|---|
reason |
string | Why you revoked the report, 1 to 500 characters. |
curl -X POST https://api.omnifence.ai/api/v1/registry/entries/4f01b81e-6ccb-4cb4-8dcc-b5e9b52bf72a/revoke \
-H "Authorization: Bearer $OMNIFENCE_REGISTRY_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Ban overturned on appeal" }'
The API returns the entry with status revoked. The entry stops matching immediately, and any open
dispute on it closes. The entry is deleted 30 days later.
Revoking is safe to repeat: revoking an entry that is already revoked returns it unchanged with
200 OK. An entry that does not exist, or that another member reported, returns
404 NOT_FOUND.