Unhook

Integration for companies

Banks, mobile operators and public bodies can connect Unhook to their own systems: to check messages, learn about campaigns that imitate their brand, and block fake domains.

Sign in to the partner dashboard →

📱 Mobile operator

Incoming SMS are checked at the SMS gateway with /partner/check. Scams are blocked, suspicious ones are labelled. Fake links are blocked on the network with /partner/blocklist.

🏦 Bank

A “Check message” button in the mobile app. The fraud team sees campaigns in the bank's name and is alerted at once by webhook.

🏛 Public body

A national campaign map: which brands are targeted, which domains repeat. A key that sees all brands can be issued.

1. Get a key

Every company gets its own API key, and it only gives access to your own brand's data (for example, an Azercell key does not show Kapital Bank's campaigns). The key is shown once and we store only its hash. In this hackathon prototype the team issues the key (python partners.py create "Azercell" --brand Azercell).

2. Add the header to your request

curl
curl https://cystocarpic-exteriorly-lucian.ngrok-free.dev/partner/me \
  -H "X-API-Key: unhook_..."

Endpoints

GET/partner/meShows who the key belongs to and its brand
POST/partner/checkChecks one message (text or image)
POST/partner/check/batchChecks up to 10 messages in one request
GET/partner/summaryNumbers for your brand
GET/partner/campaignsCampaigns that imitate your brand
GET/partner/blocklistFake domains (JSON, or ?format=csv)

Checking a message

curl
curl -X POST https://cystocarpic-exteriorly-lucian.ngrok-free.dev/partner/check \
  -H "X-API-Key: unhook_..." -H "Content-Type: application/json" \
  -d '{"text": "salam, bonusunuz hazirdir: bonus-azercell.top/qazan", "lang": "en"}'

Add "lang": "en" (or "ru", "az") to the request and the explanation comes back in that language. Default: az.

response
{
  "verdict": "scam",            // scam | suspicious | safe
  "scheme": "fake_bonus",
  "scheme_az": "Saxta bonus / uduş",
  "confidence": 0.97,
  "reasons": ["The link imitates the official Azercell site", "..."],
  "actions": ["Do not click the link", "..."],
  "explanation_az": "This message pretends to be Azercell...",   // written in the requested "lang"
  "links": [{"domain": "bonus-azercell.top", "status": "lookalike"}],
  "degraded": false,            // true: the AI could not answer, only the links were checked
  "report_id": 123
}

Batch check (up to 10 messages, answers come back in the same order):

curl
curl -X POST https://cystocarpic-exteriorly-lucian.ngrok-free.dev/partner/check/batch \
  -H "X-API-Key: unhook_..." -H "Content-Type: application/json" \
  -d '{"messages": ["message 1", "message 2"]}'

Blocklist and campaigns

CSV (to plug into a URL filter)
curl "https://cystocarpic-exteriorly-lucian.ngrok-free.dev/partner/blocklist?format=csv" -H "X-API-Key: unhook_..." -o unhook-blocklist.csv
campaigns
curl https://cystocarpic-exteriorly-lucian.ngrok-free.dev/partner/campaigns -H "X-API-Key: unhook_..."

The list is generated automatically and has not been reviewed by a person. Your own team should check it before blocking.

Webhook: an immediate alert

When a scam that imitates your brand is detected, a POST is sent to your address (to forward to Slack, e-mail or a SIEM). Every request is signed with the X-Unhook-Signature header, so you can verify it came from us.

event
{
  "event": "report.flagged",
  "sent_at": "2026-10-09T12:30:00+00:00",
  "report": {
    "id": 123,
    "verdict": "scam",
    "scheme": "fake_bonus",
    "scheme_az": "Saxta bonus / uduş",
    "confidence": 0.97,
    "text_redacted": "salam, bonusunuz hazirdir: bonus-azercell.top/qazan",
    "domains": ["bonus-azercell.top"],
    "brands": ["Azercell"]
  }
}
verifying the signature (Python)
import hashlib, hmac

def is_from_unhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)   # header: X-Unhook-Signature

Privacy, security and limits

  • Card numbers, phone numbers and one-time codes are removed before they reach the AI and before anything is stored.
  • API keys are stored as hashes, each key only gives access to its own brand, and it can be revoked.
  • This prototype sends the text of the message (without personal data) to outside AI services (Groq, Gemini). For a real bank our plan is a local model running on the company's own servers, so messages never leave the company.
  • This is a hackathon prototype: there is no service level agreement (SLA), rate limit or audit log yet.
  • The AI can be wrong. The result is a helping signal and should not be the only basis for a decision.