ScamVerify
Qr

QR Code Analysis

Upload a QR code image. Server decodes the QR code and analyzes the extracted URL for scam indicators using the full URL verification pipeline. Supported types: JPEG, PNG, WebP. Maximum size: 4.5 MB. If the QR code contains a phone number, email, or non-URL content, the decoded data is returned without URL analysis. **Quota:** Consumes 1 URL quota when a URL is extracted and analyzed. Non-URL QR codes do not consume quota. **Caching:** Results are cached by image hash. Cached lookups do not consume quota and return instantly. **Performance:** Expect 2-8 seconds for a full analysis (QR decode + URL verification pipeline). Cached results return instantly.

POST
/qr/analyze

Upload a QR code image. Server decodes the QR code and analyzes the extracted URL for scam indicators using the full URL verification pipeline. Supported types: JPEG, PNG, WebP. Maximum size: 4.5 MB.

If the QR code contains a phone number, email, or non-URL content, the decoded data is returned without URL analysis.

Quota: Consumes 1 URL quota when a URL is extracted and analyzed. Non-URL QR codes do not consume quota.

Caching: Results are cached by image hash. Cached lookups do not consume quota and return instantly.

Performance: Expect 2-8 seconds for a full analysis (QR decode + URL verification pipeline). Cached results return instantly.

Authorization

BearerAuth
AuthorizationBearer <token>

API key from your Developer Dashboard. Keys start with sv_live_ (production) or sv_test_ (test mode).

In: header

Request Body

multipart/form-data

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://scamverify.ai/api/v1/qr/analyze" \  -F file="string"

{
  "qr_found": true,
  "qr_data": "https://pay-parking-meter.example.com/scan?id=8842",
  "qr_content_type": "url",
  "image_hash": "f8e2a1c3d9b7...",
  "url_analysis": {
    "id": "url_7891",
    "url": "https://pay-parking-meter.example.com/scan?id=8842",
    "domain": "pay-parking-meter.example.com",
    "risk_score": 89,
    "verdict": "high_risk",
    "confidence": 0.91,
    "explanation": "This URL impersonates a parking meter payment service. The domain was registered 3 days ago, uses a free SSL certificate, and the hosting provider is frequently associated with phishing campaigns.",
    "signals": {
      "domain_age_days": 3,
      "registrar": "Namecheap",
      "ssl_issuer": "Let's Encrypt",
      "ssl_age_days": 2,
      "redirect_count": 1,
      "brand_impersonation": {
        "detected": true,
        "brand": "ParkMobile",
        "confidence": 0.85
      },
      "urlhaus_listed": false,
      "threatfox_listed": false,
      "ipqs_risk_score": 91,
      "community_reports": 0
    },
    "sources_checked": [
      "whois",
      "ssl",
      "urlhaus",
      "threatfox",
      "ipqs",
      "brand_detection",
      "ai_synthesis"
    ],
    "cached": false,
    "cache_expires_at": "2026-03-26T07:00:00.000Z",
    "created_at": "2026-03-19T07:00:00.000Z"
  },
  "cached": false,
  "created_at": "2026-03-19T07:00:00.000Z"
}

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request body",
    "details": {
      "issues": [
        {
          "field": "phone_number",
          "message": "phone_number is required"
        }
      ]
    }
  }
}

{
  "error": {
    "code": "missing_api_key",
    "message": "Authorization header is required. Use 'Bearer sv_live_...' format."
  }
}

{
  "error": {
    "code": "quota_exhausted",
    "message": "Monthly phone quota exhausted. Upgrade your plan for more lookups.",
    "upgrade_url": "https://scamverify.ai/settings/api"
  }
}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please wait before making another request.",
    "retry_after": 12
  }
}
{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred. Please try again later."
  }
}

Document Analysis POST

Analyze a document image for scam indicators using vision AI. Upload a photo of a suspicious letter, court notice, receipt, invoice, toll notice, or other document. The pipeline extracts entities (phone numbers, URLs, addresses, officials, legal citations, dollar amounts, dates) using GPT-4o vision, then verifies them in parallel against government databases: - **Addresses:** Smarty US Street API (deliverability, CMRA mailbox detection) + Google Places (institution verification) - **Officials:** CourtListener (federal/state judge database) - **Legal citations:** GovInfo (federal statutes/regulations) + CourtListener (case law) Results are synthesized by AI into a unified risk score with evidence-based verdict. **Supported file types:** JPEG, PNG, WebP, HEIC/HEIF, single-page PDF. **Maximum file size:** 4.5 MB. **Content type:** `multipart/form-data` (not JSON). **Quota:** Consumes 1 document quota per analysis. Document quota is separate from phone/URL/text/email quotas. Cached results (same image hash) do not consume additional quota. **QR codes:** To analyze a QR code, use the dedicated [QR Code Analysis](#tag/QR/POST/qr/analyze) endpoint, which handles server-side decoding and URL verification automatically. **Performance:** Expect 5-15 seconds for a full analysis (vision AI extraction + entity verification + AI synthesis). Cached results return instantly.

Batch Phone Lookup POST

Look up multiple phone numbers in a single request. Processes up to 100 numbers with 10 concurrent lookups at a time. **Quota:** Each successful non-cached lookup consumes 1 phone quota. If quota is exhausted mid-batch, remaining items return an error object. **Rate limit:** Batch endpoints have a fixed 5 RPM limit for all tiers.