You have a spreadsheet of 500 Instagram handles from a discovery run, and every one of them is a dead end until you can reach a human. The bio says "collabs 👉 link in bio", the link is a Linktree, the Linktree points to a Notion page, and somewhere three clicks deep there is a press@ address. Doing that by hand for 500 creators is a week of tab-juggling. Doing it wrong — blasting a generic DM — is how you get muted.

The fix is to make contact discovery a single API call. Give it an Instagram handle, get back classified email candidates — each with source provenance and a deliverability verification snapshot — plus the creator's other social accounts, and pipe the result straight into your CRM or outreach sequence. This guide covers the two endpoints that do it — /v1/intelligence/contact for pure email hunting and /v1/intelligence/profile when you also want the AI classification bundle — plus how to run them in bulk without melting your budget, and how to send the email without landing in spam or breaking the law.

Two endpoints, one job

The GET form of both endpoints takes a single Instagram q — a username, an @handle, or an instagram.com/username URL — and both run an LLM under the hood, so responses take seconds to minutes rather than milliseconds. There is no live demo widget for either one; the latency makes an inline runner pointless. You call them, you wait, you get structured JSON back in the standard { data, meta } envelope.

EndpointWhat it returnsCostWhen to use
/v1/intelligence/contactemails[] + cross-platform social_accounts[]$0.10You only need contact info
/v1/intelligence/profileThe AI classification bundle — niche, audience, brand fit (no contact fields)$0.05You want to qualify creators before contacting them

Qualify before you pay for discovery

Contact discovery costs twice what classification does, so run them in that order: /v1/intelligence/profile first to filter for fit, then /v1/intelligence/contact only on the creators that pass. The profile bundle does not include contact fields — emails come from contact alone.

Discover a single creator's email

Start with the specialist endpoint. The platform parameter selects instagram, tiktok, youtube, or linkedin (default instagram) — one engine runs each. source=live forces a fresh crawl instead of cached data and doubles the price to $0.20.

shell
curl "https://api.virev.ai/v1/intelligence/contact?q=natgeo" \
  -H "Authorization: Bearer $VIREV_API_KEY"
contact.js
const res = await fetch(
  "https://api.virev.ai/v1/intelligence/contact?q=natgeo",
  { headers: { Authorization: "Bearer kb_live_..." } }
);

const { data, meta } = await res.json();
console.log(data.emails);
// [{ email: "press@natgeo.com", category: "press",
//    contact_relevance: "possible", source_url: "https://...",
//    verification: { status: "deliverable", provider: "zerobounce", ... } }, ...]
console.log(data.social_accounts);  // [{ platform: "tiktok", handle: "..." }, ...]
console.log(meta.cost);             // "$0.1000"

The response puts everything under data. emails[] is a list of classified candidate objects rather than a single guess — each entry names the exact page it was found on (source_url), how relevant it is to outreach (contact_relevance), and, when deliverability verification ran, a verification snapshot (deliverable / risky / undeliverable / unverified). Treat deliverable as the mail server's answer at check time, not a guarantee — and note that discovery is the priced operation, so an unverified entry still bills the same. social_accounts[] gives you the same creator's handles on TikTok, YouTube, and elsewhere, which is often more valuable than the email itself: now you can look them up on the TikTok analytics API or the YouTube channel API and enrich the whole row.

Point the search at the right inbox

A sponsorship pitch, a story pitch, and a vendor intro should not land in the same inbox. The POST form of /v1/intelligence/contact takes a preset that sets the outreach goal — same engine, same $0.10, different target.

PresetFinds
creator (default)The creator's own collab inbox — bio, link-in-bio, own-site contact page
managementThe agent, manager, or agency that books the creator
brandA company's partnerships, BD, or marketing desk
pressThe newsroom or media-relations desk
shell
curl -X POST "https://api.virev.ai/v1/intelligence/contact" \
  -H "Authorization: Bearer $VIREV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Gymshark", "website": "gymshark.com", "preset": "press" }'

The preset changes ranking, not just search targets. Under press, the company's published press desk comes back recommended while its support inbox — the easiest address to find — comes back not_recommended. Under management, an agency contact outranks the creator's own inbox; when no representation is public, the creator's own booking inbox comes back marked possible — a fallback, never passed off as an agent — and support desks come back not_recommended. A not_recommended answer is the API telling you the right inbox does not exist publicly — cheaper to learn that for $0.10 than by mailing a support desk a sponsorship deck.

