Vendo AI API & MCP

The complete programmable interface to the Vendo AI autonomous sales platform. Build integrations, connect AI assistants, and automate your entire sales pipeline.

149 MCP Tools
173 REST Endpoints
v1 Stable API
24/7 Availability

Documentation last updated: July 22, 2026 — Phase 7, full UI parity. See the Changelog.

The Vendo AI Public API turns Vendo AI from a UI-only product into a fully programmable platform. Generate an API key, and you can drive the entire product — create AI agents, build audiences, launch multi-channel campaigns, manage your CRM pipeline, read analytics, and manage billing — all from your own code, Zapier/Make workflows, or directly through an AI assistant like Claude or ChatGPT via Model Context Protocol (MCP).

AI Agent Lifecycle

Create agents, scan websites, generate scripts, set avatars, configure connections — full onboarding pipeline via API.

Campaign Management

Create, launch, pause, resume, and archive multi-channel outreach campaigns with preview protection.

CRM Pipeline

Read your live lead pipeline, reply to leads on their source channel, manage kanban stages, and enrich contacts from LinkedIn.

Audience Search

Search the people graph, save audiences, enrich contacts with verified email addresses.

Vendo SDR Automation

Manage signal hunters, monitor discovered personas, launch outreach, view signal intelligence in real time.

Billing & Analytics

Read credit balance, subscriptions, invoices, usage stats, funnel analytics — full read-only billing surface.

MCP for AI Assistants

Connect Claude, ChatGPT, or Cursor directly. 149 tools let an AI operate your account in plain English.

Quick Start

Get started in three steps:

1. Get your API key

Log in to app.vendo-ai.com, go to Settings → API & MCP, and click "Create my key". You'll need an active subscription or free trial. The key is shown once — copy it immediately.

2. Make your first request

bash
curl -s https://api.vendo-ai.com/v1/billing/balance \
  -H "Authorization: Bearer vnd_live_YOUR_KEY_HERE" | jq .

# Response:
{
  "data": {
    "balance": 450
  }
}

3. Or connect via MCP

Add the Vendo AI MCP server to Claude Desktop, ChatGPT, or any MCP-compatible client:

json — Claude Desktop config
{
  "mcpServers": {
    "vendo-ai": {
      "url": "https://api.vendo-ai.com/mcp",
      "headers": {
        "Authorization": "Bearer vnd_live_YOUR_KEY_HERE"
      }
    }
  }
}

Base URL

https://api.vendo-ai.com — all API endpoints are under /v1/

https://api.vendo-ai.com/mcp — MCP Streamable HTTP transport

Authentication

API Key Format

Keys follow the pattern vnd_live_ + 64 hex characters (32 random bytes). Example:

Key format
vnd_live_8f3a27207c3dd1a49beed2a852275eb77892491daaa19541bb761300694a4d46
^^^^^^^^^
 prefix    ← 32 random bytes → hex

Passing Your Key

Include your key in every request using either header:

http
Authorization: Bearer vnd_live_YOUR_KEY
# or
X-API-Key: vnd_live_YOUR_KEY

Security Model

  • Hashed storage — only the SHA-256 hash is stored. The raw key is shown once at creation.
  • Workspace-bound — every key belongs to exactly one workspace. Cross-tenant access is structurally impossible.
  • Scope-enforced — each route requires specific scopes (all granted by default). See Scopes Reference.
  • No billing:write — a leaked key cannot move money. Top-ups and plan changes require the authenticated portal.
  • Instant revocation — delete a key in Settings, and it's invalid on the next request.

Architecture

The Public API is a dedicated microservice (vendo-public-api, port 3015) that sits in front of all internal Vendo AI services. It enforces authentication, scopes, rate limiting, audit logging, and billing pre-checks in one place. The MCP adapter (vendo-mcp, port 3016) is a thin translation layer that converts MCP tool calls into /v1 REST requests.

