{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/bewary/json-schema/bewary-envelope-schema.json",
  "title": "Envelope",
  "description": "The answer of every lookup and check.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/bewary-openapi.json#/components/schemas/Envelope",
  "properties": {
    "schema_version": {
      "type": "string",
      "title": "Schema Version"
    },
    "request_id": {
      "type": "string",
      "title": "Request Id"
    },
    "checked_at": {
      "type": "string",
      "title": "Checked At",
      "description": "RFC 3339 UTC."
    },
    "engine": {
      "type": "string",
      "title": "Engine"
    },
    "models": {
      "$ref": "#/$defs/ModelsUsed"
    },
    "input": {
      "$ref": "#/$defs/InputInfo"
    },
    "verdict": {
      "type": "string",
      "enum": [
        "scam",
        "suspicious",
        "safe",
        "unknown"
      ],
      "title": "Verdict"
    },
    "p_scam": {
      "type": "number",
      "maximum": 1.0,
      "minimum": 0.0,
      "title": "P Scam",
      "description": "Probability that the input is part of a scam."
    },
    "risk_score": {
      "type": "integer",
      "maximum": 100.0,
      "minimum": 0.0,
      "title": "Risk Score"
    },
    "confidence": {
      "type": "number",
      "maximum": 1.0,
      "minimum": 0.0,
      "title": "Confidence"
    },
    "classification": {
      "anyOf": [
        {
          "$ref": "#/$defs/Classification"
        },
        {
          "type": "null"
        }
      ]
    },
    "reason_codes": {
      "items": {
        "type": "string"
      },
      "type": "array",
      "title": "Reason Codes",
      "description": "The codes that decided the verdict, strongest first, at most 5."
    },
    "entities": {
      "items": {
        "$ref": "#/$defs/Entity"
      },
      "type": "array",
      "title": "Entities"
    },
    "signals": {
      "items": {
        "$ref": "#/$defs/Signal"
      },
      "type": "array",
      "title": "Signals"
    },
    "degraded": {
      "type": "boolean",
      "title": "Degraded"
    },
    "degraded_reasons": {
      "items": {
        "type": "string",
        "enum": [
          "source_timeout",
          "source_unavailable",
          "budget_limit",
          "redirect_unresolved",
          "input_truncated",
          "model_unavailable",
          "page_unavailable"
        ]
      },
      "type": "array",
      "title": "Degraded Reasons"
    },
    "cached": {
      "type": "boolean",
      "title": "Cached"
    },
    "explanation": {
      "anyOf": [
        {
          "$ref": "#/$defs/Explanation"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "type": "object",
  "required": [
    "schema_version",
    "request_id",
    "checked_at",
    "engine",
    "models",
    "input",
    "verdict",
    "p_scam",
    "risk_score",
    "confidence",
    "reason_codes",
    "entities",
    "signals",
    "degraded",
    "degraded_reasons",
    "cached"
  ],
  "$defs": {
    "AppFacts": {
      "properties": {
        "store": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "apple",
                "google_play"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Store"
        },
        "app_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "App Id",
          "description": "Apple: the numeric App Store id. Google Play: the package name (application id)."
        },
        "status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "live",
                "removed",
                "not_found",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Status",
          "description": "live: the store lists it now. removed: we saw it live before and the store no longer lists it. not_found: the store has no such app and we never saw it live. unknown: the store could not be read (degraded)."
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Name",
          "description": "The store's title for the app (from the last live sighting)."
        },
        "developer": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Developer",
          "description": "The developer or seller name the store publishes (from the last live sighting)."
        },
        "rating_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Rating Count",
          "description": "How many ratings the store shows (Apple: in that storefront)."
        },
        "storefront": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Storefront",
          "description": "Apple: the App Store country read, ISO 3166-1 alpha-2."
        },
        "first_seen": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "First Seen",
          "description": "The first time we saw it live, RFC 3339 UTC."
        },
        "last_seen": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Last Seen",
          "description": "The last time we saw it live, RFC 3339 UTC."
        },
        "missing_since": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Missing Since",
          "description": "The first check that found it gone after a live sighting, RFC 3339 UTC; null while live."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "AppFacts",
      "description": "A mobile app on the Apple App Store or Google Play (task E12, added 2026-10-29)."
    },
    "ArchiveHistory": {
      "properties": {
        "checked_at": {
          "type": "string",
          "title": "Checked At",
          "description": "When we read the archive's index, RFC 3339 UTC. Kept for up to 30 days."
        },
        "captured": {
          "type": "boolean",
          "title": "Captured",
          "description": "The archive holds at least one capture of the host's homepage."
        },
        "first_capture_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "First Capture At",
          "description": "The first capture, RFC 3339 UTC; null when none."
        },
        "last_capture_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Last Capture At",
          "description": "The latest capture, RFC 3339 UTC; null when none."
        },
        "captured_before_registration": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Captured Before Registration",
          "description": "The homepage was captured more than 30 days before registered_at: the name had an earlier life before this registration (it lapsed and someone registered it again). Null when either date is unknown, or for a tenant of a hosting platform."
        },
        "months_before_registration": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Months Before Registration",
          "description": "How many calendar months hold a capture before registered_at; null unless captured_before_registration."
        },
        "last_capture_before_registration_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Last Capture Before Registration At",
          "description": "The last capture before registered_at, RFC 3339 UTC: the end of the earlier life."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "checked_at",
        "captured"
      ],
      "title": "ArchiveHistory",
      "description": "The site's history in a public web archive (E9): when its homepage was first and last captured, and whether\nit was captured before the current registration began (a name that lapsed and was registered again)."
    },
    "Brand": {
      "properties": {
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Id"
        },
        "name": {
          "type": "string",
          "title": "Name"
        }
      },
      "type": "object",
      "required": [
        "name"
      ],
      "title": "Brand"
    },
    "Classification": {
      "properties": {
        "artifact_type": {
          "type": "string",
          "title": "Artifact Type",
          "description": "What the message is: delivery_notice, account_alert, otp_or_2fa_code and so on."
        },
        "stance": {
          "type": "string",
          "enum": [
            "inbound_solicitation",
            "user_own_record",
            "ambiguous"
          ],
          "title": "Stance"
        },
        "ask": {
          "type": "string",
          "enum": [
            "none",
            "pay",
            "click_link",
            "call_back",
            "give_credentials",
            "give_code",
            "install_app",
            "reply",
            "other"
          ],
          "title": "Ask"
        },
        "scam_type": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Scam Type",
          "description": "Null until the calibrated classifier ships."
        },
        "impersonated_brand": {
          "anyOf": [
            {
              "$ref": "#/$defs/Brand"
            },
            {
              "type": "null"
            }
          ]
        },
        "probabilities": {
          "additionalProperties": {
            "additionalProperties": {
              "type": "number"
            },
            "type": "object"
          },
          "type": "object",
          "title": "Probabilities"
        }
      },
      "type": "object",
      "required": [
        "artifact_type",
        "stance",
        "ask"
      ],
      "title": "Classification"
    },
    "ComplaintStats": {
      "properties": {
        "count": {
          "type": "integer",
          "title": "Count"
        },
        "days": {
          "type": "integer",
          "title": "Days",
          "description": "Distinct days with a complaint."
        },
        "first_at": {
          "type": "string",
          "title": "First At",
          "description": "First complaint day, 00:00Z."
        },
        "last_at": {
          "type": "string",
          "title": "Last At",
          "description": "Last complaint day, 00:00Z."
        },
        "subjects": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Subjects",
          "description": "FTC: subject code (imposters, debt_reduction, ...); FCC: call type (prerecorded_voice, live_voice, text_message, ...)."
        },
        "robocall_share": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "Robocall Share",
          "description": "FTC: recorded-message flag; FCC: prerecorded-voice share."
        },
        "daily": {
          "items": {
            "$ref": "#/$defs/DailyCount"
          },
          "type": "array",
          "title": "Daily",
          "description": "The last 90 days, only days with complaints, oldest first."
        },
        "reporter_states": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Reporter States",
          "description": "Top 5 US states (USPS codes) of the people who complained."
        },
        "hours": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Hours",
          "description": "Complaints by the hour of the call, \"0\" to \"23\", every hour present: the reporter's local time as they gave it (FCC: the call time; FTC: the call time when it was not given as midnight). 13 months."
        },
        "weekdays": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Weekdays",
          "description": "Complaints by weekday of the complaint day, \"1\" (Monday) to \"7\", every day present. 13 months."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "count",
        "days",
        "first_at",
        "last_at",
        "subjects",
        "robocall_share",
        "daily",
        "reporter_states",
        "hours",
        "weekdays"
      ],
      "title": "ComplaintStats",
      "description": "One source's complaints about a number over the retained 13 months (DIRECTORY-CONTRACT.md).\nCounts only: never a complaint's text, a name or a place smaller than a state."
    },
    "DailyCount": {
      "properties": {
        "day": {
          "type": "string",
          "title": "Day",
          "description": "YYYY-MM-DD."
        },
        "count": {
          "type": "integer",
          "title": "Count"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "day",
        "count"
      ],
      "title": "DailyCount"
    },
    "DatasetRef": {
      "properties": {
        "dataset": {
          "type": "string",
          "enum": [
            "registration",
            "dns",
            "certificates",
            "web_archive",
            "threat_feeds",
            "threat_aggregates",
            "brand_registry",
            "web_pages",
            "ip_network",
            "phone_numbering",
            "us_numbering",
            "phone_complaints",
            "honeypot_lines",
            "phone_reports_de",
            "shortcodes",
            "email_providers",
            "breaches",
            "wallet_reports",
            "sanctions",
            "issuer_freezes",
            "community_reports",
            "campaigns",
            "text_model",
            "platform_pages",
            "iban_registry",
            "bank_codes",
            "app_stores",
            "short_links",
            "payment_profiles"
          ],
          "title": "Dataset"
        },
        "coverage": {
          "type": "string",
          "pattern": "^(WW|[A-Z]{2})$",
          "title": "Coverage",
          "description": "WW: worldwide. A country code (US, DE): the data describes only that country's numbers, codes or complaints."
        },
        "in_coverage": {
          "type": "boolean",
          "title": "In Coverage"
        }
      },
      "type": "object",
      "required": [
        "dataset",
        "coverage",
        "in_coverage"
      ],
      "title": "DatasetRef"
    },
    "DnsFacts": {
      "properties": {
        "resolves": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Resolves"
        },
        "a": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "A"
        },
        "mx": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Mx"
        },
        "ns": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Ns"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "DnsFacts"
    },
    "DomainFacts": {
      "properties": {
        "registrable_domain": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registrable Domain",
          "description": "The owner boundary per the Public Suffix List with its private section: x.pages.dev stays x.pages.dev. Block by this."
        },
        "registered_domain": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registered Domain",
          "description": "The name a registry sold (Public Suffix List, ICANN section): x.pages.dev -> pages.dev. registered_at, expires_at and registrar describe this name."
        },
        "tld": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Tld"
        },
        "tld_abuse": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "low",
                "medium",
                "high"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Tld Abuse"
        },
        "registered_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registered At",
          "description": "RFC 3339 UTC."
        },
        "expires_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Expires At",
          "description": "When the registration expires, RFC 3339 UTC, from RDAP."
        },
        "age_days": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Age Days"
        },
        "age_bucket": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "lt_7d",
                "d7_30",
                "d30_90",
                "d90_365",
                "gt_1y",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Age Bucket"
        },
        "registrar": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registrar",
          "description": "The registrar's name, from RDAP."
        },
        "dns": {
          "anyOf": [
            {
              "$ref": "#/$defs/DnsFacts"
            },
            {
              "type": "null"
            }
          ]
        },
        "hosting": {
          "anyOf": [
            {
              "$ref": "#/$defs/HostingFacts"
            },
            {
              "type": "null"
            }
          ],
          "description": "The hosting platform serving the host (1.9.0), null when none we know of. Says where a site lives, never whether it is honest: the platforms host real brands and fake shops alike."
        },
        "status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "live",
                "gone",
                "broken",
                "parked",
                "held",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Status",
          "description": "What the domain is doing now: live (resolves), gone (NXDOMAIN), broken (SERVFAIL: a delegation that no longer answers), parked (a parking service's name servers), held (does not resolve because its registry or registrar holds it, see hold), unknown (no answer in time)."
        },
        "cert_first_seen": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Cert First Seen"
        },
        "lookalike": {
          "anyOf": [
            {
              "$ref": "#/$defs/Lookalike"
            },
            {
              "type": "null"
            }
          ]
        },
        "platform": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "none",
                "multi_tenant"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Platform"
        },
        "allowlisted": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Allowlisted"
        },
        "listed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Listed",
          "description": "On Bewary's scam list."
        },
        "seen_in_checks_7d": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Seen In Checks 7D"
        },
        "country": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Country",
          "description": "ISO 3166-1 alpha-2 country its country-code TLD names; null for generic TLDs and generic-use ccTLDs (.co, .io, .tv...)."
        },
        "target_countries": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Target Countries",
          "description": "ISO 3166-1 alpha-2 countries whose people it is aimed at, from the national lists that name it (CERT Polska: PL, Taiwan's 165 line: TW, Germany's regulator: DE, US complaint feeds: US). Empty when no list with a national scope names it."
        },
        "list_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "List Count",
          "description": "How many lists name it (our own and others'); 96% of listed domains are on one list (2026-10-27)."
        },
        "site": {
          "anyOf": [
            {
              "$ref": "#/$defs/SiteVerdict"
            },
            {
              "type": "null"
            }
          ],
          "description": "Our verdict on the site, when our worker read its page in the last 90 days; null otherwise."
        },
        "platform_status": {
          "anyOf": [
            {
              "$ref": "#/$defs/PlatformStatus"
            },
            {
              "type": "null"
            }
          ],
          "description": "The hosting platform's own answer about the site (Vercel's takedown page, Cloudflare's phishing warning, a host's not-found page), when our worker read it; null otherwise."
        },
        "registry_status": {
          "anyOf": [
            {
              "items": {
                "type": "string",
                "enum": [
                  "active",
                  "inactive",
                  "associated",
                  "locked",
                  "validated",
                  "proxy",
                  "private",
                  "removed",
                  "obscured",
                  "add_period",
                  "auto_renew_period",
                  "renew_period",
                  "transfer_period",
                  "redemption_period",
                  "pending_create",
                  "pending_delete",
                  "pending_renew",
                  "pending_restore",
                  "pending_transfer",
                  "pending_update",
                  "client_hold",
                  "server_hold",
                  "client_delete_prohibited",
                  "client_renew_prohibited",
                  "client_transfer_prohibited",
                  "client_update_prohibited",
                  "server_delete_prohibited",
                  "server_renew_prohibited",
                  "server_transfer_prohibited",
                  "server_update_prohibited",
                  "delete_prohibited",
                  "renew_prohibited",
                  "transfer_prohibited",
                  "update_prohibited",
                  "other"
                ]
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registry Status",
          "description": "The status codes the registry publishes for registered_domain (the EPP statuses of RFC 5731 and 3915 as RDAP carries them, RFC 8056), in snake case: server_hold, client_hold, redemption_period, pending_delete, client_transfer_prohibited and the rest. Null when the registry publishes no status."
        },
        "hold": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "none",
                "registrar",
                "registry",
                "both"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Hold",
          "description": "Who holds the name out of the DNS: registry (serverHold), registrar (clientHold), both, or none. A hold is how registries and registrars take a domain down. Null when the registry's status is unknown."
        },
        "registered": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registered",
          "description": "true: the registry has registered_domain; false: the registry answered that no such name is registered (it lapsed or was deleted, and anyone may register it). Null when no registration service covers the TLD."
        },
        "registration_checked_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Registration Checked At",
          "description": "When the registration record (registered_at, expires_at, registrar, registry_status, hold) was read, RFC 3339 UTC. An answer is kept up to 7 days; a daily pass reads names on our lists again, those that stopped resolving first."
        },
        "archive": {
          "anyOf": [
            {
              "$ref": "#/$defs/ArchiveHistory"
            },
            {
              "type": "null"
            }
          ],
          "description": "The site's history in a public web archive; null until we have read it (a first lookup queues the read)."
        },
        "first_seen_by_bewary": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "First Seen By Bewary",
          "description": "When Bewary's own watch first saw this host, in a new certificate or a new name in a registry's zone file, RFC 3339 UTC; null when it never did."
        },
        "first_listed_publicly": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "First Listed Publicly",
          "description": "When a public list we read first named this host, RFC 3339 UTC; null when none names it, or when a list naming it already did the first time we read that list (the date it was added there is not known)."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "DomainFacts"
    },
    "EmailFacts": {
      "properties": {
        "domain": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Domain",
          "description": "Entity id of the address's domain."
        },
        "mx": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Mx"
        },
        "disposable": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Disposable"
        },
        "free_provider": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Free Provider"
        },
        "role_account": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Role Account"
        },
        "disposable_status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "receiving",
                "dead",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Disposable Status",
          "description": "For a throwaway provider: receiving (it still takes mail: a mail host that resolves, or the domain's own address when it has no MX, RFC 5321), dead (the name is gone, declares it takes no mail with a null MX, RFC 7505, or has no mail host that resolves), unknown (not re-checked yet). Null when not disposable."
        },
        "disposable_checked_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Disposable Checked At",
          "description": "When the throwaway domain was last re-checked, RFC 3339 UTC; null when not disposable or not checked yet."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "EmailFacts"
    },
    "Entity": {
      "properties": {
        "id": {
          "type": "string",
          "title": "Id",
          "description": "e1, e2 and so on, unique in the response."
        },
        "type": {
          "type": "string",
          "enum": [
            "url",
            "domain",
            "ip",
            "phone",
            "shortcode",
            "email",
            "wallet",
            "payment_handle",
            "iban",
            "app"
          ],
          "title": "Type"
        },
        "value": {
          "type": "string",
          "title": "Value"
        },
        "normalized": {
          "type": "string",
          "title": "Normalized"
        },
        "role": {
          "type": "string",
          "enum": [
            "sender",
            "link_target",
            "redirect_hop",
            "hosting",
            "callback_number",
            "reply_to",
            "payee",
            "mentioned",
            "unknown"
          ],
          "title": "Role"
        },
        "verdict": {
          "type": "string",
          "enum": [
            "scam",
            "suspicious",
            "safe",
            "unknown"
          ],
          "title": "Verdict"
        },
        "p_scam": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "P Scam"
        },
        "risk_score": {
          "type": "integer",
          "maximum": 100.0,
          "minimum": 0.0,
          "title": "Risk Score"
        },
        "reason_codes": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Reason Codes"
        },
        "facts": {
          "anyOf": [
            {
              "$ref": "#/$defs/UrlFacts"
            },
            {
              "$ref": "#/$defs/DomainFacts"
            },
            {
              "$ref": "#/$defs/IpFacts"
            },
            {
              "$ref": "#/$defs/PhoneFacts"
            },
            {
              "$ref": "#/$defs/ShortcodeFacts"
            },
            {
              "$ref": "#/$defs/EmailFacts"
            },
            {
              "$ref": "#/$defs/WalletFacts"
            },
            {
              "$ref": "#/$defs/PaymentHandleFacts"
            },
            {
              "$ref": "#/$defs/IbanFacts"
            },
            {
              "$ref": "#/$defs/AppFacts"
            }
          ],
          "title": "Facts",
          "description": "Typed facts for the entity's type. Every key present, null when unknown."
        },
        "related": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Related",
          "description": "Ids of linked entities: a link's domain, a redirect target."
        },
        "datasets": {
          "items": {
            "$ref": "#/$defs/DatasetRef"
          },
          "type": "array",
          "title": "Datasets",
          "description": "Every dataset checked for this entity, with its geography. in_coverage false means the dataset does not cover this entity (a US-only dataset and a non-US number), so its silence is not a clean result."
        }
      },
      "type": "object",
      "required": [
        "id",
        "type",
        "value",
        "normalized",
        "role",
        "verdict",
        "p_scam",
        "risk_score",
        "reason_codes",
        "facts",
        "related",
        "datasets"
      ],
      "title": "Entity"
    },
    "Explanation": {
      "properties": {
        "text": {
          "type": "string",
          "title": "Text"
        },
        "language": {
          "type": "string",
          "title": "Language"
        }
      },
      "type": "object",
      "required": [
        "text",
        "language"
      ],
      "title": "Explanation"
    },
    "HostingFacts": {
      "properties": {
        "platform": {
          "type": "string",
          "title": "Platform",
          "description": "Platform id: shopify, squarespace, wordpress_com, wix, vercel, render, netlify, github_pages, framer, firebase, webflow, cloudflare_pages, cloudflare_workers, gitbook, carrd, substack, heroku, fly, ghost, hubspot, zendesk, blogger, weebly, godaddy. New ids may be added."
        },
        "name": {
          "type": "string",
          "title": "Name",
          "description": "The platform's display name (Shopify, GitHub Pages)."
        },
        "by": {
          "type": "string",
          "enum": [
            "name",
            "cname",
            "address"
          ],
          "title": "By",
          "description": "How it is known: the host sits under the platform's own domain (name), its CNAME points into the platform (cname), or one of its addresses is in a network only that platform serves from (address)."
        },
        "evidence": {
          "type": "string",
          "title": "Evidence",
          "description": "The host, CNAME target or address that shows it."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "platform",
        "name",
        "by",
        "evidence"
      ],
      "title": "HostingFacts",
      "description": "The hosting platform that serves the host (1.9.0, app/hosting.py), from its name and DNS answer alone."
    },
    "IbanBank": {
      "properties": {
        "name": {
          "type": "string",
          "title": "Name",
          "description": "The bank's name as its country's list gives it."
        },
        "bic": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Bic",
          "description": "Its BIC (ISO 9362) from the same list, or null when the list has none."
        },
        "source": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Source",
          "description": "The publisher's attribution for that list, e.g. 'Source: National Bank of Belgium' (1.6.0). Show it where the bank's name is shown."
        },
        "free_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Free At",
          "description": "Where the publisher gives the list free of charge (1.6.0). Several publishers (NBB, Banka Slovenije, Banco de Espana, the ECB) require that a buyer is told the data is free at the source each time it is provided."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "name"
      ],
      "title": "IbanBank",
      "description": "The bank a national bank-code list names for the IBAN's bank code. Never the account holder."
    },
    "IbanFacts": {
      "properties": {
        "country": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Country",
          "description": "ISO 3166-1 alpha-2 from the IBAN's first two letters."
        },
        "sepa": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Sepa",
          "description": "The SWIFT IBAN registry marks the country as a SEPA country; null for a country the registry does not list."
        },
        "valid": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Valid",
          "description": "ISO 13616: a registry country, its length, its BBAN structure and the check digits (MOD 97-10)."
        },
        "invalid_reason": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "country",
                "length",
                "structure",
                "checksum"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Invalid Reason",
          "description": "The first check that failed; null when valid."
        },
        "print_form": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Print Form",
          "description": "The print format: groups of four separated by a space."
        },
        "bank_code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Bank Code",
          "description": "The bank identifier at its country's position in the BBAN (SWIFT IBAN registry); null unless valid."
        },
        "branch_code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Branch Code",
          "description": "The branch identifier where the country has one; null unless valid."
        },
        "bank": {
          "anyOf": [
            {
              "$ref": "#/$defs/IbanBank"
            },
            {
              "type": "null"
            }
          ],
          "description": "The bank its country's national list names for bank_code; null when we hold no list for the country (the entity's bank_codes dataset then has in_coverage false) or the code is not in it."
        },
        "listed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Listed",
          "description": "On Bewary's scam list: a community report named this account."
        },
        "list_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "List Count",
          "description": "How many lists name it (our own and others'); 96% of listed domains are on one list (2026-10-27)."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "IbanFacts",
      "description": "An IBAN (task E11, added 2026-10-29): the account number's validity and its bank, never its holder."
    },
    "InputInfo": {
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "lookup",
            "message",
            "screenshot"
          ],
          "title": "Kind"
        },
        "channel": {
          "type": "string",
          "enum": [
            "sms",
            "email",
            "web",
            "voice",
            "social_dm",
            "messaging_app",
            "unknown"
          ],
          "title": "Channel"
        },
        "language": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Language"
        },
        "region": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Region"
        }
      },
      "type": "object",
      "required": [
        "kind",
        "channel"
      ],
      "title": "InputInfo"
    },
    "IpFacts": {
      "properties": {
        "version": {
          "anyOf": [
            {
              "type": "integer",
              "enum": [
                4,
                6
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Version"
        },
        "asn": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Asn"
        },
        "as_org": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "As Org"
        },
        "country": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Country",
          "description": "Registry country of the address block."
        },
        "hosting_type": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "datacenter",
                "cdn",
                "residential",
                "mobile",
                "business",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Hosting Type"
        },
        "reverse_dns": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Reverse Dns"
        },
        "listed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Listed"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "IpFacts"
    },
    "Lookalike": {
      "properties": {
        "brand_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Brand Id"
        },
        "technique": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "homoglyph",
                "typo",
                "brand_word",
                "brand_scam_word",
                "subdomain",
                "tld_swap",
                "userinfo"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Technique"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "Lookalike"
    },
    "ModelsUsed": {
      "properties": {
        "judge": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Judge"
        },
        "vision": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Vision"
        },
        "verify": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Verify"
        },
        "deep_tools": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Deep Tools"
        },
        "calibration": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Calibration"
        }
      },
      "additionalProperties": true,
      "type": "object",
      "title": "ModelsUsed"
    },
    "NumberLink": {
      "properties": {
        "e164": {
          "type": "string",
          "title": "E164"
        },
        "reports": {
          "type": "integer",
          "title": "Reports"
        },
        "indexable": {
          "type": "boolean",
          "title": "Indexable",
          "description": "The linked number has a page: the index rule, inside the current wave."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "e164",
        "reports",
        "indexable"
      ],
      "title": "NumberLink"
    },
    "Operator": {
      "properties": {
        "name": {
          "type": "string",
          "title": "Name"
        },
        "brand_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Brand Id"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "name"
      ],
      "title": "Operator"
    },
    "PageFacts": {
      "properties": {
        "analyzed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Analyzed",
          "description": "The page was read (deep=true only)."
        },
        "title_present": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Title Present"
        },
        "has_login_form": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Has Login Form"
        },
        "has_payment_form": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Has Payment Form"
        },
        "brand_shown": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Brand Shown",
          "description": "Brand id the page shows, if any."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "PageFacts"
    },
    "PaymentHandleFacts": {
      "properties": {
        "provider": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "cashapp",
                "venmo",
                "zelle",
                "paypal",
                "other"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Provider"
        },
        "handle": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Handle",
          "description": "The handle, lowercase, without $ or @."
        },
        "reports": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Reports"
        },
        "status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "active",
                "inactive",
                "not_found",
                "refused",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Status",
          "description": "From the service's public profile page (E8, added 2026-10-29): active (a profile is shown), inactive (the service shows the profile as not active: PayPal only), not_found (no profile under this name: never made, or closed), refused (the service refused our read), unknown (no answer we can read). Existence and status only: never the name, photo or anything else on the page. Null for a provider we do not read."
        },
        "status_checked_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Status Checked At",
          "description": "When the profile page was read, RFC 3339 UTC."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "PaymentHandleFacts"
    },
    "PhoneComplaints": {
      "properties": {
        "ftc": {
          "anyOf": [
            {
              "$ref": "#/$defs/ComplaintStats"
            },
            {
              "type": "null"
            }
          ]
        },
        "fcc": {
          "anyOf": [
            {
              "$ref": "#/$defs/ComplaintStats"
            },
            {
              "type": "null"
            }
          ]
        },
        "callbacks": {
          "anyOf": [
            {
              "items": {
                "$ref": "#/$defs/NumberLink"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Callbacks",
          "description": "FCC: the callback numbers calls from this number told people to call, most reports first, at most 5; null when none."
        },
        "pushed_by": {
          "anyOf": [
            {
              "$ref": "#/$defs/PushedBy"
            },
            {
              "type": "null"
            }
          ],
          "description": "FCC: this number as the callback number in other numbers' calls; null when it never was one."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "PhoneComplaints"
    },
    "PhoneFacts": {
      "properties": {
        "e164": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "E164"
        },
        "country": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Country"
        },
        "number_type": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "mobile",
                "landline",
                "voip",
                "toll_free",
                "premium",
                "shared_cost",
                "shortcode",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Number Type"
        },
        "original_carrier": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Original Carrier"
        },
        "line_type": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "mobile",
                "landline",
                "voip",
                "toll_free",
                "premium",
                "shared_cost",
                "shortcode",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Line Type"
        },
        "complaints": {
          "anyOf": [
            {
              "$ref": "#/$defs/PhoneComplaints"
            },
            {
              "type": "null"
            }
          ],
          "description": "FTC and FCC complaints; null when the directory could not be read."
        },
        "honeypot_hits_30d": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Honeypot Hits 30D"
        },
        "listed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Listed"
        },
        "public_listing": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "business",
                "personal",
                "none",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Public Listing",
          "description": "Never a person's name."
        },
        "indexable": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Indexable",
          "description": "The number has a directory page: it meets the index rule (two independent signals) and is inside the current wave."
        },
        "target_countries": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Target Countries",
          "description": "ISO 3166-1 alpha-2 countries whose people it is aimed at, from the national lists that name it (CERT Polska: PL, Taiwan's 165 line: TW, Germany's regulator: DE, US complaint feeds: US). Empty when no list with a national scope names it."
        },
        "list_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "List Count",
          "description": "How many lists name it (our own and others'); 96% of listed domains are on one list (2026-10-27)."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "PhoneFacts"
    },
    "PlatformStatus": {
      "properties": {
        "platform": {
          "type": "string",
          "enum": [
            "vercel",
            "netlify",
            "cloudflare",
            "github_pages",
            "firebase",
            "render",
            "glitch",
            "blogger",
            "gitbook",
            "godaddy_sites",
            "lovable",
            "heroku",
            "surge",
            "replit",
            "framer",
            "weebly",
            "square_online",
            "wix",
            "webflow",
            "canva_sites",
            "google_docs",
            "linktree",
            "jotform",
            "microsoft_forms",
            "typeform"
          ],
          "title": "Platform"
        },
        "status": {
          "type": "string",
          "enum": [
            "taken_down",
            "warning",
            "not_found",
            "suspended"
          ],
          "title": "Status",
          "description": "taken_down: the platform's page says it removed or blocked it for abuse or a terms violation. warning: the platform shows its own phishing or malware warning in front of it. not_found: the platform serves nothing here (never made, deleted by its owner, or removed without saying why: most hosts show one page for all three). suspended: paused for its owner's plan or usage, or by its owner; not a verdict on the site."
        },
        "read_at": {
          "type": "string",
          "title": "Read At",
          "description": "The newest read that showed this page, RFC 3339 UTC."
        },
        "flagged_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Flagged At",
          "description": "The first read that showed the platform's takedown page (else its warning page) since the site was last seen live, RFC 3339 UTC. Kept when the platform later deletes the site; null if it never flagged it."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "platform",
        "status",
        "read_at"
      ],
      "title": "PlatformStatus",
      "description": "What the hosting or form platform itself serves here, from a page our own worker read in the last 90 days\n(E5/E7). Only the platform's own pages count; a live page read after them clears the fact."
    },
    "PushedBy": {
      "properties": {
        "reports": {
          "type": "integer",
          "title": "Reports",
          "description": "Complaints that named this number as the callback number."
        },
        "days": {
          "type": "integer",
          "title": "Days",
          "description": "Distinct days with such a complaint."
        },
        "callers": {
          "type": "integer",
          "title": "Callers",
          "description": "Distinct caller IDs that pushed it (complaints with no caller ID not counted)."
        },
        "first_at": {
          "type": "string",
          "title": "First At",
          "description": "First such day, 00:00Z."
        },
        "last_at": {
          "type": "string",
          "title": "Last At",
          "description": "Last such day, 00:00Z."
        },
        "subjects": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Subjects",
          "description": "The FCC call types of those complaints (prerecorded_voice, live_voice, text_message, ...), most first."
        },
        "daily": {
          "items": {
            "$ref": "#/$defs/DailyCount"
          },
          "type": "array",
          "title": "Daily",
          "description": "The last 90 days, only days with reports, oldest first."
        },
        "hours": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Hours",
          "description": "Reports by the hour of the call, \"0\" to \"23\", every hour present."
        },
        "weekdays": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Weekdays",
          "description": "Reports by weekday, \"1\" (Monday) to \"7\", every day present."
        },
        "reporter_states": {
          "additionalProperties": {
            "type": "integer"
          },
          "type": "object",
          "title": "Reporter States",
          "description": "Top 5 US states (USPS codes) of the people who complained."
        },
        "top": {
          "items": {
            "$ref": "#/$defs/NumberLink"
          },
          "type": "array",
          "title": "Top",
          "description": "The caller IDs that pushed it, most reports first, at most 20."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "reports",
        "days",
        "callers",
        "first_at",
        "last_at",
        "subjects",
        "daily",
        "hours",
        "weekdays",
        "reporter_states",
        "top"
      ],
      "title": "PushedBy",
      "description": "A number as the callback number other numbers' calls told people to call (FCC)."
    },
    "RedirectHop": {
      "properties": {
        "url": {
          "type": "string",
          "title": "Url",
          "description": "A short link we read: the link itself, then any other short link it led to."
        },
        "status": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Status",
          "description": "The HTTP status the shortener answered. The destination is never requested, so it is final_url, not a hop."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "url"
      ],
      "title": "RedirectHop"
    },
    "ShortLink": {
      "properties": {
        "service": {
          "type": "string",
          "enum": [
            "bit.ly",
            "tinyurl.com",
            "is.gd",
            "v.gd",
            "cutt.ly",
            "rebrand.ly",
            "t.ly",
            "ow.ly",
            "shorturl.at",
            "tiny.cc",
            "t.co",
            "qrco.de",
            "surl.li",
            "u.to",
            "zpr.io",
            "vk.cc",
            "clck.ru",
            "other"
          ],
          "title": "Service",
          "description": "The shortening service, named by its main short domain (j.mp is bit.ly, rb.gy is rebrand.ly, q-r.to and l.ead.me are qrco.de). other: a shortener we follow but whose block and warning pages are not measured."
        },
        "state": {
          "type": "string",
          "enum": [
            "active",
            "warning",
            "disabled",
            "removed",
            "not_found",
            "hosted",
            "refused",
            "unknown"
          ],
          "title": "State",
          "description": "active: it redirects to final_url. warning: it shows its own warning page before the destination. disabled: the shortener disabled the link and says why (reason). removed: the link existed and no longer works, no reason given. not_found: the service has no such link. hosted: the service answers with a page of its own instead of a redirect. refused: the service refused our read. unknown: no answer we can read."
        },
        "reason": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "terms",
                "account_suspended",
                "threat"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Reason",
          "description": "When disabled: it broke the service's rules (terms), the account that made it was suspended for abuse (account_suspended), or the service flagged it as harmful (threat). Null otherwise."
        },
        "read_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Read At",
          "description": "When the shortener's answer was read, RFC 3339 UTC."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "service",
        "state"
      ],
      "title": "ShortLink",
      "description": "What the shortener itself says about the link, read from its own answer (E3, added 2026-10-29)."
    },
    "ShortcodeFacts": {
      "properties": {
        "code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Code"
        },
        "country": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Country"
        },
        "status": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "legitimate",
                "mixed",
                "scam",
                "unknown"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Status"
        },
        "operator": {
          "anyOf": [
            {
              "$ref": "#/$defs/Operator"
            },
            {
              "type": "null"
            }
          ]
        },
        "legit_uses": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Legit Uses"
        },
        "reports_30d": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Reports 30D"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "ShortcodeFacts"
    },
    "Signal": {
      "properties": {
        "code": {
          "type": "string",
          "title": "Code",
          "description": "A stable reason code, https://bewary.app/docs/reason-codes"
        },
        "entity": {
          "type": "string",
          "title": "Entity",
          "description": "The entity id, or \"message\"."
        },
        "severity": {
          "type": "string",
          "enum": [
            "info",
            "low",
            "medium",
            "high",
            "critical"
          ],
          "title": "Severity"
        },
        "weight": {
          "type": "number",
          "title": "Weight",
          "description": "Signed contribution: positive toward scam, negative reassuring."
        },
        "source_class": {
          "type": "string",
          "enum": [
            "confirmed",
            "first_party",
            "heuristic",
            "model",
            "attacker_content"
          ],
          "title": "Source Class"
        },
        "p": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "P",
          "description": "Model probability when source_class is model."
        },
        "dataset": {
          "type": "string",
          "enum": [
            "registration",
            "dns",
            "certificates",
            "web_archive",
            "threat_feeds",
            "threat_aggregates",
            "brand_registry",
            "web_pages",
            "ip_network",
            "phone_numbering",
            "us_numbering",
            "phone_complaints",
            "honeypot_lines",
            "phone_reports_de",
            "shortcodes",
            "email_providers",
            "breaches",
            "wallet_reports",
            "sanctions",
            "issuer_freezes",
            "community_reports",
            "campaigns",
            "text_model",
            "platform_pages",
            "iban_registry",
            "bank_codes",
            "app_stores",
            "short_links",
            "payment_profiles"
          ],
          "title": "Dataset",
          "description": "The dataset the signal came from, https://bewary.app/data"
        },
        "coverage": {
          "type": "string",
          "pattern": "^(WW|[A-Z]{2})$",
          "title": "Coverage",
          "description": "That dataset's geography: WW (worldwide) or a country code (US, DE)."
        },
        "evidence": {
          "additionalProperties": true,
          "type": "object",
          "title": "Evidence"
        }
      },
      "type": "object",
      "required": [
        "code",
        "entity",
        "severity",
        "weight",
        "source_class",
        "dataset",
        "coverage",
        "evidence"
      ],
      "title": "Signal"
    },
    "SiteBand": {
      "properties": {
        "score_from": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "Score From",
          "description": "The band's lowest score (inclusive)."
        },
        "score_to": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "Score To",
          "description": "The band's highest score (exclusive, but 1.0 is in the top band)."
        },
        "hosts": {
          "type": "integer",
          "minimum": 0.0,
          "title": "Hosts",
          "description": "Labelled hosts whose score fell in this band."
        },
        "scam_sites": {
          "type": "integer",
          "minimum": 0.0,
          "title": "Scam Sites",
          "description": "How many of them were scam or compromised sites."
        },
        "p_low": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "P Low",
          "description": "95% interval of the band's scam share, low end (Clopper-Pearson)."
        },
        "p_high": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "P High",
          "description": "95% interval of the band's scam share, high end."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "score_from",
        "score_to",
        "hosts",
        "scam_sites",
        "p_low",
        "p_high"
      ],
      "title": "SiteBand",
      "description": "The score band a site's score fell in, and what the labelled hosts in it turned out to be (1.4.0)."
    },
    "SiteVerdict": {
      "properties": {
        "read_at": {
          "type": "string",
          "title": "Read At",
          "description": "When our worker read the page, RFC 3339 UTC."
        },
        "scam_site": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Scam Site",
          "description": "Null: no call is made from the score (a call would need the precision PRECISION.md proves first). Only an operator's `live` mode, not used, sets it."
        },
        "p_scam_site": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "P Scam Site",
          "description": "The calibrated probability that the site is a scam site: the share of labelled hosts in `band` that were, estimated (k + 1/2) / (n + 1) and monotone in the score."
        },
        "score": {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0,
          "title": "Score",
          "description": "The model's raw answer, a ranking score, not a probability."
        },
        "band": {
          "$ref": "#/$defs/SiteBand",
          "description": "The score band and its labelled counts and interval."
        },
        "calibration": {
          "type": "string",
          "title": "Calibration",
          "description": "The calibration fit used, e.g. site-cal-20261030-702."
        },
        "reasons": {
          "items": {
            "type": "string",
            "enum": [
              "impersonates",
              "throwaway_name",
              "claim_vs_age",
              "asks_sensitive",
              "too_good"
            ]
          },
          "type": "array",
          "title": "Reasons",
          "description": "When the score is at or above the threshold frozen before the blind test: what the page does, as the model read it (pretends to be an organisation it is not, a throwaway name, claims an established business on a young domain, asks for sensitive details or a payment, too good to be true). Empty otherwise."
        },
        "template_hosts": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Template Hosts",
          "description": "How many other hosts we read whose page has this page's template (a campaign's sites share one)."
        },
        "version": {
          "type": "string",
          "title": "Version",
          "description": "The verdict's question set, e.g. d2."
        },
        "model": {
          "type": "string",
          "title": "Model",
          "description": "The pinned model that answered, e.g. jev-1.14.0."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "read_at",
        "p_scam_site",
        "score",
        "band",
        "calibration",
        "reasons",
        "version",
        "model"
      ],
      "title": "SiteVerdict",
      "description": "Our reading of the site at this host, from a page our own worker read (added 2026-10-28; calibrated 1.4.0).\nJev reads the page together with the domain's facts. Its score ranks scam sites well (AUC 0.915 on a blind round)\nbut is not a probability, so `p_scam_site` is the measured scam share of labelled hosts in the same score band\n(docs/b2b/PRECISION.md, GET /v1/calibration/site). It never changes the entity's verdict."
    },
    "UrlFacts": {
      "properties": {
        "scheme": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "http",
                "https",
                "other"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Scheme"
        },
        "host": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Host",
          "description": "Entity id of the link's domain."
        },
        "final_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Final Url",
          "description": "Where the link lands after shorteners and redirects."
        },
        "redirect_chain": {
          "anyOf": [
            {
              "items": {
                "$ref": "#/$defs/RedirectHop"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Redirect Chain",
          "description": "The short links read on the way, in order."
        },
        "shortener": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Shortener"
        },
        "redirect_resolved": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Redirect Resolved"
        },
        "short_link": {
          "anyOf": [
            {
              "$ref": "#/$defs/ShortLink"
            },
            {
              "type": "null"
            }
          ],
          "description": "On a shortener: the link's state as the shortener answers it. Null for a link that is not on a shortener."
        },
        "page": {
          "anyOf": [
            {
              "$ref": "#/$defs/PageFacts"
            },
            {
              "type": "null"
            }
          ]
        },
        "target_countries": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Target Countries",
          "description": "ISO 3166-1 alpha-2 countries whose people it is aimed at, from the national lists that name it (CERT Polska: PL, Taiwan's 165 line: TW, Germany's regulator: DE, US complaint feeds: US). Empty when no list with a national scope names it."
        },
        "list_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "List Count",
          "description": "How many lists name it (our own and others'); 96% of listed domains are on one list (2026-10-27)."
        },
        "platform_status": {
          "anyOf": [
            {
              "$ref": "#/$defs/PlatformStatus"
            },
            {
              "type": "null"
            }
          ],
          "description": "A form or link-in-bio platform's own answer about this one URL (a Google form, a Linktree profile, a Jotform form). A hosting platform's answer about the whole site is on the host's domain entity."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "UrlFacts"
    },
    "WalletFacts": {
      "properties": {
        "chain": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "btc",
                "eth",
                "trx",
                "ltc",
                "sol",
                "xmr",
                "dash"
              ]
            },
            {
              "type": "null"
            }
          ],
          "title": "Chain",
          "description": "From the address format; eth is any EVM address (the same address exists on every EVM chain)."
        },
        "caip2": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Caip2",
          "description": "CAIP-2 chain id where the chain is fixed (bip122:..., solana:...)."
        },
        "listed": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Listed"
        },
        "sanctioned": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Sanctioned",
          "description": "On a US sanctions list (added 1.1.0)."
        },
        "frozen_by_issuer": {
          "anyOf": [
            {
              "items": {
                "type": "string",
                "enum": [
                  "tether",
                  "circle"
                ]
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "title": "Frozen By Issuer",
          "description": "Stablecoin issuers whose token contract has this address frozen now (Tether: USDT on Tron and Ethereum; Circle: USDC on Ethereum), read from the contracts' own events; [] when checked and not frozen. Issuers do not publish why (1.9.0)."
        },
        "reports": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "Reports"
        },
        "list_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "title": "List Count",
          "description": "How many lists name it (our own and others'); 96% of listed domains are on one list (2026-10-27)."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "title": "WalletFacts"
    }
  }
}