Skip to main content

Discovery Scan API

The Discovery Scan API lets you run Chainara's discovery scanners on demand and get back actionable indicators — crypto wallet addresses and URLs (IOCs) — plus a per-source scam verdict. You submit a scan for a module (e.g. youtube, telegram) with your existing API key; the scan runs asynchronously and you retrieve results by polling or via a signed webhook.

It's the same scanning engine that powers Chainara's automated discovery jobs, exposed per request so you can point it at your own search terms or channels.

Available modules

ModuleWhat it scansModule-specific input
youtubeLive/recent YouTube videos for crypto-scam overlays, QR codes, and links (vision analysis)queries[] or video_url, optional max_streams_per_query
telegramRecent messages in public Telegram channelschannels[], optional max_messages_per_channel
meta-adsMeta (Facebook/Instagram) Ad Library for crypto-scam ads — returns destination domains + impersonated handlesqueries[], optional max_ads_per_query, countries[]
blueskyBluesky (AT Protocol) posts matching your search queriesqueries[], optional limit
bing-adsMicrosoft Bing Ad Library (EU/EEA) for crypto recovery/broker-scam ads — returns destination URLsqueries[], optional max_ads_per_query

Call GET /api/v2/discovery/modules for the live list and an example body for each.

tip

The module list grows over time. Always discover capabilities programmatically via /discovery/modules rather than hard-coding the set.

Authentication

All endpoints use your standard API key (see API & Integration):

Authorization: Bearer <your-api-key>

Endpoints

MethodPathPurpose
GET/api/v2/discovery/modulesList modules + example body for each
POST/api/v2/discovery/{module}/scanSubmit a scan → 202 with jobId
GET/api/v2/discovery/{module}/scan/{jobId}Poll status + IOCs + findings
GET/api/v2/discovery/scansList your recent scans (?module=, ?limit=)

Submit a scan

The request body is module-specific plus two common blocks — filters (optional) and callback_url (optional).

# YouTube
curl -X POST https://api.chainara.io/api/v2/discovery/youtube/scan \
-H "Authorization: Bearer $CHAINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"queries": ["Brad Garlinghouse live giveaway", "XRP airdrop confirmed"],
"max_streams_per_query": 10,
"filters": { "scams_only": true },
"callback_url": "https://you.example.com/webhooks/chainara"
}'
# Telegram
curl -X POST https://api.chainara.io/api/v2/discovery/telegram/scan \
-H "Authorization: Bearer $CHAINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "channels": ["@investigations"], "max_messages_per_channel": 60 }'
# Meta Ads (Facebook / Instagram Ad Library)
curl -X POST https://api.chainara.io/api/v2/discovery/meta-ads/scan \
-H "Authorization: Bearer $CHAINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "queries": ["xrp giveaway", "ripple airdrop"], "max_ads_per_query": 30, "countries": ["US"] }'
// 202 Accepted
{
"jobId": "855a022b-c7e6-4b7e-bf59-0fe57a46efb0",
"module": "youtube",
"status": "scanning",
"statusUrl": "/api/v2/discovery/youtube/scan/855a022b-…",
"webhook": { "url": "https://you.example.com/…", "signed": true }
}

Poll for results

curl https://api.chainara.io/api/v2/discovery/youtube/scan/855a022b-… \
-H "Authorization: Bearer $CHAINARA_API_KEY"
{
"jobId": "855a022b-…",
"module": "youtube",
"status": "completed",
"summary": { "itemsScanned": 14, "hitsConfirmed": 3, "iocCount": 5 },
"iocs": {
"wallets": [ { "chain": "xrp", "address": "rXxx…", "foundIn": ["abc123"] } ],
"urls": [ { "url": "https://giftsaylor.us", "domain": "giftsaylor.us", "foundIn": ["abc123"] } ]
},
"findings": [
{
"sourceId": "abc123",
"sourceUrl": "https://www.youtube.com/watch?v=abc123",
"verdict": "scam",
"confidence": 0.85,
"signals": ["impersonation", "qr_code", "scam_language"],
"wallets": [ /* … */ ],
"urls": [ /* … */ ],
"extra": { "streamLayout": "scam_overlay" }
}
]
}

status is one of queued · scanning · completed · partial · failed. The iocs block is the de-duplicated rollup across all findings — usually the only part you need to action. Each finding's verdict is scam, benign, or unknown, with a confidence of 0–1.

Timing

YouTube scans take ~2–5 minutes (video capture + vision analysis). Telegram scans typically finish in under a minute. Poll every ~15 seconds, or use a callback_url webhook to avoid polling.

Filters (all modules)

FieldEffect
scams_onlyReturn only findings with verdict: scam
min_confidenceDrop findings below this confidence (0–1)
require_iocsDrop findings with no wallet/URL

Webhooks

If you supply callback_url, Chainara POSTs the completed result to that URL with an HMAC signature so you can verify authenticity:

X-Chainara-Event: discovery-scan.completed
X-Chainara-Timestamp: 1748396843
X-Chainara-Signature: sha256=<hmac>

The signature is HMAC-SHA256(secret, "{timestamp}.{rawBody}"). Verify in Node:

import crypto from "crypto";

function verify(req, secret) {
const ts = req.headers["x-chainara-timestamp"];
const expected =
"sha256=" + crypto.createHmac("sha256", secret)
.update(`${ts}.${req.rawBody}`).digest("hex");
const got = req.headers["x-chainara-signature"];
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(got));
}

The webhook body mirrors the poll response (jobId, module, status, summary, iocs, findings) plus an event field. Your per-job signing secret is shown in the API Keys area of the dashboard.

Errors

StatusMeaning
400Invalid request body (e.g. missing module params)
401Missing or invalid API key
404Unknown module, or job not found / not yours
502Could not queue the scan — retry

Try it

Use the interactive Discovery section of the API Explorer to send live requests with your key.