One entity, many handles

identities[] takes up to 8 {platform, id} pairs — aliases for one person or company, not a batch. The engine runs a single merged investigation across all of them and returns one result at the same flat $0.10; extra handles give it more entry points, not more work. To enrich a list of different creators, send one request per creator.

shell
# one entity, two entry points, one $0.10 investigation
curl -X POST "https://api.virev.ai/v1/intelligence/contact" \
  -H "Authorization: Bearer $VIREV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "identities": [
      { "platform": "instagram", "id": "natgeo" },
      { "platform": "youtube",   "id": "@NatGeo" }
    ],
    "preset": "press"
  }'

The body is strict

At least one of identities, name, or website is required. Unknown fields — including inside an identity object — are rejected with a 400, never silently dropped, and validation runs before auth and billing, so a malformed request is never charged. To nudge targeting without leaving the preset, pass prompt_amend (≤2000 chars), e.g. Prefer a UK-based contact.

Pair it with the profile bundle

If you're building an outreach pipeline, /v1/intelligence/profile is the other half of the workflow. It returns the classification bundle — account_role, primary_niche, commercial_intent, brand_safety — which is the reason to reach out; contact is the way to do it. Classify first, then discover contacts only for creators that fit.

qualify_then_contact.py
import requests

HEADERS = {"Authorization": "Bearer kb_live_..."}

profile = requests.get(
    "https://api.virev.ai/v1/intelligence/profile",
    params={"q": "natgeo"},
    headers=HEADERS,
).json()["data"]

if "travel" in (profile["primary_niche"] or "").lower():
    contact = requests.get(
        "https://api.virev.ai/v1/intelligence/contact",
        params={"q": "natgeo"},
        headers=HEADERS,
    ).json()["data"]
    print(contact["emails"])  # only spent $0.10 on a qualified lead

Enrich a list without blowing your budget

Real outreach starts from a list, not one handle. The loop is straightforward: iterate your handles, call contact, and collect the results. Two things to build in from the start — respect the 100 req/min default rate limit (a 429 carries a Retry-After header), and remember you are never charged for a non-200, so a failed lookup costs nothing and can be retried freely.

bulk_contacts.py
import requests, time

HANDLES = ["natgeo", "nasa", "bbcearth"]  # from your discovery run
HEADERS = {"Authorization": "Bearer kb_live_..."}
rows = []

for handle in HANDLES:
    res = requests.get(
        "https://api.virev.ai/v1/intelligence/contact",
        params={"q": handle},
        headers=HEADERS,
    )
    if res.status_code == 429:
        time.sleep(int(res.headers.get("Retry-After", 5)))
        continue  # non-200 was free — safe to retry
    if res.status_code != 200:
        continue  # log and move on; you were not billed
    data = res.json()["data"]
    rows.append({
        "handle": handle,
        "emails": data.get("emails", []),
        "socials": data.get("social_accounts", []),
    })

print(f"Enriched {len(rows)} creators")

A few cost anchors for planning a run: at $0.10 each, 1,000 creators is $100 of contact discovery. Qualifying with /v1/intelligence/profile at $0.05 first usually shrinks that bill — if only a third of your list fits, the pipeline costs $50 of classification plus ~$33 of discovery instead of $100 across the board. And the starter offer — pay $1, get a $5 balance — covers your first ~50 contact lookups or ~100 profile enrichments before you commit to anything.

Send the email without getting burned

Finding the address is the easy part. Not getting reported is the discipline. These emails are business contact points creators published so brands could reach them — but publishing an address is not consent to receive bulk mail, and the law treats it that way.

  • CAN-SPAM (US): use accurate From/Subject headers, include a real physical mailing address, and provide a working unsubscribe that you honor within 10 business days.
  • GDPR (EU recipients): you can lean on legitimate interest for B2B outreach, but you must offer a clear opt-out and stop on request. Keep a record of why you contacted them.
  • Relevance over volume: use the brand_fit_summary and content_tags you already pulled to send something specific. A creator who gets a personalized, on-niche pitch replies; one who gets a mail-merge blast blocks you.
  • Verify before a big send: the API returns candidates — run them through your ESP's validation step to catch bounces before they hurt your sender reputation.
Discovery gives you the address. Etiquette gives you the reply. Treat every send as if the creator will screenshot it.

Turn handles into inboxes

Pay $1, get a $5 balance — enough for ~50 contact lookups or ~100 full profile enrichments. No subscription, no minimum.

Get your API key →