POST/v1/validate

Run a TrustCheck

Submit one or more pieces of identity input — a name plus any combination of emails, phones, or addresses — and get back a scored verification with per-field match status, sub-scores, history, and an overall verdict. TrustMatch generates the request_id for you; you don't need to mint or pass an identifier.

Authentication

Send your key as either X-API-Key: tm_... or Authorization: Bearer tm_.... Each successful call counts against your monthly included quota; calls beyond your plan's included calls are billed as overage on your next invoice.

Request body

At minimum you must include a name. Adding email and phone dramatically improves the score's precision because TrustMatch can cross-reference identities.

Request Body

ParamTypeRequiredDescription
operation"validate" | "raw"OPTDefaults to validate (returns the scored TrustMatch response). Pass raw to also include the upstream identity-graph payload for debugging.
nameAddressesNameAddress[]YESAt least one entry with a fullName. Optional structured address per entry (line1, city, region, postalCode, countryCode). Up to 5 entries.
emailAddressesstring[]OPTUp to 5 email addresses. Lowercased and validated server-side.
phoneNumbersstring[]OPTUp to 5 phone numbers (10–15 digits). Non-digit characters are stripped before validation.
intentstring (enum)OPTOptional. Biases the AI narrative without changing the numeric score. One of: online-dating, buying-or-selling, sending-money, suspected-scam, reconnecting, general. Unknown values fall back to general. Has no effect unless ?ai=true or /v1/validate/enhanced is used.

Example request

{
  "operation": "validate",
  "nameAddresses": [
    { "fullName": "Jane Doe" }
  ],
  "emailAddresses": ["jane@example.com"],
  "phoneNumbers": ["+15551234567"]
}

Response

Response Model

200 OKContent-Type: application/json
{
  "success": true,
  "request_id": "5f3c8b1e-2a4d-4e9c-b6a1-9c7e3f1d8b25",
  "trustworthiness_score": 87,
  "status": "HIGH",
  "confidence_level": "HIGH",
  "possible_catfish": false,
  "summary": "Identity matched across name, email and phone.",
  "input_validation": {
    "name":  { "input": "Jane Doe",          "match_status": "Primary Match",  "matched_identity": 1, "is_primary": "Yes",  "match_message": "VERIFIED MATCH: Name matches the primary verified identity." },
    "email": { "input": "jane@example.com",  "match_status": "Primary Match",  "matched_identity": 1, "is_primary": "Yes",  "match_message": "VERIFIED MATCH: Email matches the primary verified identity." },
    "phone": {
      "input": "15551234567",
      "match_status": "Primary Match",
      "matched_identity": 1,
      "is_primary": "Yes",
      "match_message": "VERIFIED MATCH: Phone matches the primary verified identity.",
      "inputs": [
        { "input": "15551234567", "standardized": "+15551234567", "match_status": "Primary Match", "matched_identity": 1, "is_primary": "Yes", "validated": true }
      ]
    },
    "overall_match": { "all_components_match_same_identity": true, "matched_identity": 1 }
  },
  "identity_score":      { "final": 90, "raw": 90, "match_flags": { "name": "Primary Match", "email": "Primary Match", "phone": "Primary Match" } },
  "trust_score":         { "final": 85, "raw": 85, "reasons": ["Identity history: 4+ years", "No recent risk signals"] },
  "combined_trust_score":{ "final": 87, "pre_capped": 87, "confidence_level_label": "high", "explanation": "Strong cross-channel match with established history." },
  "verification_flags": [],
  "insights": [],
  "history": {
    "first_seen": "2021-08-14T00:00:00Z",
    "last_seen": "2026-04-30T00:00:00Z",
    "days_since_first_seen": 1721,
    "days_since_last_seen": 14
  }
}

Notes

  • request_id is server-generated. Use it to look up this call later or correlate logs.
  • trustworthiness_score is 0–100. Verdicts: 85+ = VERIFIED, 65–84 = LIKELY REAL, 40–64 = SUSPICIOUS, below 40 = HIGH RISK.
  • Unverifiedmeans “no matching record” — not “this failed a check”. It means the identity graph returned nothing it could link to that value. A phone that is real, in service, and genuinely belongs to the person still returns Unverified if it has never appeared in the underlying data. Render it as no record. Do not render it as invalid, suspicious, or could not be verified — those assert a negative finding about a named individual that this response does not support. A value that genuinely belongs to someone else is a different status: Different Identity Match (ID n).
  • Submitting more than one value for a field? Read input_validation.<field>.inputs[] — it carries one row per submitted value. The field-level match_status and match_message are collapsed across every value you sent, and input names only the single value the identity graph resolved against — never treat that pair as a verdict about the other values. Key rows by input, not position: phones are stripped to digits before matching.

