---
title: "Fingerprint a suspected phishing/smishing kit"
method: POST
path: "/v1/payg/scamkit-fingerprint"
tags: ["x402 pay-per-call"]
---

# Fingerprint a suspected phishing/smishing kit

`POST /v1/payg/scamkit-fingerprint`

## Request

- Base URL: `https://api.relayshield.net`
- URL: `https://api.relayshield.net/v1/payg/scamkit-fingerprint`
- Auth: none required

Turn one suspicious link into a matchable kit identity: extract the kit's structural signals (DOM skeleton, script hashes, form/exfil hosts, brand marks, URL pattern class), strip per-victim nonces and credentials BEFORE hashing, and return a stable kit_<sha256> fingerprint ID that is identical for the same kit across sightings. INPUT LIMITATION (v1): the Lambda has no JS rendering, so the `url` field is fetched as static HTML only. For JS-heavy kits, render the page yourself and submit the rendered HTML via the `html` field. Secrets, tokens, and machine identifiers are removed before hashing and are never returned or stored — two kits differing only in rotated credentials fingerprint identically. The v1b fetch pipeline also captures server-side telemetry nobody else ships in a kit API: up to 5 redirect hops, response headers (including X-Evilginx), TLS version/cipher/certificate facts for the kit host, and up to 2 bounded secondary fetches (Evilginx canary + remote favicon). OPTIONAL `observed_telemetry` (ja3/ja4/user_agent_shifts/app_ids/ip_anomalies/session_anomalies) records YOUR OWN proxy/EDR/IdP telemetry verbatim, marked caller_supplied — the pipeline never computes JA3/JA4 locally (those fingerprint the TLS client, not the kit server). The returned kit_family is auto-resolved: the 13 FLAME TP-0067 families Andrew approved carry family_status approved; every other name is suggested. URL -> malware-family attribution: for kind='kit' with a fetched URL, the response also carries malware_families from RelayShield's IOC corpus (empty when the corpus has no malware label for the URL) with malware_attribution='relayshield_ioc_corpus' when attributed, else null. Caller-supplied html gets no URL attribution.

**Billing.** $0.50 in USDC per call over x402, on Base or Solana. No API key, no signup and no
subscription. Send the request with no payment header, take the `402` challenge that comes back,
pay it, and repeat the request. Only successful calls are charged.

## Request body

- object
  - `url` string: Live URL to fingerprint. Fetched as static HTML only in v1 (no JS rendering).
  - `html` string: Caller-supplied kit HTML (alternative to url; takes precedence). Submit rendered HTML for JS-heavy kits.
  - `source` string: Optional caller tag recorded with the sighting (e.g. 'sms-feed-2026-09').
  - `family` string: Optional caller-supplied family label for a brand-new fingerprint (approved if it names one of the 13 FLAME TP-0067 families, suggested otherwise).
  - `kind` string: Fingerprint kind: 'kit' (default — phishing-kit HTML flow) or 'malware' (malware-sample flow; requires 'signals').
  - `signals` object: REQUIRED for kind='malware': caller-computed feature dict for the sample (v1 does no binary extraction in Lambda). Ignored for kind='kit'.
  - `malware_family` string: Optional Malpedia family_id for kind='malware' (e.g. 'win.beavertail'). Resolved live against the Malpedia taxonomy; the 5 Andrew-approved WaterPlum families emit family_status approved, everything else suggested.
  - `observed_telemetry` object: Optional CALLER-SUPPLIED telemetry from your own proxy/EDR/IdP (ja3, ja4, user_agent_shifts, app_ids, ip_anomalies, session_anomalies). Recorded verbatim and marked caller_supplied; never presented as server-measured. The pipeline never computes JA3/JA4 locally — those fingerprint the TLS client, not the kit server.

## Response `200`

Payment settled and the check ran. `ok` is true and `data` holds the result.

- object
  - `ok` true, required
  - `data` object, required

## Other responses

- `400`: A required field is missing or malformed. Never billed.
- `402`: Payment required. The body carries a complete x402 version 2 challenge with the accepted networks, the amount in USDC base units, and the recipient. Pay it and repeat the request with the payment header.
- `405`: Wrong HTTP method. Every endpoint is POST.

---

[API](https://skmtc.dev/relayshield/apis/relayshield-api.md) · [All operations](https://skmtc.dev/relayshield/apis/relayshield-api/llms.txt) · [OpenAPI document](https://skmtc.dev/relayshield/apis/relayshield-api/revisions/4d4721b936dd?raw)
