API documentation
The Harm Watch provides a read-only JSON API for approved organisations. Access is granted per organisation — apply here.
Authentication
Include your API key as a Bearer token in every request:
Authorization: Bearer hw_live_your_key_here
Keys are issued by your organisation admin from the API keys page. A revoked or expired key returns 401.
Rate limits
Default: 1,000 requests per hour per key. Every response includes:
X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 998 X-RateLimit-Reset: 1722614400 # Unix timestamp
Exceeding the limit returns 429 Too Many Requests with a Retry-After header.
Endpoints
https://www.harm.watch/api/v1/submissionsPaginated list of submissions. Defaults to status=live.
Query parameters
statuslive (default). Comma-separated for multiple: live,pending_reviewcategoryFilter by category slug, e.g. frauddescriptorFilter by descriptor slugdomainExact domain match, e.g. example.comsinceISO 8601 date — only records with last_reported_at after thiscursorOpaque pagination cursor from next_cursor in prior responselimitRecords per page, default 100, max 500Response
{
"data": [
{
"id": "uuid",
"url": "https://example.com/path",
"domain": "example.com",
"status": "live",
"categories": ["fraud", "impersonation"],
"descriptors": ["targets-children"],
"report_count": 7,
"first_reported_at": "2026-01-04T09:12:00Z",
"last_reported_at": "2026-02-11T18:40:00Z",
"status_changed_at": null
}
],
"next_cursor": "eyJ0cyI6...",
"has_more": true
}https://www.harm.watch/api/v1/submissions/:idSingle submission by UUID. Same shape as a list item.
Returns 404 if not found.
https://www.harm.watch/api/v1/tagsActive harm taxonomy — categories and descriptors. Use this to map slugs to human-readable labels.
{
"data": [
{
"id": "uuid",
"slug": "fraud",
"label": "Fraud, scams, and financial crime",
"kind": "category",
"description": null,
"parent_id": null,
"sort_order": 1
}
]
}Errors
All errors use a consistent envelope:
{
"error": {
"code": "rate_limited",
"message": "You have exceeded your rate limit. Try again after the Retry-After period."
}
}401unauthorizedMissing, invalid, or revoked API key403forbiddenAPI access not enabled for this organisation404not_foundResource not found429rate_limitedRate limit exceeded500server_errorInternal error — please try againData notice
All records are allegations by members of the public, not confirmed findings. Never characterise a submission as proven, confirmed, or illegal. Reporter data (email addresses, report text, IP information) is never returned by the API.