Connecting LumaKol to the software you already run
A workspace API with scoped keys, cursor pagination for syncing, and signed webhooks for the six events that matter to a calling team — plus how to wire it into Zapier, Make, n8n or Pabbly without writing code.

No CRM is the only system a business runs. There is an accounting package, a website, a ticketing tool, a warehouse system, a spreadsheet somebody built in 2019 that everybody still depends on. A CRM that cannot talk to any of them becomes another island, and the bridge between islands ends up being a person copying rows by hand at the end of the day.
LumaKol now has a public API and outgoing webhooks. Between them they cover both directions: you can ask LumaKol for data when you need it, and LumaKol can tell you the moment something happens. This post is about how they are built and how to decide which one to use, rather than a reference — the endpoint list lives in the developer section of the app, next to where you create the keys.
Keys belong to the workspace, not to a person
This is the first design decision, and it is the one that saves you a Monday morning. An API key issued in LumaKol belongs to the workspace. When the developer who created it leaves the company and their account is deactivated, the integration they built keeps running: the key falls back to acting as the workspace owner rather than dying with its author.
Anyone who has run an integration built on a personal login knows why this matters. Those integrations fail silently, weeks after the person left, and the first sign of trouble is a report with a hole in it.
Scopes
A key is issued with an explicit list of what it may do, and nothing else:
| Scope | Allows |
|---|---|
| leads:read | Reading leads, their activity, stages and dispositions |
| leads:write | Creating and updating leads, and adding notes |
| calls:read | Reading logged calls |
| users:read | Reading the workspace’s members |
| webhooks:manage | Creating, editing and removing webhook subscriptions |
Give each integration its own key with the smallest scope that does the job. A dashboard that only draws charts gets leads:read and calls:read and can do no damage even if the key ends up somewhere it should not. A website form handler gets leads:write and cannot read your call history. The habit costs nothing when you create the key and is worth a great deal the day something goes wrong.
Storage and revocation
The key is shown once, at the moment it is created, and never again. What LumaKol stores is a one-way hash of it, so the key cannot be read back out of the database by anyone — including us. If you lose it, you issue a new one; there is no recovery, by design.
Revocation is immediate. Press revoke and the next request made with that key is refused. There is no grace period and no propagation delay to wait out, which is what you want when a laptop goes missing or a contractor’s engagement ends.
Keys also respect the state of the workspace. If a workspace is suspended, its keys stop working entirely. If it is read-only — an expired trial, a cancelled plan — the keys keep serving GET requests but refuse writes, exactly as the app itself does. An integration can never be a back door around the state of the account.
Reading data without hammering the API
The base URL is https://api.lumakol.com/api/v1. Lists are paginated with a cursor rather than page numbers, which matters more than it sounds.
Page numbers break during a sync. You fetch page one, someone updates a lead, the ordering shifts, and page two now starts after a record you never saw. On a nightly sync of a few thousand leads, that is a handful of records missing every night with nothing to indicate it happened. A cursor points at a fixed position in the ordering, so paging through the set gives you every record exactly once even while people are working.
A list response carries the rows, a next cursor, and a flag telling you whether more remain. The loop is: request, process, pass the cursor back, repeat until the flag is false. Combine it with the updated-since filter and an incremental sync becomes simple — ask for everything changed since your last successful run, page through it, store the timestamp, stop. There are filters for stage, owner, source, tag and free text, plus a lookup by your own external identifier so you can match LumaKol’s leads to the records in your own system without keeping a mapping table.
Webhooks: six events worth reacting to
Polling is the wrong tool for anything that needs to happen promptly. If you want a message sent when a lead reaches a particular stage, checking every fifteen minutes means the message is up to fifteen minutes late and you have made ninety-six pointless requests for each useful one.
You can subscribe an HTTPS endpoint of yours to any combination of six events:
- lead.created — a lead entered the workspace, from any source.
- lead.updated — a field on a lead changed.
- lead.stage_changed — the lead moved along the pipeline. The event most business logic hangs off.
- lead.assigned — the lead got a new owner.
- call.logged — a call was recorded against a lead, with its outcome.
- follow_up.due — a promised callback has come due.
Events are queued the instant the thing happens, in the same breath as the change itself, so an event cannot be lost to a restart between the action and the notification. They are also fire-and-forget from the app’s point of view: a webhook endpoint that is down or slow can never delay or fail an agent logging a call.
Verifying that a delivery really came from us
Your endpoint is a URL on the public internet, and anyone who learns it can post to it. Every delivery therefore carries headers identifying the event and the delivery, a timestamp, and an HMAC-SHA256 signature computed over the timestamp and the body using a secret shared only with you.
Your receiver should recompute that signature from the raw request body and compare it before trusting a single field in the payload. Two details matter in practice: use the raw body rather than a re-serialised version of the parsed JSON, because a single whitespace difference changes the signature; and use a constant-time comparison rather than a plain equality check. The secret can be shown again on demand — so you can rebuild a receiver without deleting the webhook — and rotated when you need to.
When your endpoint is down
Failed deliveries are retried on a front-loaded schedule spanning about half a day: the first retries come within minutes, then the gaps widen to hours. A receiver that is down for a deploy loses nothing at all. One that is down all day is given up on, because at that point the events are stale and a queue that grows without bound helps nobody.
Recent delivery attempts are visible in the app with their status, attempt count and the response your endpoint gave, which turns the usual “is it them or us?” argument into a two-minute look at a list. There is also a test delivery button, so you can prove a receiver works before you depend on it. Webhook URLs must be HTTPS and must resolve to a public address — a URL pointing at a private or internal range is refused when you save it and re-checked before every delivery.
Connecting it without writing code
A LumaKol app for Zapier is built and waiting on Zapier’s review; until it appears in their directory, and on Make, n8n or Pabbly Connect, the route is a manual connection. You do not need an app for it. Every one of those platforms offers a generic webhook trigger and a generic HTTP action, and between the two you can build most of what a dedicated app would give you.
- In the automation platform, create a new scenario starting with its incoming webhook trigger — “Webhooks by Zapier”, “Custom webhook” in Make, the Webhook node in n8n, “Catch Hook” in Pabbly. Copy the URL it gives you.
- In LumaKol, add a webhook pointing at that URL and subscribe it to the events you care about. Send a test delivery so the platform can see the payload shape and build its field mapping.
- Add your action step: a row in Google Sheets, a message in Slack, a record in your accounting system, an email to a manager.
- To write back into LumaKol, use the platform’s HTTP request action against the API with one of your keys in the authorisation header — creating a lead, updating a stage or adding a note. If all you need is to send in new leads, a lead source of the “Website or other app” kind (Setup → Lead sources) gives you a private webhook URL that needs no key and applies that source’s owner, stage and tags to every lead.
- Turn the scenario on and, before you rely on it, deliberately break it: point it at a bad URL and watch the delivery list show the failure, so you know what a problem looks like when it happens for real.
Once the Zapier app is listed it will save a few clicks there. The generic path works today on every platform and, because it is a plain signed webhook and a plain REST call, it keeps working regardless of which automation platform you move to later.
このトピックに関する質問
Can I see my API key again after creating it?+
No. Only a one-way hash is stored, so the plaintext key exists solely in the response that created it. If it is lost, revoke it and issue a new one.
What happens to my integrations if the person who built them leaves?+
They keep working. Keys belong to the workspace rather than to an individual, and a key whose creator is no longer an active member falls back to acting as the workspace owner.
How long are failed webhook deliveries retried?+
About half a day, with the attempts front-loaded so a brief outage costs you nothing. After that the delivery is marked failed and the reason is visible in the delivery list.
Do I need webhooks if I am already polling the API?+
Not necessarily, but polling adds latency you cannot remove and makes most of its requests for nothing. Use webhooks for anything that should happen promptly, and the API for bulk reads, backfills and reconciliation.