VendorStacks
On this section

API Reference

Base URL https://vendorradar-production.up.railway.app . Authenticated endpoints take Authorization: Bearer vr_live_…. All responses are JSON and carry an X-Request-Id header. Concepts, limits, and full error semantics live in Documentation.

Keys

POST/v1/keys
auth: nonecost: Free

Issue an API key instantly. POST an email, get a key in the same response — no verification click. New keys receive 25 free credits (free plan: 5 live scans/day; indexed lookups uncapped).

ParameterInRequiredDescription
emailbodyrequiredEmail address to associate with the key. JSON body field.
curl
curl -X POST https://vendorradar-production.up.railway.app
/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com"}'
JavaScript (fetch)
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/keys", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ email: "you@company.com" }),
});
const { api_key, credit_balance } = await res.json();
Response
HTTP/1.1 201 Created

{
  "api_key": "vr_live_8f4b2c91d3e7a650",
  "email": "you@company.com",
  "credit_balance": 25,
  "free_tier": true,
  "note": "Key shown once. Store it now."
}
  • The key is returned exactly once and cannot be recovered — store it immediately.
  • 400 if the email is malformed; 429 if too many keys were requested from the same source recently.

Lookups

GET/v1/check?url={domain}
auth: Bearer keycost: 1 credit flat (scans automatically when unindexed)

Check an entity: does this domain publish a subprocessor/DPA disclosure, where does it live, and which vendors are on it. 1 credit flat — indexed answers return <1s; unindexed domains live-scan automatically (15–90s) at the same price.

ParameterInRequiredDescription
urlqueryrequiredDomain or URL of the entity to check, e.g. acme.com. Scheme and path are normalized away.
freshqueryoptionaltrue forces a live re-scan even when the entity is indexed. Same 1-credit price, just slower (15–90s).
categoryqueryoptionalRestrict the response to one category slug (see /v1/vendors), e.g. sms_messaging.
AuthorizationheaderrequiredBearer vr_live_… API key.
curl
curl "https://vendorradar-production.up.railway.app
/v1/check?url=notify-hq.com" \
  -H "Authorization: Bearer $VENDORSTACKS_KEY"
JavaScript (fetch)
const res = await fetch(
  "https://vendorradar-production.up.railway.app
/v1/check?url=" + encodeURIComponent("notify-hq.com"),
  { headers: { Authorization: `Bearer ${process.env.VENDORSTACKS_KEY}` } },
);
const data = await res.json();
// data.found, data.vendor_stack, data.credits_used
Response
HTTP/1.1 200 OK

{
  "domain": "notify-hq.com",
  "found": true,
  "cache": "hit",
  "scanned_at": "2026-07-21T09:14:02Z",
  "disclosure_url": "https://notify-hq.com/legal/subprocessors",
  "vendor_stack": {
    "sms_messaging": [
      {
        "vendor": "twilio",
        "confidence": "vendor_keyword",
        "evidence": {
          "source": "https://notify-hq.com/legal/subprocessors",
          "quote": "Twilio Inc. — SMS and voice message delivery"
        }
      }
    ],
    "email": [
      {
        "vendor": "sendgrid",
        "confidence": "vendor",
        "evidence": {
          "source": "https://notify-hq.com/legal/subprocessors",
          "quote": "SendGrid (Twilio Inc.) — transactional email"
        }
      }
    ],
    "payments": [
      {
        "vendor": "stripe",
        "confidence": "vendor_keyword",
        "evidence": {
          "source": "https://notify-hq.com/legal/dpa",
          "quote": "Stripe, Inc. — payment processing services"
        }
      }
    ]
  },
  "sends_sms": true,
  "credits_used": 1,
  "credit_balance": 24
}
  • found: false means no disclosure page was located for the entity — it does not mean the entity uses no vendors. See confidence tiers below.
  • Fairness rule: if a live scan fails to locate a disclosure page, credits_used is 0.
