Savdhaan.in
API Reference

Savdhaan API Documentation

Integrate real-time scam detection into your app. Analyze text, images, and URLs against 6+ threat intelligence sources.

Quickstart

Get started with the Savdhaan API in 3 steps. Scan any suspicious text or image and get an evidence-based risk score.

1

Create an account

Sign up with email or Google. Free — no credit card required.

2

Get your API key

Go to your Profile and create an API key. Keys start with svd_ and are shown only once.

3

Make your first scan

Send a POST request with the suspicious content. You'll get a risk score, evidence, and recommended actions.

curl -X POST https://api.savdhaan.in/api/v1/scan \
  -H "X-API-Key: svd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Congratulations! You won Rs 50,000. Click http://prize.xyz to claim.",
    "content_type": "text"
  }'

Free tier includes 10 scans/hour — enough to get started and test your integration.

Authentication

All API requests require an API key passed via the X-API-Key header.

Request Header
X-API-Key: svd_4a7b3c2d9e1f5a6b8c0d3e4f5a6b7c8d

Key details

  • Format: svd_ prefix + 32 alphanumeric characters
  • Create keys at your Profile page (max 5 active keys)
  • Keys are shown only once at creation — store them securely
  • Never expose your API key in client-side code — always call from your server

POST /api/v1/scan

Scan text content for scam indicators. Returns a risk score, evidence, and recommended actions.

Request Body

ParameterTypeRequiredDescription
contentstringYesText to scan (1–10,000 characters)
content_typeenumNo"text" (default) or "image"
channelenumNo"sms" | "whatsapp" | "email" | "social_dm" | "website" | "other"
categoryenumNo"scam_check" (default) | "job_offer" | "rental_lease" | "investment" | "contract" | "auto"
localestringNoLanguage hint, e.g. "en" (default), "hi"

Example

curl -X POST https://api.savdhaan.in/api/v1/scan \
  -H "X-API-Key: svd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Congratulations! You won Rs 50,000. Click http://prize.xyz to claim.",
    "content_type": "text"
  }'

Response

200 OK
{
  "ok": true,
  "data": {
    "scan_id": "e7b26d9c-5a2b-4e1a-8f3c-9d2e1c5b7a4f",
    "risk_score": 92,
    "risk_level": "critical",
    "scam_type": "lottery_prize",
    "explanation": "This message exhibits multiple lottery scam indicators...",
    "evidence": [
      {
        "source": "Pattern Detection",
        "detail": "Contains lottery/prize scam phrases",
        "is_threat": true,
        "confidence": 0.99
      },
      {
        "source": "URL Reputation",
        "detail": "Domain prize.xyz registered 3 days ago",
        "is_threat": true,
        "confidence": 0.95
      }
    ],
    "actions": [
      "Do not click any links",
      "Delete the message immediately",
      "Report to your mobile provider"
    ],
    "entities": {
      "urls": ["http://prize.xyz"],
      "phones": [],
      "emails": [],
      "crypto_addresses": [],
      "upi_ids": []
    },
    "checks_performed": [
      "entity_extraction",
      "rule_based_pattern_detection",
      "url_reputation (Google Safe Browsing, PhishTank, URLhaus, VirusTotal)",
      "domain_age_verification (WHOIS)",
      "llm_classification"
    ],
    "checks_not_available": [],
    "confidence_note": "High confidence based on multiple threat signals",
    "content_snippet": "Congratulations! You won Rs 50,000...",
    "scam_card": {
      "card_id": "lty7x9k2",
      "card_url": "https://savdhaan.in/card/lty7x9k2",
      "image_url": "https://savdhaan.in/static/cards/lty7x9k2.png"
    },
    "community": {
      "total_similar_reports": 42,
      "entity_signals": [],
      "first_reported_at": "2025-12-15T10:30:00Z"
    },
    "processing_time_ms": 2156,
    "created_at": "2026-02-22T16:30:45Z"
  }
}

POST /api/v1/scan/image

Scan an image (screenshot) for scam indicators. OCR extracts text automatically, then runs the same analysis pipeline as text scans.

Content-Type must be multipart/form-data — not JSON.

Request Fields

ParameterTypeRequiredDescription
filefileYesImage file: JPEG, PNG, WebP, or GIF (max 10 MB)
channelenumNo"sms" | "whatsapp" | "email" | "social_dm" | "website" | "other"
categoryenumNo"scam_check" (default) | "job_offer" | "rental_lease" | "investment" | "contract" | "auto"
localestringNoLanguage hint, default: "en"

Example

curl -X POST https://api.savdhaan.in/api/v1/scan/image \
  -H "X-API-Key: svd_your_key_here" \
  -F "file=@screenshot.png" \
  -F "channel=whatsapp"

Response format is identical to POST /scan.

GET /api/v1/scan/{scan_id}

Retrieve a previous scan result by its ID. Only returns scans created with your API key.

Path Parameters

ParameterTypeRequiredDescription
scan_idUUIDYesThe scan ID returned from POST /scan

Example

