Base URL: https://scamcrawl.com/api/v1. All read endpoints are unauthenticated and CORS-open for GET. Responses use { "data": … } on success and { "error": { "code", "message" } } on failure.
Authentication. Bearer token for the **private/admin** API. Keys look like `sk_<prefix8>_<secret>`; only the 8-char prefix and a SHA-256 of the key are stored, and the plaintext is shown exactly once at issuance. Roles are hierarchical: VIEWER < MODERATOR < ADMIN. The public read endpoints documented here do NOT require this scheme. The private/admin surface is documented but not part of this public reference. Machine-readable spec: /api/v1/openapi.
Operators
Published operator networks (the public face of a cluster).
get/operatorsList published operators
Paginated list of published operator networks (non-contaminated clusters), ordered by domain count then recency. Public-safe summary only.
Parameters
| Name | In | Type | Description |
|---|
page | query | integer | 1-based page number. Defaults to 1; values < 1 are coerced to 1. |
pageSize | query | integer | Items per page. Defaults to 20, hard-capped at 100 (larger values are clamped). |
Responses
get/operators/{id}Get a published operator
Public-safe detail for one operator: member domains, confidence-labeled shared-evidence bindings, and regulator warnings. Unpublished or contaminated operators return 404 — the API never reveals that a non-public record exists.
Parameters
| Name | In | Type | Description |
|---|
idrequired | path | string | Cluster id (cuid). |
Responses
| Status | Body | Description |
|---|
| 200 | ClusterDetail | Operator detail. |
| 404 | Error | Operator not found (or not published). |
Clusters
The graph-oriented view of the same published networks.
get/clustersList published clusters
Paginated list of published clusters. A cluster is the same underlying entity as an operator; this is the graph-oriented listing. Identical shape to /operators.
Parameters
| Name | In | Type | Description |
|---|
page | query | integer | 1-based page number. Defaults to 1; values < 1 are coerced to 1. |
pageSize | query | integer | Items per page. Defaults to 20, hard-capped at 100 (larger values are clamped). |
Responses
get/clusters/{id}Get a published cluster
Public-safe cluster detail plus adjacency to other published clusters (confidence label only, never edge evidence values). Unpublished or contaminated clusters return 404.
Parameters
| Name | In | Type | Description |
|---|
idrequired | path | string | Cluster id (cuid). |
Responses
Domains
Look up the public status of a single domain.
get/domains/{domain}Look up a domain
The "check a URL" lookup. The path segment is normalized to a registrable domain. Returns the public verdict, the operator it belongs to (if published), and any regulator warnings. Unknown, unpublished, or invalid input returns 404/400 — only PUBLISHED targets are exposed.
Parameters
| Name | In | Type | Description |
|---|
domainrequired | path | string | A domain or URL (URL-encoded). Normalized to a registrable domain server-side. |
Responses
| Status | Body | Description |
|---|
| 200 | DomainLookup | The domain is publicly listed. |
| 400 | Error | The supplied value could not be parsed as a domain. |
| 404 | Error | Domain not listed (unknown or not published). |
Activity
Recent pipeline activity and aggregate counts.
get/feedRecent pipeline activity
Up to 50 recent public pipeline events (crawls, discovery searches, pivots). Never includes verbatim phrases, query text, or match thresholds. A domain appearing here is NOT labelled a scam.
Responses
| Status | Body | Description |
|---|
| 200 | FeedEvent[] | Recent events, newest first. |
get/statsAggregate counts
Public counts: operators exposed (published, non-contaminated clusters), domains tracked, and total clusters. An empty or unreachable database yields zeros, never an error.
Responses
| Status | Body | Description |
|---|
| 200 | Stats | Aggregate counts. |
Community
Submitter leaderboard.
get/leaderboardSubmitter leaderboard
Top submitters ranked by impact: scams they reported and the associated scams the discovery loop surfaced from those seeds. Public fields only (handle + counts) — never email or linking detail.
Responses
| Status | Body | Description |
|---|
| 200 | object | Ranked submitters. |
Intake
Submit a suspected scam URL for review.
post/reportReport a suspected scam URL
Submit a suspected scam URL or domain for review. The value is normalized to a registrable domain and recorded as a DISCOVERED target; it NEVER publishes or asserts a verdict. Accepts either a JSON body or a form post. If the request carries a signed-in browser session cookie, the submission is credited to that user; API-key and anonymous posts stay anonymous.
Request body
| Content type | Schema |
|---|
application/json | url stringrequired
|
application/x-www-form-urlencoded | url stringrequired
|
Responses
| Status | Body | Description |
|---|
| 202 | ReportReceipt | Report received and recorded for review. |
| 400 | Error | Missing/malformed body, or the value is not a valid domain. |
| 500 | Error | The report could not be recorded right now; retry later. |
System
Liveness and the machine-readable API description.
get/healthLiveness check
Liveness probe. Does not touch the database, so it stays up even when the DB is unreachable.
Responses
| Status | Body | Description |
|---|
| 200 | Health | The service is up. |
get/openapiThis OpenAPI document
Returns this OpenAPI 3.1 document as JSON.
Responses
| Status | Body | Description |
|---|
| 200 | object | The OpenAPI 3.1 description of this API. |
Schemas
The object shapes referenced by the responses above.
Error
| Field | Type | Description |
|---|
errorrequired | object | |
PageMeta
| Field | Type | Description |
|---|
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer | |
hasMorerequired | boolean | |
Confidence
Coarse, methodology-free link confidence. Confirmed linkLikely linkPossible link |
Verdict
UNKNOWNLIKELY_LEGITSUSPICIOUSLIKELY_SCAMCONFIRMED_SCAM |
OperatorSummary
| Field | Type | Description |
|---|
idrequired | string | |
labelrequired | string | null | Human-readable operator label, if assigned. |
domainCountrequired | integer | |
regulatorConfirmedPctrequired | integer | Percentage of member domains that overlap a regulator warning (0–100). |
PublicBinding
| Field | Type | Description |
|---|
categoryrequired | string | Evidence category, e.g. 'recycled website copy', 'shared hosting fingerprint'. |
confidencerequired | Confidence | |
domainCountrequired | integer | Member domains carrying this evidence. |
PublicWarning
| Field | Type | Description |
|---|
regulatorrequired | string | Regulator code, e.g. 'FCA'. |
warningUrlrequired | string | null | |
publishedAtrequired | string | null | |
ClusterMemberDomain
| Field | Type | Description |
|---|
domainrequired | string | |
statusrequired | string | Public status, e.g. PUBLISHED / CRAWLED. |
warningsrequired | PublicWarning[] | |
ClusterDetail
| Field | Type | Description |
|---|
idrequired | string | |
labelrequired | string | null | |
domainCountrequired | integer | |
liveCountrequired | integer | Member domains that are published/live. |
verdictrequired | Verdict | |
regulatorConfirmedPctrequired | integer | |
bindingsrequired | PublicBinding[] | |
domainsrequired | ClusterMemberDomain[] | |
ClusterEdge
| Field | Type | Description |
|---|
clusterIdrequired | string | |
labelrequired | string | null | |
confidencerequired | Confidence | |
DomainLookup
| Field | Type | Description |
|---|
domainrequired | string | |
listedrequired | boolean | Always true on a 200 (only published targets are exposed). |
verdictrequired | Verdict | |
operatorrequired | object | null | |
warningsrequired | PublicWarning[] | |
FeedEvent
| Field | Type | Description |
|---|
atrequired | string | |
kindrequired | enum: "CRAWL" | "DISCOVER" | "PIVOT" | |
bodyrequired | string | Human-readable, methodology-free event description. |
Stats
| Field | Type | Description |
|---|
operatorsExposedrequired | integer | |
domainsTrackedrequired | integer | |
clustersrequired | integer | |
LeaderboardRow
| Field | Type | Description |
|---|
rankrequired | integer | |
handlerequired | string | Public display handle (never the email). |
reportedrequired | integer | Fresh scams this user submitted. |
detectedrequired | integer | Associated scams the discovery loop surfaced from those seeds. |
ReportReceipt
| Field | Type | Description |
|---|
domainrequired | string | The normalized registrable domain that was recorded. |
statusrequired | enum: "received" | |
Health
| Field | Type | Description |
|---|
statusrequired | enum: "ok" | |
timerequired | string | |