GET/v1/company/{domain}
auth: Bearer keycost: 1 credit, never scans

Full profile read for an entity: complete vendor stack across all 13 categories, disclosure sources, and scan history. Guaranteed instant — this endpoint never triggers a scan.

ParameterInRequiredDescription
domainpathrequiredThe entity's domain, e.g. notify-hq.com.
AuthorizationheaderrequiredBearer vr_live_… API key.
curl
curl "https://vendorradar-production.up.railway.app
/v1/company/notify-hq.com" \
  -H "Authorization: Bearer $VENDORSTACKS_KEY"
JavaScript (fetch)
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/company/notify-hq.com", {
  headers: { Authorization: `Bearer ${process.env.VENDORSTACKS_KEY}` },
});
const profile = await res.json();
Response
HTTP/1.1 200 OK

{
  "domain": "notify-hq.com",
  "found": true,
  "first_seen": "2026-03-02T11:40:19Z",
  "scanned_at": "2026-07-21T09:14:02Z",
  "disclosure_sources": [
    "https://notify-hq.com/legal/subprocessors",
    "https://notify-hq.com/legal/dpa"
  ],
  "vendor_stack": {
    "sms_messaging": [{ "vendor": "twilio", "confidence": "vendor_keyword", "evidence": { "...": "..." } }],
    "email": [{ "vendor": "sendgrid", "confidence": "vendor", "evidence": { "...": "..." } }],
    "payments": [{ "vendor": "stripe", "confidence": "vendor_keyword", "evidence": { "...": "..." } }],
    "cloud_infra": [{ "vendor": "aws", "confidence": "vendor", "evidence": { "...": "..." } }]
  },
  "sends_sms": true,
  "credits_used": 1,
  "credit_balance": 23
}
  • Returns 404 with found: false (0 credits) if the domain has never been scanned — use /v1/check, which live-scans unindexed domains automatically.

Prospecting

GET/v1/prospect?vendor=&category=&page=
auth: Bearer keycost: 1 credit / page

Reverse lookup: list entities by vendor or category. Returns every entity in the index whose disclosure names the given vendor, optionally narrowed by category — 10 entities per page, each with its quoted evidence.

ParameterInRequiredDescription
vendorqueryoptionalCanonical vendor slug, e.g. twilio. At least one of vendor or category is required.
categoryqueryoptionalCategory slug, e.g. sms_messaging. Combine with vendor to narrow.
pagequeryoptional1-based page number. Default 1. Each page of 10 entities costs 1 credit.
AuthorizationheaderrequiredBearer vr_live_… API key.
curl
curl "https://vendorradar-production.up.railway.app
/v1/prospect?vendor=twilio&category=sms_messaging&page=1" \
  -H "Authorization: Bearer $VENDORSTACKS_KEY"
JavaScript (fetch)
const params = new URLSearchParams({
  vendor: "twilio",
  category: "sms_messaging",
  page: "1",
});
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/prospect?" + params, {
  headers: { Authorization: `Bearer ${process.env.VENDORSTACKS_KEY}` },
});
const { companies, total } = await res.json();
Response
HTTP/1.1 200 OK

{
  "vendor": "twilio",
  "category": "sms_messaging",
  "page": 1,
  "per_page": 10,
  "total": 1417,
  "companies": [
    {
      "domain": "notify-hq.com",
      "confidence": "vendor_keyword",
      "evidence": {
        "source": "https://notify-hq.com/legal/subprocessors",
        "quote": "Twilio Inc. — SMS and voice message delivery"
      },
      "scanned_at": "2026-07-21T09:14:02Z"
    },
    { "domain": "shipfast.io", "confidence": "vendor", "evidence": { "...": "..." } }
  ],
  "credits_used": 1,
  "credit_balance": 22
}
  • Each page of 10 entities costs 1 credit. Page numbering starts at 1.

Account

