API reference
Everything the app does is available over HTTPS. Create a key under API keys. Secret keys (hk_live_…) can do everything; publishable keys (hk_pub_…) can only submit form leads, so they are safe to ship in a website.
Authorization: Bearer hk_live_… # or: x-api-key: hk_live_…Leads are matched on email (case-insensitive) or on source + source_ref. A match merges non-empty fields and returns 200; a new lead returns 201.
POST https://usehunter.app/v1/leads
{
"name": "Joe Bloggs", "company": "Joe's Plumbing", "email": "joe@example.com",
"phone": "+1 905 555 0100", "website": "joesplumbing.ca", "city": "Hamilton",
"source": "zapier", "tags": ["ads"], "notes": "Asked about a water heater"
}Accepts JSON or a plain HTML form post. Works from any origin with a publishable key. A filled _gotcha field silently drops bots.
<form action="https://usehunter.app/v1/forms" method="post">
<input type="hidden" name="x-api-key" value="hk_pub_…">
<input name="name" placeholder="Your name" required>
<input name="email" type="email" required>
<textarea name="message"></textarea>
<input name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
<button>Send</button>
</form>With JavaScript, send the key as a header instead of a field.
No website needed. Every publishable key also serves a Hunter-hosted form at https://usehunter.app/f/hk_pub_… that shows your business name and booking link. Put it in an Instagram bio, a Google Business Profile, or a QR code. GET /forms with the key returns the public profile the page renders.
One line adds a floating button to any website that opens your hosted form. Works on site builders that allow script embeds (Webflow, Framer, Squarespace, WordPress).
<script src="https://usehunter.app/widget.js" data-key="hk_pub_…" defer></script>
<!-- optional -->
data-label="Request a callback" data-color="#0a5c36" data-position="left"Cal.com, Calendly, Typeform, Tally and Jotform post directly to an inbound URL you create under Integrations. Bookings arrive as qualified leads tagged booked; form answers are matched to fields by their labels and anything else lands in notes. Paste the provider's signing secret when it offers one and Hunter rejects unsigned deliveries.
POST https://usehunter.app/v1/inbound/calcom/<token> # Cal.com → Webhooks
POST https://usehunter.app/v1/inbound/calendly/<token> # Calendly → Integrations → Webhooks (invitee.created)
POST https://usehunter.app/v1/inbound/typeform/<token> # Typeform → Connect → Webhooks
POST https://usehunter.app/v1/inbound/tally/<token> # Tally → Integrations → Webhooks
POST https://usehunter.app/v1/inbound/jotform/<token> # Jotform → Settings → Integrations → WebHooks
POST https://usehunter.app/v1/inbound/generic/<token> # any JSON: {"name","email","phone","company","message"}Under Integrations → Phone, connect a Twilio account and pick a number; Hunter points the number's SMS and voice webhooks at itself, so nothing is configured in the Twilio console. From then on every text becomes a lead message (and hands off through Autopilot like an email reply), and a missed call texts the caller back within seconds and opens a task. Connect ElevenLabs and Hunter builds two Conversational AI agents from your business profile: a receptionist that can answer the number, and an outbound agent for one-off follow-up calls. Paste the post-call webhook URL Hunter gives you into ElevenLabs so transcripts, summaries and collected details (name, email, need, intent) land on the lead.
Twilio webhooks (set automatically):
POST https://usehunter.app/functions/v1/twilio-sms # inbound texts + delivery status
POST https://usehunter.app/functions/v1/twilio-voice # ring-me mode: forward, then text back
ElevenLabs post-call webhook (paste once):
POST …/functions/v1/elevenlabs-webhook?token=<from Integrations>
Events: call.missed · call.completed · message.sent / message.replied carry "channel": "sms" | "call"Outbound AI calls are only ever placed by a person, one lead at a time, after confirming consent. Hunter will not cold-call a list. Texts honour STOP automatically.
GET https://usehunter.app/v1/leads?stage=new&limit=50&since=2026-09-01T00:00:00Z
GET https://usehunter.app/v1/leads/:id
PATCH https://usehunter.app/v1/leads/:id {"stage":"qualified","tags":["hot"]}
DELETE https://usehunter.app/v1/leads/:id
POST https://usehunter.app/v1/leads/:id/enroll {"sequence_id":"…"}
GET https://usehunter.app/v1/sequencesStart a lead-finding run. Requires Apify connected in Integrations. Results land in your leads as they complete; poll the hunt or subscribe to hunt.completed.
POST https://usehunter.app/v1/hunts
{"kind":"google_maps","query":"plumbers","location":"Hamilton, ON","max_results":50}
GET https://usehunter.app/v1/hunts/:id → {"status":"succeeded","leads_found":48,"leads_new":41}Add an HTTPS endpoint under Integrations. Every delivery is signed; verify it before trusting the body.
x-hunter-event: lead.created | lead.stage_changed | lead.won | lead.handoff | message.sent | message.replied | hunt.completed
x-hunter-signature: t=1725300000,v1=<hex hmac-sha256(secret, t + "." + body)>
{ "id": "…", "type": "lead.created", "created_at": "…", "data": {…},
"lead": { "id": "…", "name": "…", "company": "…", "email": "…", "stage": "new", … } }Deliveries retry five times with backoff. Reject timestamps older than five minutes.
Use a Webhooks-by-Zapier "Catch Hook" as a Hunter webhook endpoint for outbound, and a "POST" action against /v1/leads (or a generic inbound URL, which needs no API key) for inbound. No Hunter-specific app is needed.
Export a CSV from HubSpot, Pipedrive, Zoho, a spreadsheet or anything else and use Import on the Leads page. Columns are matched by name, first and last names are joined, and rows whose email already exists are merged rather than duplicated. Up to 5,000 rows per file.
{"error":"email: Invalid email"} # 422 validation
{"error":"Invalid or revoked API key"} # 401
{"error":"Connect Apify in Integrations before starting a hunt"} # 412