API and webhooks overview
What the OmniLead REST API can do, how requests and responses look, and where to find every endpoint.
The OmniLead REST API lets you search the four lenses, reveal contacts, manage leads and pipelines, enroll leads in sequences and keep your own systems in sync with webhooks. It's the same data and the same rules as the app: every contact comes with its source, credits are charged the same way, and every compliance check still runs.
The API is included in the Agency plan.
Quick start
Create a test key
Go to Settings → API, click Create API key, choose Test, name it and click Create key. Copy the key; it's shown once.
Make your first request
List your leads with the key in the
Authorizationheader.Switch to a live key
When your integration works, create a Live key and store it in your secrets manager.
curl https://omni.cloudgens.net/api/v1/leads \
-H "Authorization: Bearer $OMNILEAD_API_KEY" \
-H "OmniLead-Version: 2026-09-28" \
--data-urlencode "limit=10" -Gconst res = await fetch("https://omni.cloudgens.net/api/v1/leads?limit=10", {
headers: {
Authorization: `Bearer ${process.env.OMNILEAD_API_KEY}`,
"OmniLead-Version": "2026-09-28",
},
});
const { data, has_more, next_cursor } = await res.json();import os
import requests
resp = requests.get(
"https://omni.cloudgens.net/api/v1/leads",
headers={
"Authorization": f"Bearer {os.environ['OMNILEAD_API_KEY']}",
"OmniLead-Version": "2026-09-28",
},
params={"limit": 10},
timeout=30,
)
resp.raise_for_status()
page = resp.json()The basics
- Base URL:
https://omni.cloudgens.net/api/v1 - Format: JSON in, JSON out. Send
Content-Type: application/jsonwith a body. - Authentication: a bearer API key. See Authenticate with API keys.
- Versioning: dated versions, sent in the
OmniLead-Versionheader. The current version is2026-09-28. See Versioning and changelog. - Rate limit: 120 requests a minute per key. See Rate limits.
- Errors: one error shape everywhere, with a stable
code. See Handle errors. - IDs: strings with a prefix that tells you the type, such as
lead_,co_,seq_andevt_. - Times: ISO 8601 in UTC, for example
2026-09-28T10:12:44Z.
Pagination
List endpoints use cursors. Pass limit (1–100, default 25) and, for the next page, starting_after set to the previous response's next_cursor:
{
"object": "list",
"data": [{ "id": "lead_7Hq2mR9xKd", "object": "lead", "full_name": "Maya Lindqvist" }],
"has_more": true,
"next_cursor": "lead_7Hq2mR9xKd"
}Stop when has_more is false. Cursors stay valid even if new leads are added while you page.
Search is the one exception: GET /search takes a page number, because each page of results costs 1 credit and you choose how many to buy.
Safe retries with idempotency keys
Every POST accepts an Idempotency-Key header. Send a unique value, such as a UUID, for each operation. If your request times out and you retry with the same key within 24 hours, OmniLead returns the original response instead of doing the work twice, and adds the header Idempotent-Replayed: true. This matters most for reveals and enrollments.
Reusing a key with a different request body returns a 409 with the code conflict.
What you can do
Sequences are built and launched in the app, where the pre-launch checklist runs. The API manages who's enrolled.
Test keys and live keys
- Live keys (
ol_live_…) do everything, including spending credits and sending email through your sequences. - Test keys (
ol_test_…) read and write your CRM data like live keys, but never spend credits or send email. Search returns page 1 free, reveals returnstatus: "dry_run"without the contact details, and enrollments report who would be enrolled or skipped without enrolling anyone. Responses includelivemode: false.
Use a test key while you build, and in the reference's Try it console.
Webhooks
Webhooks tell your systems when something happens in OmniLead: a lead is created, a lead replies, an email bounces, someone unsubscribes, or credits run low. Every delivery is signed so you can check it came from us. See Receive webhooks.