Your App / AI Assistant │ │ HTTPS + Bearer vnd_live_… ▼ ┌──────────────────────────────────────┐ │ api.vendo-ai.com (nginx) │ │ TLS termination, CORS, WAF │ └──┬────────────────────────┬──────────┘ │ /v1/* │ /mcp ▼ ▼ ┌─────────────────┐ ┌──────────────┐ │ vendo-public-api│ │ vendo-mcp │ │ (port 3015) │ │ (port 3016) │ │ │ │ │ │ • API key guard │ │ • MCP SDK │ │ • Scope check │ │ • 149 tools │ │ • Rate limiter │ │ • Session │ │ • Audit log │ │ management │ │ • Billing check │ │ │ │ • /v1 routes │ │ Calls /v1 → │ └───┬───┬───┬─────┘ └──────────────┘ │ │ │ ▼ ▼ ▼ Internal Vendo AI Services ├── vendo-auth (3001) ├── vendo-billing (3002) ├── vendo-companies (3005) └── vendo-sales-process (3008)

Workspace Isolation

Every API key is resolved to a single workspace_id on the first call — the gateway calls vendo-auth with a shared internal secret and caches the result on the key row. All downstream calls inject this workspace_id and refuse to honour any caller-supplied workspace id. Cross-tenant access is structurally impossible regardless of what the request body contains.

Why a Separate Microservice?

Stable contract/v1/... is a promise. Internal services evolve freely behind it. One hardening surface for keys, rate limits, quota, and audit. Independent scaling from the UI traffic.

Rate Limits

Default rate limit is 60 requests per minute per API key (sliding window). Response headers tell you your current state:

HeaderDescription
X-RateLimit-LimitMaximum requests per window (default 60)
X-RateLimit-RemainingRemaining requests in current window
Retry-AfterSeconds until window resets (only sent on 429)
X-Idempotency-Replaytrue when an Idempotency-Key matched a cached response

When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After header.

Error Handling

All errors follow a consistent JSON structure:

json — error response
{
  "code": "missing_scope",
  "message": "Required scope(s) not on key: agents:write"
}
HTTP CodeError CodeMeaning
400bad_requestInvalid input or parameters
400confirmation_requiredDestructive action — send dry_run or confirm
401unauthorizedMissing or invalid API key
402no_creditsInsufficient credit balance
403missing_scopeKey lacks the required scope
404not_foundResource doesn't exist or wrong workspace
409idempotency_conflictIdempotency-Key reused for a different request
429rate_limitedToo many requests — check Retry-After header
500downstream_errorInternal service error (retry safe)

Agents

The Agents API provides complete lifecycle management — from creating an AI sales agent to scanning a website, generating a conversational script, setting an avatar, and configuring connections (Google Meet, Telegram, Website Widget, Presentations).

Core Endpoints

MethodEndpointScopeDescription
GET/v1/agentsagents:readList all agents
GET/v1/agents/with-statsagents:readList agents with connection + credit stats
GET/v1/agents/:idagents:readGet agent details
GET/v1/agents/plan-limitsagents:readPlan capacity vs current agent count
GET/v1/agents/dashboard/analyticsagents:readDashboard summary
POST/v1/agentsagents:writeCreate a new agent (1 credit)
PATCH/v1/agents/:idagents:writeUpdate agent info
DELETE/v1/agents/:idagents:writeDelete agent (requires confirm)
POST/v1/agents/:id/deep-scanagents:writeDeep-scan website — 15 credits, paired dry_run/confirm
POST/v1/agents/:id/duplicateagents:writeClone an agent

Agent Credits & Analytics

MethodEndpointScopeDescription
GET/v1/agents/:id/credits-spentagents:readCredits this agent has spent
GET/v1/agents/:id/credits-spent/connectionsagents:readPer-connection credit breakdown
GET/v1/agents/credits-spentagents:readWhole-workspace agent credit breakdown

Agent Pipeline Endpoints

These endpoints power the full onboarding flow — from scanning a website to generating a sales script:

MethodEndpointDescription
POST/v1/agents/scanQuick website scan (no agent id needed yet)
POST/v1/agents/:id/scan-websiteQuick site scan attached to an agent
POST/v1/agents/:id/deep-scanDeep website scan — 15 credits, requires dry_run/confirm
POST/v1/agents/:id/save-scan-dataPersist scan output onto the agent
POST/v1/agents/:id/generate-descriptionGenerate company description (1 credit)
POST/v1/agents/:id/generate-scriptGenerate full sales script — 1 credit, 8-stage AI
POST/v1/agents/:id/generate-support-scriptGenerate support script
POST/v1/agents/:id/generate-responseGenerate a single AI reply for a given inbound message, using the agent's script and knowledge base. Useful for previewing how the agent would answer before enabling a channel
POST/v1/agents/:id/generate-narrator-scriptGenerate narrator script
POST/v1/agents/:id/generate-transition-phrasesSlide transition narration
POST/v1/agents/:id/generate-page-descriptionsAI page descriptions for an agent
POST/v1/agents/page-descriptionsAI page descriptions without an agent
PATCH/v1/agents/:id/companySet / update the company block: name, website, description and contact_channels — see the warning below
PATCH/v1/agents/:id/avatarSet avatar from URL (body: { "image_url": "https://..." })
PATCH/v1/agents/:id/scriptManually overwrite script
PATCH/v1/agents/:id/voiceUpdate Retell voice settings
PATCH/v1/agents/:id/integrationsUpdate CRM integration config
PATCH/v1/agents/:id/statusACTIVE / PAUSED / DRAFT / ARCHIVED
DELETE/v1/agents/:id/documentsDelete an agent document (body: { "filename": "…" })

PATCH /v1/agents/:id/company — Send the Complete Company Object

Despite the PATCH verb, this endpoint replaces the company block: company_name, company_website and company_description are always overwritten by what you send. Sending only contact_channels will blank the company name. Read the agent first and resend the existing values alongside your changes.

bash — full company object incl. contact channels
curl -X PATCH https://api.vendo-ai.com/v1/agents/{id}/company \
  -H "Authorization: Bearer $VENDO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Ltd",
    "company_website": "https://acme.com",
    "company_description": "…",
    "contact_channels": {
      "meeting_url": "https://calendly.com/acme/30min",
      "email": "sales@acme.com",
      "phone": "+44 20 1234 5678",
      "whatsapp": "+44 7700 900000",
      "telegram": "@acme_sales"
    }
  }'

Channels you omit are cleared, so always send the full set you want the agent to have. The MCP tool set_agent_contact_channels handles the read-modify-write for you.

Connection Endpoints

MethodEndpointDescription
GET/v1/agents/:id/connectionsList all connections
POST/v1/agents/:id/connectionsCreate a connection (generic)
GET/v1/agents/:id/connections/:cidGet one connection
PATCH/v1/agents/:id/connections/:cidUpdate connection config
DELETE/v1/agents/:id/connections/:cidDisconnect
GET/v1/agents/:id/connections/:cid/statsPer-connection stats
GET/v1/agents/:id/connections/:cid/conversationsConversation history
GET/v1/agents/:id/widget/embed-codeEmbed code for the website widget
GET/v1/agents/voices/retellList available Retell voices
GET/v1/agents/:id/google-meet/auth-urlStart Google Meet OAuth (returns URL)
GET/v1/agents/:id/google-meetCurrent Google Meet config
PATCH/v1/agents/:id/google-meet/configUpdate Google Meet config
DELETE/v1/agents/:id/google-meetDisconnect Google Meet
GET/v1/agents/:id/google-meet/meetingsList meetings
POST/v1/agents/:id/google-meet/syncForce sync meetings
POST/v1/agents/:id/telegram/connectConnect Telegram bot (body: { "bot_token": "…" })
DELETE/v1/agents/:id/telegramDisconnect Telegram bot
GET/v1/agents/:id/telegramCurrent bot info
PATCH/v1/agents/:id/telegram/voiceToggle voice (body: { "enabled": true/false })
POST/v1/agents/:id/telegram/reconfigureReconfigure bot settings
GET/v1/agents/:id/telegram/analyticsTelegram analytics
GET/v1/agents/:id/presentationsList presentations attached to this agent
GET/v1/agents/:id/presentations/embedPresentation embed code
GET/v1/agents/:id/narrator/analyticsNarrator analytics
GET/v1/agents/:id/narrator/leadsLeads captured by the agent's presentations
PATCH/v1/agents/:id/narrator/leads/:leadIdUpdate / dismiss a narrator lead

Preview Endpoints

Preview exactly what your agent would send before any campaign launch:

MethodEndpointDescription
POST/v1/agents/:id/preview/emailPreview the email this agent would send
POST/v1/agents/:id/preview/linkedin-invitePreview the LinkedIn invite text
POST/v1/agents/:id/preview/linkedin-followupPreview the LinkedIn follow-up message

Campaigns

Campaigns are multi-channel outreach sequences. You can create a campaign, attach an audience, configure channels (email, LinkedIn, calls), and launch it — all through the API.

MethodEndpointScopeDescription
GET/v1/campaignscampaigns:readList all campaigns
GET/v1/campaigns/:idcampaigns:readGet campaign details + stats
POST/v1/campaignscampaigns:writeCreate a campaign
PATCH/v1/campaigns/:idcampaigns:writeUpdate campaign settings
DELETE/v1/campaigns/:idcampaigns:writeDelete campaign (requires confirm)
POST/v1/campaigns/:id/launchcampaigns:controlLaunch campaign (requires confirm)
POST/v1/campaigns/:id/pausecampaigns:controlPause all channels
POST/v1/campaigns/:id/pause-channelcampaigns:controlPause a specific channel
POST/v1/campaigns/:id/resume-channelcampaigns:controlResume a specific channel
POST/v1/campaigns/:id/archivecampaigns:controlArchive campaign

CRM

CRM — programmatic access to the built-in Vendo CRM. Leads are people who demonstrated interest: replied to your LinkedIn or email outreach, engaged one of your AI agents (widget, phone, Telegram), or booked a meeting — plus leads your team adds manually. Read your live pipeline, move cards between stages, reply to leads on their source channel, and enrich contacts from a LinkedIn URL. Scopes: crm:read, crm:write.

MethodEndpointScopeDescription
GET/v1/crm/leadscrm:readList pipeline leads. Query: stage, source, q, range (24h…1y|all), limit (≤200), offset
GET/v1/crm/leads/:idcrm:readFull lead card: identity, origin, company enrichment, activity, comments
GET/v1/crm/leads/:id/conversationcrm:readFull message thread on the lead's source channel
GET/v1/crm/statscrm:readPer-stage counts, new today/this week, stale leads
GET/v1/crm/pipeline-stagescrm:readOrdered kanban stages (id, name, color, is_terminal)
POST/v1/crm/leadscrm:writeCreate a lead manually. All fields optional (at least one non-empty)
PATCH/v1/crm/leads/:idcrm:writeUpdate lead attributes
PATCH/v1/crm/leads/:id/stagecrm:writeMove lead to another stage
POST/v1/crm/leads/:id/reassigncrm:writeChange lead owner
POST/v1/crm/leads/:id/replycrm:writeSends a real message to the lead on their source channel (LinkedIn or email). Lead auto-moves to Manager Dialog stage
POST/v1/crm/leads/:id/commentscrm:writeInternal team note on the lead card
POST/v1/crm/leads/enrichcrm:writeEnrich from LinkedIn URL → name, title, employer, avatar, location, and unverified pattern-guess email. Consumes 1 LinkedIn budget
DELETE/v1/crm/leads/:idcrm:writeSoft-delete a lead (requires confirm)
POST/v1/crm/pipeline-stagescrm:writeCreate a custom stage (inserted before Won/Lost)
PATCH/v1/crm/pipeline-stages/:idcrm:writeRename / recolor a stage (system stages can't be renamed)
DELETE/v1/crm/pipeline-stages/:idcrm:writeDelete stage (requires confirm). Refused if stage holds leads or is a system stage
GET/v1/crm/workspace-memberscrm:readPeople who can own a lead. Call this before reassign to get valid owner ids
GET/v1/crm/agentscrm:readAI agents in this workspace that leads can be attributed to
GET/v1/crm/linkedin-accountscrm:readLinkedIn accounts connected to this workspace, as shown in the CRM
GET/v1/crm/calendar/eventscrm:readCustom calendar events. Optional from / to (ISO dates)
POST/v1/crm/calendar/eventscrm:writeCreate a custom calendar event
PATCH/v1/crm/calendar/events/:idcrm:writeUpdate a calendar event
DELETE/v1/crm/calendar/events/:idcrm:writeDelete a calendar event. No confirmation step required
GET/v1/crm/notificationscrm:readList CRM notifications. Optional limit, unread_only
PATCH/v1/crm/notifications/:id/readcrm:writeMark one notification as read
POST/v1/crm/notifications/read-allcrm:writeMark all notifications as read
GET/v1/crm/settingscrm:readRead CRM settings, including the notify_* toggles
PATCH/v1/crm/settingscrm:writeUpdate CRM settings — e.g. mute notifications while an integration drives the CRM
GET/v1/crm/communications/cardscrm:readOne card per campaign and per SDR search, with outbound counters
GET/v1/crm/communications/cards/:type/:id/historycrm:readEvery outbound touch for one card. type is campaign or sdr. Filters: channel (email/linkedin/phone), replied, from, to, limit, offset
GET/v1/crm/communications/cards/:type/:id/threadcrm:readFull message thread with one contact. Requires key from a history row
bash — CRM examples
# Who replied to me this week?
curl -s https://api.vendo-ai.com/v1/crm/leads?range=7d&limit=20 \
  -H "Authorization: Bearer vnd_live_..."

# Reply to a lead on their source channel (LinkedIn or email)
curl -s -X POST https://api.vendo-ai.com/v1/crm/leads/LEAD_ID/reply \
  -H "Authorization: Bearer vnd_live_..." \
  -H "Content-Type: application/json" \
  -d '{"text": "Thanks for getting back to me — does Tuesday 3pm work?"}'

# Enrich a person from LinkedIn before adding them
curl -s -X POST https://api.vendo-ai.com/v1/crm/leads/enrich \
  -H "Authorization: Bearer vnd_live_..." \
  -H "Content-Type: application/json" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/someone"}'

Leads vs Communications

/v1/crm/leads contains people who replied — the CRM is a collector of answers, across LinkedIn, email, the widget, voice and phone.

/v1/crm/communications is the full outbound stream: everyone you contacted, whether or not they answered. Use it to analyse deliverability and coverage; use leads to work the pipeline.

Calendar: Custom Events Only

Calendar endpoints manage custom events. SDR sending windows also appear in the web app's calendar, but they are derived from each search's schedule and are not editable — read them via GET /v1/sdr/searches/:id.

Audiences

MethodEndpointScopeDescription
GET/v1/audiencesaudiences:readList the audiences saved in this workspace
GET/v1/audiences/:idaudiences:readRead one saved audience with its filters and contact count
POST/v1/audiences/searchaudiences:readSearch the people graph (preview, free)
POST/v1/audiencesaudiences:writeSave audience from search results
bash — search audience
curl -X POST https://api.vendo-ai.com/v1/audiences/search \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "positions": ["VP Sales", "Head of Revenue"],
    "countries": ["United States"],
    "companySizes": ["small", "medium"],
    "industries": ["SaaS", "Technology"],
    "mustHaveEmail": true,
    "limit": 25
  }'

Audience Sets

Pre-built, ready-to-use audiences you can buy and launch outreach against without building filters yourself. Browsing is free; purchasing costs 2 credits per contact.

MethodEndpointDescription
GET/v1/audiences/setsBrowse the marketplace catalog and its categories. Free.
GET/v1/audiences/sets/:slugDetails of one set: size, description, freshness. slug is human-readable (e.g. uk-fintech-founders), not a UUID.
GET/v1/audiences/sets/:slug/contactsPaginated contact preview. Accepts offset and limit. Contact details stay masked until purchase.
POST/v1/audiences/sets/:id/buySpends credits. Buys the set and snapshots its contacts into your workspace. Requires dry_run / confirm. Takes the set id (UUID), not the slug.
POST/v1/audiences/sets/:id/launchSpends credits and starts real outreach. Buys the snapshot, then launches a campaign against it. Requires dry_run / confirm.
bash — buy an audience set (dry-run first)
# 1. See what it would cost — nothing is charged
curl -X POST https://api.vendo-ai.com/v1/audiences/sets/{set_id}/buy \
  -H "Authorization: Bearer $VENDO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

# 2. Execute after reviewing the cost
curl -X POST https://api.vendo-ai.com/v1/audiences/sets/{set_id}/buy \
  -H "Authorization: Bearer $VENDO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'

Vendo SDR

The SDR (Signal-Driven Revenue) module gives you full control over the autonomous discovery pipeline — 12 AI hunters that continuously scan the web for buying signals, discover prospects, and launch outreach.

Signal Search Lifecycle

MethodEndpointDescription
GET/v1/sdr/searchesList all signal searches
GET/v1/sdr/searches/:idGet search details
POST/v1/sdr/searchesCreate a Signal Search (hunters start immediately)
PATCH/v1/sdr/searches/:idUpdate search parameters
POST/v1/sdr/searches/:id/activateActivate a search
POST/v1/sdr/searches/:id/pausePause a search
POST/v1/sdr/searches/:id/resumeResume a paused search
POST/v1/sdr/searches/:id/regenerateRegenerate search configuration
DELETE/v1/sdr/searches/:idDelete search (requires confirm)

Agent Signal Profile

MethodEndpointDescription
GET/v1/sdr/agents/:id/profileGet the agent's current signal profile
POST/v1/sdr/agents/:id/profile/generate(Re-)generate the signal profile (Claude call)
POST/v1/sdr/searches/previewPreview Claude output before creating a search

Personas & Signals

MethodEndpointDescription
GET/v1/sdr/people?search_id=…List discovered people (with filters: company, role, min_relevance, limit, offset)
GET/v1/sdr/people/stats?search_id=…Counts, top companies, by-role, credits spent, daily series
POST/v1/sdr/people/export-to-audienceExport selected people to a custom audience
POST/v1/sdr/people/backfill-avatarsAsync backfill of LinkedIn avatars onto people rows

SDR Outreach

MethodEndpointDescription
GET/v1/sdr/searches/:id/outreachGet outreach status for one Signal Search
POST/v1/sdr/searches/:id/outreach/launchLaunch outreach — paired dry_run/confirm
GET/v1/sdr/searches/:id/outreach/contentRead outreach templates
PATCH/v1/sdr/searches/:id/outreach/contentUpdate outreach templates
POST/v1/sdr/searches/:id/outreach/content/previewRender a personalised message preview
POST/v1/sdr/searches/:id/outreach/pausePause outreach delivery
POST/v1/sdr/searches/:id/outreach/resumeResume outreach delivery
DELETE/v1/sdr/searches/:id/outreachDelete outreach campaign (paired dry_run/confirm)
POST/v1/sdr/searches/:id/outreach/linkedin/connectLink LinkedIn accounts to this outreach
GET/v1/sdr/outreach/sales-processCompleted SDR outreach campaigns for Sales Process

SDR Observability

MethodEndpointDescription
GET/v1/sdr/searches/:id/run-statePrimary run state for the search
GET/v1/sdr/searches/:id/run-statesPer-source map of hunter states
GET/v1/sdr/searches/:id/stats?days_back=30Signal counts by source over time
GET/v1/sdr/searches/:id/healthPer-search operator dashboard
GET/v1/sdr/recent?limit=20Recent signals across the workspace
GET/v1/sdr/company-heat?limit=50Hottest companies by composite signal strength
GET/v1/sdr/learning-insightsWorkspace-level learned signal weights
POST/v1/sdr/searches/:id/learning-recomputeManually trigger the learning loop
POST/v1/sdr/searches/:id/sources/pausePause one hunter (body: { "source": "linkedin_jobs" }) or all
POST/v1/sdr/searches/:id/sources/resumeResume one hunter
POST/v1/sdr/searches/:id/run-nowTrigger an immediate run — paired dry_run/confirm
GET/v1/sdr/people/export.csvExport contacts of a search as a CSV file (not JSON). Requires search_id; optional company, role, min_relevance. Returns text/csv with a Content-Disposition attachment header. Contacts only — deliberately carries no scores or signal reasoning.
GET/v1/sdr/people/:id/detailFull provenance for one person: which hunter found them, what query fired, which signal triggered the pick, and the scoring breakdown.
GET/v1/sdr/searches/:id/outreach/activity-feedRecent discovery + outreach events for a search, newest first. Optional limit (default 40).
GET/v1/sdr/searches/:id/outreach/summarySent / queued counters per channel for a search.

CSV Export — the One Non-JSON Endpoint

GET /v1/sdr/people/export.csv is the only endpoint that does not return the standard { "data": ... } envelope — it returns the raw CSV file so you can pipe it straight into a spreadsheet or another tool:

bash — export contacts
curl -H "Authorization: Bearer $VENDO_API_KEY" \
  "https://api.vendo-ai.com/v1/sdr/people/export.csv?search_id={search_id}" \
  -o contacts.csv

Columns: First name, Last name, Job title, Headline, Email, LinkedIn URL, Location, Company, Company website, Company description, Added on.

The 9 Signal Hunters

HunterSignal SourceWhat It Detects
linkedin_jobsLinkedIn job postingsHiring signals — companies actively building sales/marketing teams
linkedin_companyLinkedIn company updatesCompany changes — funding, expansion, leadership shifts
connected_peopleLinkedIn networkJob changes and role transitions in your network
ai_web_hunterWeb + AI analysisNews mentions, press releases, product launches
crunchbase_rssCrunchbase feedFunding rounds, acquisitions, new ventures
hn_hiringHacker NewsWho is Hiring threads — tech company demand signals
g2_reviewsG2 ReviewsCompetitor reviews — companies evaluating alternatives
tech_stackTechnology detectionTechnology changes — new stack adoption, migration signals
email_enricherEmail verificationEnriches discovered personas with verified email addresses

Paid vs Free Hunters

Free: linkedin_jobs, linkedin_company, connected_people, crunchbase_rss, hn_hiring

Paid (off by default): ai_web_hunter, g2_reviews, tech_stack — these spend Anthropic + web-search budget per run. Enable via enabled_sources on sdr_create_search or PATCH /v1/sdr/searches/:id.

email_enricher charges 5 credits per enriched contact (transaction type SDR_CONTACT).

Billing

Full read-only billing access. A leaked API key cannot move money — all money-moving paths require the authenticated portal.

MethodEndpointDescription
GET/v1/billing/balanceCurrent credit balance (lightweight)
GET/v1/billing/balance/fullBalance + plan summary + spent totals
GET/v1/billing/subscriptionCurrent subscription (plan, status, dates)
GET/v1/billing/subscription/limitsMax agents, extra slots, plan status
GET/v1/billing/pricingPublic pricing catalogue (plans + add-ons)
GET/v1/billing/transactions?type=…&from=…&to=…&limit=…&offset=…Credit transaction history
GET/v1/billing/invoices?year=…&month=…Stripe invoices (paid + open)
GET/v1/billing/usage/by-typeSpend grouped by action type
GET/v1/billing/usage/monthlyPer-month spend breakdown
GET/v1/billing/usage/by-agentSpend per agent (workspace-wide)
GET/v1/billing/usage/agents/:agentIdSpend for one agent
GET/v1/billing/usage/agents/:agentId/connectionsPer-channel spend for one agent
GET/v1/billing/sdr/email-capacitySDR sender capacity (included + extras, daily limit)

LinkedIn Accounts

LinkedIn sending capacity is the scarcest resource in outreach: LinkedIn enforces roughly 70–80 invitations per day per account, server-side, regardless of your configuration. If invite volume looks low, check how many healthy accounts are connected here first.

MethodEndpointDescription
GET/v1/linkedin/accountsList connected LinkedIn accounts and their status.
POST/v1/linkedin/accounts/connectReturns a hosted URL a human must open in a browser to authorise an account. Optional campaignId.
POST/v1/linkedin/accounts/:id/reconnectRe-authenticate an account whose session expired. Requires dry_run / confirm.
DELETE/v1/linkedin/accounts/:idDisconnect an account. Requires dry_run / confirm.

Connecting Cannot Be Automated

POST /v1/linkedin/accounts/connect returns a hosted authorisation URL; a human has to open it and complete the flow. No account exists until they do.

Reconnecting Changes the Account Id

Re-authentication creates a new account identifier upstream. Outreach already sent from the old id stays attached to it, so per-account history can appear empty afterwards and running campaigns may need to be re-pointed at the new account. Always run the dry_run first.

Destructive Action Protocol

Any action that's hard to undo requires a two-step confirmation. This protects against accidental launches and ensures AI assistants always show a preview before executing.

How It Works

Step 1: Preview with dry_run

Send {"dry_run": true} to see what would happen without executing.

Step 2: Execute with confirm

After reviewing the preview, send {"confirm": true} to execute the action.

Missing both? → 400 confirmation_required

Sending neither dry_run nor confirm returns an error. Sending both also returns an error (mutual exclusion).

Protected Routes

  • DELETE /v1/agents/:id — deleting an agent
  • DELETE /v1/campaigns/:id — deleting a campaign
  • POST /v1/campaigns/:id/launch — launching outreach
  • POST /v1/agents/:id/deep-scan — deep website scan (15 credits)
  • DELETE /v1/sdr/searches/:id — deleting a Signal Search
  • DELETE /v1/sdr/searches/:id/outreach — deleting SDR outreach
  • POST /v1/sdr/searches/:id/outreach/launch — launching SDR outreach
  • POST /v1/sdr/searches/:id/run-now — manually triggering a hunter (paid sources spend credits)
  • DELETE /v1/crm/leads/:id — soft-deleting a CRM lead
  • DELETE /v1/crm/pipeline-stages/:id — deleting a CRM pipeline stage
  • POST /v1/audiences/sets/:id/buy — buying an Audience Set (spends credits)
  • POST /v1/audiences/sets/:id/launch — buying + launching outreach on an Audience Set
  • POST /v1/linkedin/accounts/:id/reconnect — re-authenticating a LinkedIn account (changes its id)
  • DELETE /v1/linkedin/accounts/:id — disconnecting a LinkedIn account
bash — dry_run example
# Step 1: Preview
curl -X POST https://api.vendo-ai.com/v1/campaigns/abc123/launch \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

# Response: preview of what would happen
{
  "data": {
    "dry_run": true,
    "would_do": "Launch campaign \"Q3 Outreach · Jun 15, 2026 12:25\"",
    "campaign_name": "Q3 Outreach · Jun 15, 2026 12:25",
    "recipient_count": null,
    "channels": ["email", "linkedin"],
    "daily_limit": 100,
    "note": "Confirm to actually start. Once launched, contacts begin receiving outreach."
  }
}

# Step 2: Execute after human review
curl -X POST https://api.vendo-ai.com/v1/campaigns/abc123/launch \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'

Idempotency

For any POST / PATCH / DELETE request, pass an Idempotency-Key header. The API guarantees that replaying the same request with the same key returns the same result without re-executing the side effect.

bash
curl -X POST https://api.vendo-ai.com/v1/campaigns \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: my-unique-key-123" \
  -H "Content-Type: application/json" \
  -d '{"name": "Q3 Outreach", "agent_id": "..."}'

# Second call with same key → replays cached response.
# Look for the X-Idempotency-Replay: true response header — it tells you
# the request hit the cache instead of running the side effect.
  • Same key + same request → cached replay (no side effects)
  • Same key + different request → 409 idempotency_conflict
  • TTL: 24 hours (keys expire after that)
  • Namespace: per API key (no cross-tenant collisions)

MCP — Model Context Protocol

The Vendo AI MCP server exposes the entire /v1 API surface as 149 MCP tools that any compatible AI assistant (Claude, ChatGPT, Cursor, Windsurf, etc.) can call. Your AI assistant can create agents, search audiences, launch campaigns, and monitor results — all in natural language.

MCP Endpoint

https://api.vendo-ai.com/mcp — Streamable HTTP transport (POST for JSON-RPC, GET for SSE, DELETE to close session)

MCP Setup & Connection

Claude Desktop / Claude Code

json — ~/.claude.json or claude_desktop_config.json
{
  "mcpServers": {
    "vendo-ai": {
      "url": "https://api.vendo-ai.com/mcp",
      "headers": {
        "Authorization": "Bearer vnd_live_YOUR_KEY_HERE"
      }
    }
  }
}

ChatGPT / Other MCP Clients

Point any MCP-compatible client at https://api.vendo-ai.com/mcp with your API key as the Bearer token. The server uses Streamable HTTP transport and returns a mcp-session-id header that the client must include in subsequent requests.

How MCP Authentication Works

  • Your API key is presented as Authorization: Bearer vnd_live_… at session start
  • vendo-mcp validates the key through vendo-public-api (same validation as REST)
  • vendo-mcp holds no secrets itself — it's a pure pass-through
  • Every MCP→API call carries X-Vendo-Via: mcp so you can distinguish AI activity in audit logs
  • All security (scopes, rate limits, billing) is enforced in vendo-public-api

149 MCP Tools — Complete Reference

Tools are organized by domain. Destructive actions use paired tool names: preview_* shows what would happen, the action tool executes it. The model must explicitly pick the execute variant — this is stronger than a boolean flag.

36

Agent Tools

Full lifecycle: create, scan, script, avatar, connections, contact channels

23

Campaign & Audience Tools

Campaigns, audience search, saved audiences, Audience Sets marketplace

38

SDR Tools

Signal searches, personas, outreach, observability, CSV export

33

CRM & Communications

Leads, stages, calendar, notifications, settings, outbound stream

6

LinkedIn Tools

Connected accounts, capacity, connect/reconnect/disconnect

13

Billing Tools

Balance, subscription, pricing, invoices, usage, capacity

MCP — Agent Tools (36)

Read Operations

Tool NameDescription
list_agentsList all AI agents in the workspace
list_agents_with_statsList agents with connection + credit stats
get_agentGet full details of a specific agent
get_agent_plan_limitsCapacity check (used vs allowed agent slots)
list_agent_connectionsList all connections for an agent
list_agent_presentationsList presentations attached to an agent
list_narrator_leadsLeads captured by the agent's presentations
get_narrator_analyticsPresentation engagement analytics
get_widget_embed_codeHTML snippet for the website widget
list_retell_voicesAvailable Retell voices for set_agent_voice
list_google_meet_meetingsList Google Meet meetings booked through this agent
get_telegram_bot_infoConnected bot info
get_telegram_analyticsTelegram bot analytics

Create & Configure

Tool NameDescription
create_agentCreate an agent (1 credit)
update_agentUpdate basic-info fields
set_agent_statusACTIVE / PAUSED / DRAFT / ARCHIVED
set_agent_companySet company name + website + description
set_agent_contact_channelsSet the meeting link, email, phone, WhatsApp and Telegram the agent hands out when asked how to get in touch
set_agent_voiceVoice / language / speed config
set_agent_avatar_from_urlSet avatar from a publicly-reachable image URL
duplicate_agentClone an agent
scan_website_quickQuick website scan (no agent id)
save_scan_dataPersist deep-scan output onto an agent
generate_agent_descriptionAI company description (1 credit)
generate_agent_scriptGenerate full sales script (1 credit, 8 stages)
connect_google_meetReturns Google OAuth URL — open in a browser
disconnect_google_meetDisconnect Google Meet
connect_telegram_botConnect bot (body: { bot_token })
disconnect_telegram_botDisconnect Telegram bot

Preview (Non-Destructive)

Tool NameDescription
preview_agent_emailRender an example outreach email
preview_linkedin_inviteRender a LinkedIn connection request
preview_linkedin_followupRender a LinkedIn follow-up message
preview_deep_scanWhat deep_scan_agent would cost + cover
preview_delete_agentWhat delete_agent would remove

Destructive Actions (Require Prior Preview)

Tool NameDescription
deep_scan_agentExecute deep website scan — 15 credits
delete_agentPermanently delete an agent

MCP — Campaign & Audience Tools (23)

Tool NameDescription
list_campaignsList all campaigns
get_campaignCampaign details + live stats
create_campaignCreate a campaign (DRAFT)
update_campaignUpdate campaign settings
pause_campaignPause all channels
pause_channelPause one channel (email / linkedin / phone_call / voice_call)
resume_channelResume one channel
archive_campaignArchive
preview_launch_campaignRecipients / channels / cost preview
launch_campaignExecute launch
preview_delete_campaignDeletion preview
delete_campaignPermanently delete
search_audienceFree preview search of the people graph
save_audienceSave matched contacts as a reusable audience
list_audiencesList saved audiences
get_audienceRead one saved audience
list_audience_setsBrowse the Audience Sets marketplace
get_audience_setDetails of one set by slug
get_audience_set_contactsPreview contacts in a set
preview_buy_audience_setDry-run of buying a set — shows cost, charges nothing
buy_audience_setSpends credits. Buys a set
preview_launch_audience_setDry-run of buying + launching outreach
launch_audience_setSpends credits and starts real outreach.

MCP — CRM & Communications Tools (33)

Tool NameTypeDescription
crm_list_leadsreadList pipeline leads with filters (stage/source/search/range)
crm_get_leadreadFull lead card incl. origin and company enrichment
crm_get_conversationreadMessage thread with the lead on their source channel
crm_statsreadPipeline stats: per-stage counts, new, stale
crm_list_stagesreadOrdered kanban stages
crm_create_leadwriteAdd a manual lead (all fields optional)
crm_update_leadwritePatch lead attributes
crm_move_leadwriteMove lead to another stage
crm_reply_to_leadwrite ⚠️Real outbound message — the model must show the draft to the human first
crm_add_commentwriteInternal note on the card
crm_enrich_from_linkedinwriteProfile lookup + unverified pattern-guess email; consumes LinkedIn budget
crm_create_stagewriteAdd custom kanban column
crm_update_stagewriteRename / recolor stage
preview_delete_crm_leaddry-runPreview lead deletion
delete_crm_leaddestructiveSoft-delete lead (after preview + human approval)
preview_delete_crm_stagedry-runPreview stage deletion
delete_crm_stagedestructiveDelete empty non-system stage
crm_list_workspace_membersreadList people who can own a CRM lead. Call before reassigning
crm_list_workspace_agentsreadList AI agents leads can be attributed to
crm_list_linkedin_accountsreadList LinkedIn accounts connected to the workspace
reassign_crm_leadwriteChange who owns a lead
crm_list_calendar_eventsreadList custom CRM calendar events for a date range
crm_create_calendar_eventwriteAdd an event to the CRM planner
crm_update_calendar_eventwriteEdit a calendar event
crm_delete_calendar_eventwriteRemove a calendar event
crm_list_notificationsreadList CRM notifications
crm_mark_notification_readwriteMark one notification as read
crm_mark_all_notifications_readwriteClear the notification badge
crm_get_settingsreadRead CRM settings including notify_* toggles
crm_update_settingswriteChange CRM settings, e.g. mute notifications
crm_communication_cardsreadList communication cards (full outbound stream)
crm_communication_historyreadOutbound history for one campaign or SDR search
crm_communication_threadreadFull message thread with one contact

MCP — SDR Tools (38)

Tool NameDescription
sdr_list_searchesList Signal Searches in the workspace
sdr_get_searchOne Signal Search by id
sdr_preview_searchPreview the Claude-generated ICP profile before saving
sdr_create_searchCreate a Signal Search (hunters start immediately)
sdr_update_searchUpdate name / sources / regions / profile
sdr_activate_searchSet status=active
sdr_pause_searchPause hunters
sdr_resume_searchResume hunters
sdr_regenerate_searchRe-run Claude on the agent's KB
sdr_preview_delete_searchPreview deletion
sdr_delete_searchPermanently delete (paired)
sdr_get_agent_signal_profileRead the agent's signal profile
sdr_generate_agent_signal_profile(Re-)generate via Claude
sdr_list_personasPersonas discovered for a search
sdr_persona_statsCounts, by-role, top companies, credits spent
sdr_export_personas_to_audienceSave personas as a reusable audience
sdr_get_outreachOutreach campaign status for a search
sdr_preview_launch_outreachPreview launch counts + channels
sdr_launch_outreachLaunch outreach (paired)
sdr_get_outreach_contentRead configured templates
sdr_update_outreach_contentEdit templates
sdr_preview_outreach_contentRender personalised preview
sdr_pause_outreachPause sending
sdr_resume_outreachResume sending
sdr_preview_delete_outreachPreview deletion
sdr_delete_outreachDelete outreach campaign
sdr_run_statesPer-source hunter states
sdr_healthOperator health view for a search
sdr_signal_statsSignals by source over the last N days
sdr_recent_signalsWorkspace-wide recent signals
sdr_company_heatHottest companies by composite signal strength
sdr_learning_insightsPer-signal-type weights from outcome learning
sdr_preview_run_nowPreview triggering an immediate hunter run
sdr_run_nowTrigger an immediate hunter run (paired)
sdr_get_person_detailWhy a person was picked: hunter, query, signal, scores
sdr_export_people_csvExport a search's contacts as CSV text
sdr_activity_feedLive discovery + outreach ticker for a search
sdr_outreach_summarySent/queued counters per channel

MCP — LinkedIn Tools (6)

Tool NameDescription
list_linkedin_accountsList connected accounts and capacity
connect_linkedin_accountGet a hosted URL for a human to authorise an account
preview_reconnect_linkedin_accountDry-run of reconnecting
reconnect_linkedin_accountRe-authenticate an account (changes its id)
preview_disconnect_linkedin_accountDry-run of disconnecting
disconnect_linkedin_accountRemove an account; sending from it stops

MCP — Billing Tools (13)

Tool NameDescription
get_balanceCurrent credit balance (lightweight)
get_balance_fullBalance + plan + spent totals
get_subscriptionPlan, status, period dates, currency
get_subscription_limitsMax agents (base + add-on slots)
get_pricingPublic pricing catalogue (plans + add-ons)
get_credit_transactionsCredit transaction history with filters
get_invoicesStripe invoice history
get_credit_usage_by_typeSpend grouped by action type
get_credit_usage_monthlyPer-month spend breakdown
get_credit_usage_by_agentSpend per agent (workspace-wide)
get_credit_usage_for_agentSpend for one agent
get_credit_usage_for_agent_connectionsPer-channel spend for one agent
get_sdr_email_capacitySDR managed-sender entitlement + daily limit

MCP — Destructive Action Safety

In MCP, destructive actions use paired tool names instead of boolean flags. This is safer because the AI model must explicitly choose the execute variant — it can't accidentally pass confirm: true to a tool.

Preview ToolExecute ToolAction
preview_launch_campaignlaunch_campaignLaunch outreach campaign
preview_delete_agentdelete_agentDelete an AI agent
preview_delete_campaigndelete_campaignDelete a campaign
preview_deep_scandeep_scan_agentDeep website scan (15 credits)
sdr_preview_delete_searchsdr_delete_searchDelete a Signal Search
sdr_preview_launch_outreachsdr_launch_outreachLaunch SDR outreach
sdr_preview_delete_outreachsdr_delete_outreachDelete SDR outreach campaign
sdr_preview_run_nowsdr_run_nowManual hunter trigger
preview_delete_crm_leaddelete_crm_leadSoft-delete a CRM lead
preview_delete_crm_stagedelete_crm_stageDelete a CRM pipeline stage
preview_buy_audience_setbuy_audience_setBuy an Audience Set (spends credits)
preview_launch_audience_setlaunch_audience_setBuy + launch outreach on an Audience Set
preview_reconnect_linkedin_accountreconnect_linkedin_accountRe-authenticate a LinkedIn account
preview_disconnect_linkedin_accountdisconnect_linkedin_accountDisconnect a LinkedIn account

Why Paired Names?

The tool name itself encodes intent. An AI assistant cannot accidentally call launch_campaign when it meant to preview — it has to deliberately pick the execute name. Combined with tool descriptions that say "Only call AFTER the user has reviewed the preview," this gives stronger safety than a boolean flag.

Guide: Create an Agent via API

The full agent onboarding pipeline:

bash — full agent pipeline
# 1. Create the agent (description is REQUIRED — NOT NULL in DB).
AGENT=$(curl -s -X POST https://api.vendo-ai.com/v1/agents \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Sales Agent", "description": "Outbound SDR for SaaS"}')
AGENT_ID=$(echo $AGENT | jq -r '.data.id')

# 2. (Optional) quick scan to fetch the company website's structure.
curl -s -X POST https://api.vendo-ai.com/v1/agents/scan \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"website_url": "https://example.com"}'

# 3. Set company info — REQUIRED before generate-script will work.
curl -s -X PATCH https://api.vendo-ai.com/v1/agents/$AGENT_ID/company \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Example Inc",
    "company_website": "https://example.com",
    "company_description": "We build internal tools for revenue teams."
  }'

# 4. Generate the conversational + email script (1 credit, 8-stage AI).
curl -s -X POST https://api.vendo-ai.com/v1/agents/$AGENT_ID/generate-script \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"script_style": "FRIENDLY_CASUAL", "purpose": "sales"}'

# 5. Set the avatar from a public URL. The API downloads and stores it locally.
curl -s -X PATCH https://api.vendo-ai.com/v1/agents/$AGENT_ID/avatar \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"image_url": "https://example.com/avatar.jpg"}'

# 6. Preview what this agent would send before launching anything.
curl -s -X POST https://api.vendo-ai.com/v1/agents/$AGENT_ID/preview/email \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" -d '{}'

Guide: Launch a Campaign

bash — campaign launch flow
# 1. Search for audience
curl -s -X POST https://api.vendo-ai.com/v1/audiences/search \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"positions": ["CTO", "VP Engineering"], "countries": ["United States"], "companySizes": ["small", "medium"]}'

# 2. Save the audience
AUDIENCE=$(curl -s -X POST https://api.vendo-ai.com/v1/audiences \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Tech Leaders Q3", "search_params": {...}}')

# 3. Create campaign
CAMPAIGN=$(curl -s -X POST https://api.vendo-ai.com/v1/campaigns \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Q3 Outreach", "agent_id": "...", "audience_id": "..."}')
CAMPAIGN_ID=$(echo $CAMPAIGN | jq -r '.data.id')

# 4. Preview launch (dry_run)
curl -s -X POST https://api.vendo-ai.com/v1/campaigns/$CAMPAIGN_ID/launch \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

# 5. Launch after review
curl -s -X POST https://api.vendo-ai.com/v1/campaigns/$CAMPAIGN_ID/launch \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'

Guide: SDR Signal Pipeline

bash — SDR pipeline
# 0. (Optional) Preview the AI-generated profile before creating the search
curl -s -X POST https://api.vendo-ai.com/v1/sdr/searches/preview \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "AGENT_UUID"}'

# 1. Create a signal search (target_regions is required by the wizard).
#    workspace_id and user_id are injected automatically from your API key.
SEARCH=$(curl -s -X POST https://api.vendo-ai.com/v1/sdr/searches \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VP Sales hunt — US",
    "agent_id": "AGENT_UUID",
    "target_regions": ["US"],
    "enabled_sources": ["linkedin_jobs", "connected_people"]
  }')
SEARCH_ID=$(echo $SEARCH | jq -r '.data.search.id')

# 2. List people the hunters discovered
curl -s "https://api.vendo-ai.com/v1/sdr/people?search_id=$SEARCH_ID&limit=20" \
  -H "Authorization: Bearer $KEY"

# 3. Check signal stats for that search (default window: last 30 days)
curl -s "https://api.vendo-ai.com/v1/sdr/searches/$SEARCH_ID/stats" \
  -H "Authorization: Bearer $KEY"

# 4. Export people to a saveable audience that any campaign can use
curl -s -X POST https://api.vendo-ai.com/v1/sdr/people/export-to-audience \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d "{ \"search_id\": \"$SEARCH_ID\", \"name\": \"Signal-found leads\" }"

Guide: Zapier & Make Integration

Connect Vendo AI to 5,000+ apps through Zapier or Make (Integromat):

Zapier: Use Webhooks by Zapier

  1. Add a "Webhooks by Zapier" action step
  2. Choose "Custom Request"
  3. Set method, URL (e.g., https://api.vendo-ai.com/v1/agents), and headers (Authorization: Bearer vnd_live_...)
  4. Set Content-Type: application/json and add your request body

Make: Use HTTP module

  1. Add an "HTTP: Make a request" module
  2. Set URL, method, and headers identically
  3. Parse the JSON response to use in subsequent steps

Scopes Reference

Every API key has a set of scopes that control which endpoints it can access. By default, all scopes are granted when you create a key.

ScopeAllows
agents:readList and get agents, connections, previews
agents:writeCreate, update, delete agents; scan websites; generate scripts
audiences:readSearch the people graph (preview)
audiences:writeSave audiences, enrich contacts
campaigns:readList and get campaigns with stats
campaigns:writeCreate, update, delete campaigns
campaigns:controlLaunch, pause, resume, archive campaigns (separate scope for safety)
analytics:readFunnel and per-campaign analytics
crm:readRead CRM leads, conversations, pipeline stages, calendar, notifications, settings and the Communications stream
crm:writeCreate and update leads, move them between stages, reply, comment, reassign, manage stages, calendar events and CRM settings
billing:readCredit balance, subscriptions, invoices, usage history

No billing:write — By Design

There is intentionally no billing:write scope. Top-ups, plan changes, and payment actions happen only in the authenticated portal. A leaked key cannot spend money beyond the metering it already triggers through normal API usage.

Coverage & Limits

The API mirrors the web app: agents, campaigns, SDR discovery and outreach, audiences, the CRM and LinkedIn account management are all available programmatically.

Intentionally UI-only

Anything that moves money stays on the authenticated portal, so a leaked API key can never trigger a charge. These actions are deliberately NOT exposed by the Public API or MCP — Stripe Checkout / Customer Portal flows are inherently browser-bound:

  • Subscription Checkout (POST /api/billing/stripe/create-checkout-session)
  • One-time credit top-up Checkout (POST /api/billing/stripe/create-credit-checkout)
  • Stripe Customer Portal redirect (POST /api/billing/stripe/customer-portal)
  • Retry payment on an open invoice (POST /api/billing/stripe/pay-invoice)
  • Cancel / resume a subscription (POST /api/billing/subscriptions/cancel|resume)
  • Buy extra agent slot ($20/mo recurring add-on)
  • Buy extra SDR sender pair ($20/mo recurring add-on)

Billing is fully readable — balance, subscription, pricing, transactions, invoices and credit-usage breakdowns — but never writable. There is no billing:write scope, and there will not be one. Customers who need automated top-ups can use the Stripe Customer Portal directly and set auto-recharge there. We are tracking webhook-based notifications (credits.low, subscription.canceled) as a future addition — see "What's Next" below.

Requires a Human Step

  • Connecting a LinkedIn account. The API returns a hosted authorisation URL; a person must complete the flow in a browser.

Streaming

The web app uses server-sent events for live SDR activity. The API exposes the same data through polled endpoints (/v1/sdr/searches/:id/outreach/activity-feed) rather than a stream.

Changelog

2026-07-22 — Phase 7: Full UI Parity

  • +30 REST endpoints (173 total) and +36 MCP tools (149 total) — everything you can do in the web app is now available programmatically, except payment operations
  • New domains: Audience Sets marketplace and LinkedIn Accounts management
  • CRM expanded: workspace members, calendar, notifications, settings, and the full outbound Communications stream
  • SDR additions: CSV contact export, per-person provenance, activity feed, outreach summary
  • Protected Routes grew from 8 to 12; scopes crm:read / crm:write registered for key issuance

2026-07-06 — CRM Domain Added

  • 16 REST endpoints + 17 MCP tools for the built-in Vendo CRM
  • Read your live pipeline, reply to leads on their source channel, manage kanban stages, and enrich contacts from LinkedIn
  • New scopes: crm:read / crm:write
  • Coverage grew to 6 domains with the CRM addition

2026-06-15 — Full Platform Coverage

  • Phase 5c — 13 billing read-only tools and 13 endpoints (balance, subscriptions, invoices, usage)
  • Phase 5b — 34 SDR tools, 37 endpoints covering the full signal pipeline
  • Phase 5a — 29 agent tools, 59 endpoints covering full agent lifecycle
  • Phase 4 — MCP server launched at api.vendo-ai.com/mcp
  • Phase 2.5 — Destructive action protocol, idempotency keys
  • Phase 3 — Frontend Settings → API & MCP tab shipped
  • Phases 1–2 — Core API: agents read, campaigns CRUD, audiences, billing balance

What's Next

Webhooks — outbound events for campaign.launched, email.replied, persona.discovered

OpenAPI spec — downloadable at /v1/openapi.json

Spend ceiling — per-session credit limits for MCP usage

Scroll to Top