VouchHound.

VouchHound API

Real-time merchant trust scoring. Cross-checks five independent signals — domain history, web presence, certificate transparency, payment integration, and content authenticity — to score how trustworthy a store actually is.

The API is built for AI agent platforms that need to verify merchants in milliseconds before transacting on a user's behalf, fraud and trust teams at marketplaces who want to triage risky listings, and integrators building consumer-facing shopping tools.

One request, one composite score. No SDK to learn, no model to host, no calibration to maintain.

Authentication

All API requests are authenticated with an API key passed as a Bearer token in the Authorization header.

Authorization: Bearer vh_test_YOUR_KEY_HERE

Keys are scoped to a single account and tier. They look like vh_test_… and are shown to you exactly once at creation — store them in a secrets manager, not source control.

Getting an API key. We're in private beta. Email hello@vouchhound.com and we'll get back to you within one business day with a key and tier assignment.

Quickstart

The simplest possible call — paste your key in, run it, get a trust score back.

curl -X POST https://api.vouchhound.com/v1/score \
  -H "Authorization: Bearer vh_test_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"url": "allbirds.com"}'

Returns a JSON envelope with the composite trust score, a verdict, and a breakdown of which signals contributed. Full schema below.

POST /v1/score

POST https://api.vouchhound.com/v1/score

Run all signals against a single URL and return a composite trust score with a breakdown of contributions.

Request body

FieldTypeDescription
url string, required The store URL to score. Bare domains, full URLs, with or without https://, with or without paths — all work. Maximum 500 characters.

Response body

Every response is wrapped in a stable envelope. The fields you'll most often care about live under data.

FieldTypeDescription
version string API version that produced this response. Currently always "v1".
request_id string Unique identifier for this request (echoes the X-Request-Id header). Include this when reporting issues.
computed_at string (ISO 8601) When the scoring finished, in UTC.
data.url string The URL that was scored, echoed from the request.
data.trust_score integer 0–100 Composite trust score. Higher means more trustworthy.
data.verdict enum One of trusted, caution, high_risk, insufficient_data.
data.confidence number 0–1 How much of the underlying signal evidence we successfully gathered. Lower confidence means more signals were unavailable.
data.top_positive_signals array<string> Human-readable reasons supporting trust, ordered by contribution.
data.top_negative_signals array<string> Human-readable reasons supporting risk, ordered by contribution.
data.signal_data object Raw output from each underlying signal, keyed by signal name. Useful for clients that want to render signal-level detail.
data.errors array<string> Signals that failed to gather data this request. Missing signals lower confidence but never penalize the score.

Example request

POST /v1/score HTTP/1.1
Host: api.vouchhound.com
Authorization: Bearer vh_test_YOUR_KEY_HERE
Content-Type: application/json

{"url": "allbirds.com"}

Example response

{
  "version": "v1",
  "request_id": "req_7498cd8ea636474db24226dea38b6b98",
  "computed_at": "2026-05-27T01:44:39Z",
  "data": {
    "url": "allbirds.com",
    "trust_score": 90,
    "verdict": "trusted",
    "confidence": 0.9,
    "top_positive_signals": [
      "Established e-commerce setup on Shopify with: Apple Pay, Shopify Payments",
      "Site has been crawled since 2000-06-20 (25.9y ago)",
      "About page reads as human-written (15/100)",
      "Domain registered 24.4y ago"
    ],
    "top_negative_signals": [],
    "signal_data": {
      "domain_age": { "creation_date": "2002-01-09", "age_years": 24.4 },
      "wayback_first_seen": { "first_seen": "2000-06-20", "first_seen_years_ago": 25.9 },
      "payment_providers": {
        "platform": "Shopify",
        "providers_detected": ["Apple Pay", "Shopify Payments"],
        "checkout_accessible": true
      },
      "about_page_ai_detection": {
        "verdict": "likely_human",
        "ai_generation_likelihood": 15
      }
    },
    "errors": []
  }
}

Code examples

Complete, paste-and-run examples in three languages. Replace the API key placeholder with the one you got from hello@vouchhound.com.

curl -X POST https://api.vouchhound.com/v1/score \
  -H "Authorization: Bearer vh_test_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"url": "allbirds.com"}' \
  | jq .data.trust_score
import os
import requests

API_KEY = os.environ['VOUCHHOUND_API_KEY']  # or paste directly for testing