Intent — tailoring the AI narrative

The optional intent field tells TrustMatch what situation the check is for. The Gemini overview adjusts its positive_signals, risk_factors, and recommended_actions to match — the same scores get a different story. The numeric trustworthiness_score and signal status flags are intent-agnostic.

intent valueWhen to use it
online-datingUser is vetting a romantic interest from a dating app, DM, or long-distance contact.
buying-or-sellingUser is about to do a peer-to-peer commerce transaction (Marketplace, OfferUp, watches, cars, tickets).
sending-moneyUser is about to send funds (Zelle, Venmo, crypto, gift cards, vendor deposits, GoFundMe).
suspected-scamUser already suspects fraud. The AI leads with red flags instead of balancing the verdict.
reconnectingUser is verifying a claimed identity from a returning contact, old friend, or claimed family.
generalDefault. Balanced verdict with no use-case bias. Use when none of the above fit.
Note: Intent only changes the AI narrative. Without ?ai=true or /v1/validate/enhanced, intent is recorded but has no visible effect — the base response shape is unchanged.

AI enhancement

TrustMatch can layer a Gemini-powered analysis on top of any verification. Two opt-in modes, same endpoint, same auth:

POST/v1/validate?ai=true

Light AI — adds a narrative overview and refined insights on top of the regular response. Body and auth are identical to a plain call; just append the query flag.

POST/v1/validate/enhanced

Full AI — runs the complete analysis pipeline: trust enhancement, fraud-pattern detection, name matching, and the overview narrative. Same request body shape as /v1/validate.

Request — call with AI enabled

curl -X POST "https://api.trustmatch.app/v1/validate?ai=true" \
  -H "X-API-Key: tm_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "validate",
    "nameAddresses": [{ "fullName": "Jane Doe" }],
    "emailAddresses": ["jane@example.com"],
    "phoneNumbers": ["+15551234567"],
    "intent": "online-dating"
  }'

Response — same as above, plus ai_insights

{
  "request_id": "5f3c8b1e-2a4d-...",
  "trustworthiness_score": 87,
  "status": "HIGH",
  /* …all the normal fields… */
  "ai_insights": {
    "ai_enabled": true,
    "trust_enhancement": {
      "overview": "Strong cross-channel identity match with established history.",
      "risk_assessment": "low",
      "confidence_adjustment": "+2",
      "reasoning": "All three contact channels match the same dominant identity..."
    },
    "intent": "online-dating",
    "overview": {
      "overview": "Jane Doe’s identity verifies cleanly across name, email and phone — no catfish signals.",
      "key_findings": [
        "Three contact channels resolve to the same dominant identity.",
        "Identity history spans 4+ years — well above the catfish threshold."
      ],
      "positive_signals": [
        "Email and phone both match primary identity.",
        "Established history is inconsistent with romance-scam patterns."
      ],
      "risk_factors": [],
      "recommended_actions": [
        "Video chat before any in-person meeting.",
        "First meet in a public place — don’t accept rides.",
        "Even with a strong verification, never send money to someone you haven’t met."
      ],
      "review_priority": "AUTO_APPROVE"
    }
  }
}

With /v1/validate/enhanced, the same response also includes ai_insights.fraud_detection and ai_insights.name_matching.

Field reference

  • overview.overview — 1–2 sentence headline summary, safe to show to end users.
  • overview.positive_signals[] — verified facts that raise confidence (max 5 items).
  • overview.risk_factors[] — flagged concerns; empty when none are detected.
  • overview.recommended_actions[] — suggested next steps; use these to drive your own UI checklist.
  • overview.review_priority — one of AUTO_APPROVE, MANUAL_REVIEW, AUTO_REJECT. Treat as a hint, not a decision.
  • ai_insights.ai_enabledtrue when the AI call succeeded. If false, the base response is still valid and complete — treat the AI block as a soft-failure.
Billing: AI-enabled calls count as one regular check against your plan. There is no separate AI tariff today. We may price AI separately if token costs grow — current dev plans include AI use at no surcharge.