scamcrawl Public API

Read access to published scam-operator networks and intake of suspected scam URLs. v1.0.0

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
NameInTypeDescription
pagequeryinteger1-based page number. Defaults to 1; values < 1 are coerced to 1.
pageSizequeryintegerItems per page. Defaults to 20, hard-capped at 100 (larger values are clamped).
Responses
StatusBodyDescription
200OperatorSummary[]A page of operator summaries.
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
NameInTypeDescription
idrequiredpathstringCluster id (cuid).
Responses
StatusBodyDescription
200ClusterDetailOperator detail.
404ErrorOperator 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
NameInTypeDescription
pagequeryinteger1-based page number. Defaults to 1; values < 1 are coerced to 1.
pageSizequeryintegerItems per page. Defaults to 20, hard-capped at 100 (larger values are clamped).
Responses
StatusBodyDescription
200OperatorSummary[]A page of cluster summaries.
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
NameInTypeDescription
idrequiredpathstringCluster id (cuid).
Responses
StatusBodyDescription
200ClusterDetailWithEdgesCluster detail with public adjacency edges.
404ErrorCluster not found (or not published).

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
NameInTypeDescription
domainrequiredpathstringA domain or URL (URL-encoded). Normalized to a registrable domain server-side.
Responses
StatusBodyDescription
200DomainLookupThe domain is publicly listed.
400ErrorThe supplied value could not be parsed as a domain.
404ErrorDomain 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
StatusBodyDescription
200FeedEvent[]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
StatusBodyDescription
200StatsAggregate 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
StatusBodyDescription
200objectRanked 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 typeSchema
application/json
url stringrequired
application/x-www-form-urlencoded
url stringrequired
Responses
StatusBodyDescription
202ReportReceiptReport received and recorded for review.
400ErrorMissing/malformed body, or the value is not a valid domain.
500ErrorThe 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
StatusBodyDescription
200HealthThe service is up.
get/openapiThis OpenAPI document

Returns this OpenAPI 3.1 document as JSON.

Responses
StatusBodyDescription
200objectThe OpenAPI 3.1 description of this API.

Schemas

The object shapes referenced by the responses above.

Error

FieldTypeDescription
errorrequiredobject

PageMeta

FieldTypeDescription
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
hasMorerequiredboolean

Confidence

Coarse, methodology-free link confidence.
Confirmed linkLikely linkPossible link

Verdict

UNKNOWNLIKELY_LEGITSUSPICIOUSLIKELY_SCAMCONFIRMED_SCAM

OperatorSummary

FieldTypeDescription
idrequiredstring
labelrequiredstring | nullHuman-readable operator label, if assigned.
domainCountrequiredinteger
regulatorConfirmedPctrequiredintegerPercentage of member domains that overlap a regulator warning (0–100).

PublicBinding

FieldTypeDescription
categoryrequiredstringEvidence category, e.g. 'recycled website copy', 'shared hosting fingerprint'.
confidencerequiredConfidence
domainCountrequiredintegerMember domains carrying this evidence.

PublicWarning

FieldTypeDescription
regulatorrequiredstringRegulator code, e.g. 'FCA'.
warningUrlrequiredstring | null
publishedAtrequiredstring | null

ClusterMemberDomain

FieldTypeDescription
domainrequiredstring
statusrequiredstringPublic status, e.g. PUBLISHED / CRAWLED.
warningsrequiredPublicWarning[]

ClusterDetail

FieldTypeDescription
idrequiredstring
labelrequiredstring | null
domainCountrequiredinteger
liveCountrequiredintegerMember domains that are published/live.
verdictrequiredVerdict
regulatorConfirmedPctrequiredinteger
bindingsrequiredPublicBinding[]
domainsrequiredClusterMemberDomain[]

ClusterEdge

FieldTypeDescription
clusterIdrequiredstring
labelrequiredstring | null
confidencerequiredConfidence

ClusterDetailWithEdges

FieldTypeDescription
extends ClusterDetail
edgesrequiredClusterEdge[]Adjacency to other published clusters (confidence label only).

DomainLookup

FieldTypeDescription
domainrequiredstring
listedrequiredbooleanAlways true on a 200 (only published targets are exposed).
verdictrequiredVerdict
operatorrequiredobject | null
warningsrequiredPublicWarning[]

FeedEvent

FieldTypeDescription
atrequiredstring
kindrequiredenum: "CRAWL" | "DISCOVER" | "PIVOT"
bodyrequiredstringHuman-readable, methodology-free event description.

Stats

FieldTypeDescription
operatorsExposedrequiredinteger
domainsTrackedrequiredinteger
clustersrequiredinteger

LeaderboardRow

FieldTypeDescription
rankrequiredinteger
handlerequiredstringPublic display handle (never the email).
reportedrequiredintegerFresh scams this user submitted.
detectedrequiredintegerAssociated scams the discovery loop surfaced from those seeds.

ReportReceipt

FieldTypeDescription
domainrequiredstringThe normalized registrable domain that was recorded.
statusrequiredenum: "received"

Health

FieldTypeDescription
statusrequiredenum: "ok"
timerequiredstring