resp = requests.post(
    'https://api.vouchhound.com/v1/score',
    headers={
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json',
    },
    json={'url': 'allbirds.com'},
    timeout=30,
)
resp.raise_for_status()

body = resp.json()
data = body['data']
print(f"{data['url']}: {data['trust_score']}/100 — {data['verdict']}")
for signal in data['top_positive_signals']:
    print(f'  + {signal}')
// Node.js 18+ (native fetch). No dependencies.
const API_KEY = process.env.VOUCHHOUND_API_KEY;

const resp = await fetch('https://api.vouchhound.com/v1/score', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ url: 'allbirds.com' }),
});

if (!resp.ok) {
  throw new Error(`VouchHound API error ${resp.status}: ${await resp.text()}`);
}

const body = await resp.json();
const { data } = body;
console.log(`${data.url}: ${data.trust_score}/100 — ${data.verdict}`);
for (const signal of data.top_positive_signals) {
  console.log(`  + ${signal}`);
}

Errors

All errors follow a consistent shape. Switch on error.code — it's the stable machine-readable identifier. error.message is human-readable and may change wording without notice.

{
  "detail": {
    "error": {
      "code": "rate_limit_exceeded",
      "message": "You've used 100 of your 100 daily requests. Limit resets at 2026-05-28T01:44:39+00:00.",
      "docs_url": "https://vouchhound.com/docs/errors#rate_limit_exceeded",
      "limit": 100,
      "used": 100,
      "reset_at": "2026-05-28T01:44:39+00:00"
    }
  }
}
HTTPerror.codeMeaning
400 invalid_url The url field was missing, empty, or longer than 500 characters.
401 missing_api_key No Authorization: Bearer header was provided.
401 invalid_api_key The provided API key was not recognized.
401 revoked_api_key This key has been revoked. Request a new one from hello@vouchhound.com.
429 rate_limit_exceeded The daily call limit for your key's tier has been reached. The error body includes limit, used, and reset_at.
500 scoring_failed An internal error occurred while scoring. Include the X-Request-Id header value when reporting.

Rate limits

Per-key, rolling 24-hour window. Every API response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so well-behaved clients can back off intelligently before getting throttled.

TierDaily callsHow to get it
free 100 Available immediately on key creation.
pro 10,000 Email hello@vouchhound.com with your use case.
enterprise Custom Talk to us. Volume pricing, dedicated capacity, SLAs.

Response times

Honest disclosure: a typical /v1/score call takes 5–10 seconds. We run five independent signal checks in parallel (WHOIS, Wayback Machine, Certificate Transparency, payment integration scan, and an LLM-backed authenticity check on the About page), and the slowest one sets the wall-clock floor.

We're actively working on a sub-3-second tier — primarily through aggressive caching of stable signals (domain age, web presence, certificate history all change rarely) and dropping the slowest of the third-party calls behind a faster fallback. Subscribe to the API changelog at hello@vouchhound.com to hear when that lands.

If latency matters: set client-side timeouts at 30s, not 5s. The 5–10s number is the typical case; the long tail (when a third-party API is degraded) can extend to 25s. The X-Response-Time-ms response header gives you the exact server-side time for any given request.

Known limitations

VouchHound is calibrated for verifying lesser-known merchants — the merchants AI agents and shoppers most need help evaluating. We're explicit about where the system currently underperforms:

  • Enterprise brands with custom payment infrastructure. Major retailers (Nike, Apple, Lululemon, Costco) often process payments through Adyen, Cybersource, or in-house systems rather than Stripe or Shopify. Our payment-provider detection currently misses these, which can produce false negatives on otherwise well-established sites. We're working on this.
  • Sites with aggressive bot protection. Some sites block automated trust-checking. We treat ≥2 blocked signals as a fraud signal — correct for most cases, but can occasionally produce false positives on legitimate sites with strict security policies.
  • WooCommerce and generic Stripe integrations. Stores using less common platforms may show as "no payment provider detected" even when payments work normally.
  • URL-semantic and image-provenance signals not yet shipped. Sites with obviously suspicious domain patterns or stolen product imagery aren't currently caught by our signal suite.
Current performance on our 42-URL calibration corpus: ~69% accuracy, ~5% false positive rate, ~48% recall on known scams. We're transparent about these numbers because honest calibration is more useful than inflated confidence.