Elevion API
Your leads, in every tool you use
Read leads and campaigns, pause a campaign from your own app, and get a signed webhook the moment someone new writes, leaves their email or taps your link. Part of the Business plan.
Getting started
Create a key in Settings, Integrations. It starts with elv_live_ and is shown once. Every key belongs to one workspace and only sees that workspace. Send it as a Bearer token:
curl https://elevion.cc/api/v1/me \
-H "Authorization: Bearer elv_live_YOUR_KEY"{ "workspace": { "id": "…", "name": "Nora's studio" }, "key": { "id": "…", "name": "Zapier" } }Leads
A lead is a person who got a DM from one of your campaigns. Newest first, up to 100 per page. Pass the nextCursor you got back to read the next page.
GET
/leadsFilters:status(contacted, replied, captured, opted_out),campaignId,email,since(an ISO date),limit(1 to 100) andcursor.GET
/leads/{id}One lead, or 404 if it isn't in this workspace.
curl "https://elevion.cc/api/v1/leads?status=captured&limit=50" \
-H "Authorization: Bearer elv_live_YOUR_KEY"{
"data": [
{
"id": "8c1d0e7a-...",
"instagramUsername": "mia.moves",
"email": "mia@example.com",
"phone": null,
"status": "captured",
"keyword": "GUIDE",
"replies": 2,
"campaign": { "id": "f2a9...", "name": "Free guide" },
"instagramAccount": "nora.jade",
"createdAt": "2026-10-20T09:14:02.000Z",
"capturedAt": "2026-10-20T09:16:40.000Z",
"lastReplyAt": "2026-10-20T09:16:40.000Z"
}
],
"nextCursor": "eyJ0IjoiMjAyNi0xMC0yMFQwOToxNDowMi4wMDBaIiwiaWQiOiI4YzFkIn0"
}Campaigns
GET
/campaignsYour campaigns with status, trigger, keywords and link. Filter with status.PATCH
/campaigns/{id}Pause or resume. Resuming follows the same rules as the dashboard: your plan, a connected Instagram account and no other campaign answering the same keyword.GET
/deliveriesMatched comments and what Elevion did with each, newest first, with the same cursor paging as leads.
curl -X PATCH https://elevion.cc/api/v1/campaigns/CAMPAIGN_ID \
-H "Authorization: Bearer elv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "paused" }'Webhooks
Subscribe an https address to an event. Elevion checks for new events every minute and sends each one as a POST with JSON. Subscriptions start from now, older events aren't sent.
lead.createdSomeone new got a DMlead.capturedThey left an email or numberlink.tappedThey opened your link, once per person
POST
/hooksBody: event and url. The answer includes a secret, shown once, for checking signatures.GET
/hooksYour subscriptions and whether they're working.DELETE
/hooks/{id}Unsubscribe. Answering any event with 410 Gone unsubscribes too.
curl -X POST https://elevion.cc/api/v1/hooks \
-H "Authorization: Bearer elv_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "event": "lead.captured", "url": "https://example.com/elevion" }'POST https://example.com/elevion
x-elevion-event: lead.captured
x-elevion-signature: t=1792500000,v1=5f2b…
{ "type": "lead.captured", "id": "lead.captured:8c1d…", "createdAt": "…", "data": { "lead": { … } } }The signature is an HMAC-SHA256 of the timestamp, a dot and the raw body, keyed with your secret. Answer with any 2xx within 10 seconds. Failed deliveries are retried up to 6 times over about 6 hours, and a webhook that keeps failing is switched off and your team gets a notification. Use the event id to skip duplicates.
import { createHmac, timingSafeEqual } from "node:crypto";
export function fromElevion(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((part) => part.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}Zapier and Make
There's no Elevion app in the Zapier or Make directories yet. You can connect both today:
- In Zapier, add a Webhooks by Zapier trigger with Catch Hook. In Make, add a Custom webhook. Copy the address it gives you.
- Subscribe that address with the POST /hooks request above, using the event you want.
- Send yourself a test: comment your keyword from a second account. The event shows up in Zapier or Make within a minute.
Errors and limits
Errors come back as JSON with a readable error and a stable code. Each key can make 120 requests a minute; above that you get 429 with a retry-after header.
- 401
invalid_keyThe key is missing, wrong or revoked. - 403
upgrade_requiredThe workspace isn't on Business anymore. - 400
invalid_inputA parameter is missing or doesn't fit. - 404
not_foundIt doesn't exist in this workspace. - 409
campaign_overlapAnother campaign already answers this keyword. - 429
rate_limitedSlow down for a minute.