GET/v1/balance
auth: Bearer keycost: Free

Current credit balance and lifetime usage for the calling key.

ParameterInRequiredDescription
AuthorizationheaderrequiredBearer vr_live_… API key.
curl
curl "https://vendorradar-production.up.railway.app
/v1/balance" \
  -H "Authorization: Bearer $VENDORSTACKS_KEY"
JavaScript (fetch)
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/balance", {
  headers: { Authorization: `Bearer ${process.env.VENDORSTACKS_KEY}` },
});
const { credit_balance } = await res.json();
Response
HTTP/1.1 200 OK

{
  "credit_balance": 22,
  "free_tier": true,
  "lifetime_credits_used": 3,
  "topup_url": "https://vendorstacks.com/pricing"
}

Reference

GET/v1/pricing
auth: nonecost: Free

Machine-readable pricing: operation costs and available credit packs. Point your agent here before it spends.

curl
curl "https://vendorradar-production.up.railway.app
/v1/pricing"
JavaScript (fetch)
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/pricing");
const { operations, packs } = await res.json();
Response
HTTP/1.1 200 OK

{
  "operations": {
    "lookup": { "credits": 1, "note": "flat; live-scans automatically when unindexed" },
    "prospect_page": { "credits": 1, "note": "per page of 10 entities" }
  },
  "packs": [
    { "usd": 10,  "credits": 1100 },
    { "usd": 50,  "credits": 6000 },
    { "usd": 250, "credits": 35000 }
  ],
  "free_tier": { "credits": 25, "live_scans_per_day": 5 }
}
GET/v1/vendors
auth: nonecost: Free

The vendor taxonomy: all 13 categories and the canonical vendor slugs recognized in each, for building reverse-lookup queries.

curl
curl "https://vendorradar-production.up.railway.app
/v1/vendors"
JavaScript (fetch)
const res = await fetch("https://vendorradar-production.up.railway.app
/v1/vendors");
const { categories } = await res.json();
// categories.sms_messaging -> ["twilio", "sinch", ...]
Response
HTTP/1.1 200 OK

{
  "categories": {
    "sms_messaging": ["twilio", "sinch", "messagebird", "vonage", "plivo"],
    "email": ["sendgrid", "mailgun", "postmark", "ses", "iterable"],
    "payments": ["stripe", "adyen", "braintree", "checkout_com"],
    "...": ["..."]
  }
}
GET/healthz
auth: nonecost: Free

Liveness probe. Returns 200 when the API is up. No auth, never rate limited.

curl
curl https://vendorradar-production.up.railway.app
/healthz
Response
HTTP/1.1 200 OK

{ "ok": true }

Confidence tiers

Every match carries a confidence field describing how the vendor was identified. Extraction is deterministic — tiers describe evidence strength, not model certainty.

TierStrengthMeaning
vendor_keywordStrongestThe disclosure row names the vendor and describes the matching category function (e.g. “Twilio Inc. — SMS delivery”). Both signals present in the quoted text.
vendorStrongThe disclosure row names the vendor; the category is assigned from the vendor's canonical classification rather than the row's own wording.
vendor_inferred_smsInferredNo explicit SMS vendor row, but the disclosure's wording indicates SMS capability (e.g. a messaging aggregator listed for “customer communications”). Only used for the sends_sms flag, never for vendor_stack entries.

found: false means no disclosure page could be located — not that the entity uses no vendors.

Errors at a glance

StatusMeaningCharged
400validation errorNo
401unauthorized (bad or revoked key)No
402payment_required — includes topup_urlNo
404not_foundNo
413payload_too_large (32KB body cap)No
429rate_limited (rpm) or daily_scan_limit (free plan, 5 live scans/day)No
500internal_error — quote X-Request-IdNo
502scan_failed — fairness rule, charged 0No

Full anatomy, example bodies, and agent-handoff guidance: Documentation → Errors.