curl https://api.savdhaan.in/api/v1/scan/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-API-Key: svd_your_key_here"

POST /api/v1/scan/streamSSE

Stream scan progress as Server-Sent Events. Same request body as POST /scan. Emits real-time progress events as each pipeline step completes, then a final result event.

Pipeline Steps (9 total)

#StepDescription
1dedup_checkCheck if this content was already scanned
2entity_extractionExtract URLs, phones, emails, UPI IDs, crypto addresses
3rule_engineRun pattern-matching rules (14 signals)
4threat_intelQuery 6+ threat databases in parallel
5llm_classificationAI-powered scam classification
6score_mergeMerge all evidence into final risk score
7actionsGenerate recommended actions
8persistSave results to database
9scam_cardGenerate shareable scam card (if risk >= 40)

Event Types

event: progress— Emitted after each pipeline step
{
  "scan_step": "threat_intel",
  "step_number": 4,
  "total_steps": 9,
  "message": "Checking threat intelligence databases...",
  "elapsed_ms": 1200
}
event: result— Final event with the full scan result
event: error— Emitted if the scan fails

Example

curl -N -X POST https://api.savdhaan.in/api/v1/scan/stream \
  -H "X-API-Key: svd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"content": "Your account is blocked. Call +91-9999999999 to verify.", "content_type": "text"}'

POST /api/v1/report

Submit feedback on a scan result. Helps improve our detection accuracy.

Request Body

ParameterTypeRequiredDescription
scan_idUUIDYesID of the scan to report on
feedback_typeenumYes"confirmed_scam" | "false_positive" | "false_negative" | "helpful" | "not_helpful"
commentstringNoAdditional context (max 2,000 characters)
contact_emailstringNoEmail for follow-up (max 255 characters)

Example

curl -X POST https://api.savdhaan.in/api/v1/report \
  -H "X-API-Key: svd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "scan_id": "550e8400-e29b-41d4-a716-446655440000",
    "feedback_type": "confirmed_scam",
    "comment": "This was a real phishing attempt"
  }'

Response

200 OK
{
  "ok": true,
  "data": {
    "report_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "scan_id": "550e8400-e29b-41d4-a716-446655440000",
    "feedback_type": "confirmed_scam",
    "status": "pending",
    "message": "Thank you for your feedback. It helps us improve."
  }
}

Response Format

All API responses use a consistent envelope format.

Success

{
  "ok": true,
  "data": { ... },
  "error": null,
  "meta": {
    "request_id": "550e8400-..."
  }
}

Error

{
  "ok": false,
  "data": null,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded."
  },
  "meta": {
    "request_id": "550e8400-..."
  }
}

Risk Level Scale

LevelScore RangeMeaning
critical80–100Almost certainly a scam — do not engage
high60–79Strong scam indicators detected
medium40–59Some suspicious patterns — proceed with caution
low20–39Minor signals — likely safe but verify
none0–19No scam indicators found

Key Response Fields

ParameterTypeRequiredDescription
scan_idUUIDYesUnique identifier for this scan
risk_scoreintegerYes0–100 risk score
risk_levelstringYescritical | high | medium | low | none
scam_typestringNoDetected scam category (e.g. phishing, upi_fraud, lottery_prize)
explanationstringYesAI-generated explanation of the risk assessment
evidencearrayYesList of specific threat signals found (source, detail, confidence)
actionsarrayYesRecommended actions for the user
entitiesobjectYesExtracted entities: urls, phones, emails, crypto_addresses, upi_ids
scam_cardobjectNoShareable scam card (card_id, card_url, image_url) — generated when risk >= 40
communityobjectNoCommunity signals: total_similar_reports, entity_signals
processing_time_msintegerYesTotal scan time in milliseconds

Error Codes

When a request fails, the response includes an error object with a machine-readable code.

HTTPCodeDescriptionRecovery
400INVALID_INPUTRequest validation failedCheck request body and fix errors
401UNAUTHORIZEDMissing or invalid API keyProvide a valid X-API-Key header
404NOT_FOUNDScan or resource not foundVerify the ID is correct
413PAYLOAD_TOO_LARGEImage exceeds 10 MBReduce image size
415UNSUPPORTED_MEDIA_TYPEImage format not supportedUse JPEG, PNG, WebP, or GIF
429RATE_LIMIT_EXCEEDEDPlan rate limit reachedWait and retry, or upgrade plan
500INTERNAL_ERRORUnexpected server errorRetry with exponential backoff

Example Error Response

429 Too Many Requests
{
  "ok": false,
  "data": null,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Limit: 10 requests per hour."
  },
  "meta": {
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Rate Limits

Rate limits are enforced per API key using a sliding window.

PlanScans / HourPrice
Free10$0
Premium100Coming soon

When you hit the rate limit, the API returns 429 Too Many Requests.

The response includes a Retry-After header indicating how many seconds to wait before retrying.

Need higher limits? Contact us for enterprise plans with custom rate limits.

Need help?

For technical assistance, API integration support, or bug reports, contact us at support@savdhaan.in