Skip to content
Webhooks, CSV and the API

Tell Your Other Tools the Moment It Happens

A lead arrives, a deal is won, a customer gets a reply: a signed request goes to Slack, Zapier, n8n or your own code. And when the data has to move in bulk, the lists import and export as CSV.

No per-integration fee and no task quota. MIT licensed, self-host it anywhere.

One POST per event, signed

An admin adds a URL in Settings, on the web or the phone, and picks the events it should hear about. Up to ten per organisation.

  • Signed HMAC-SHA256 on every JSON delivery Keyed with a secret the server generates and shows you twice in its life: when the webhook is created and when you rotate it. The signature covers a timestamp, so a captured request cannot be replayed later.
  • Retried Six attempts over about eight and a half hours A failure is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours. A 410 from your end turns the webhook off and says why. Every delivery is in a log you can read and redeliver from.
  • Admin only Reading the list included A hook URL is often a secret of its own, and every endpoint receives copies of your records, so members cannot see webhooks at all. An API token cannot create one either: only a signed-in admin can.
Payloads, headers and the signature check
[ APP.BOTTLECRM.IO/SETTINGS/WEBHOOKS ]
What you can subscribe to

Seven modules, twenty-three events

Won and lost follow the kind of stage a deal enters in your own pipeline, not a stage name. Ticket replies go out only when they are public; an internal note is never sent anywhere.

Leads

created, updated, deleted

Contacts

created, updated, deleted

Accounts

created, updated, deleted

Deals

created, updated, deleted, won, lost

Tickets

created, updated, public reply added

Invoices

created, updated, paid

Tasks

created, updated, deleted

Where to point it

Slack, Zapier, n8n, or your own endpoint

Step-by-step recipes for each are in the docs. None of them needs anything installed on the CRM side.

Slack

Paste an incoming-webhook URL and pick the Slack format. Each event becomes one line in the channel, such as "Deal won: Acme renewal", with names escaped, so a record named to ping the whole channel cannot.

Zapier

Point a webhook at a Webhooks by Zapier Catch Hook, send one real event as the sample, and map the fields from there. Filter on the event name if one hook listens for several.

n8n

Use a Webhook node on its production URL. Turn on the raw body and a Code node can check the signature before anything else runs, then a Switch node routes on the event.

Your own code

Verify the signature against the raw body, compare in constant time, and de-duplicate on the event id, which stays the same across redeliveries. The docs carry the function in Python and Node.

In bulk

CSV in, CSV out, on the web and the phone

Import is preview first, so a file tells you what it would do before it does it. Export is the list you are looking at, filters and all.

Headers, limits and what an error looks like

Import leads, contacts and tickets

From the Import button on the list, in the web app or the phone app. Pick a file and you see every row that would be created and every row that is wrong, with the row and the field named. Nothing is written until you commit.

All or nothing

Commit checks the whole file again from scratch, and if any row is invalid it creates none. Half an import is harder to clean up than no import. Up to 5,000 rows and 5 MB per file.

References stay inside your org

An account name, an assignee, a team or a contact in the file is looked up in your organisation only. A name that does not resolve is a row error, not a silent skip and not a new record.

Export six lists

Leads, contacts, accounts, deals, tickets and invoices, from the Export button on the web or the phone. The file is the list you are looking at, with its filters, every page of it.

Only what you can see

Any member can export, and each person gets exactly the rows the list would show them. A rep who sees only their own deals exports only their own deals.

Safe to open in a spreadsheet

A cell that starts like a formula is written so a spreadsheet reads it as text. Somebody typing a formula into your web form cannot have it run on a colleague's machine when the export is opened.

Read this before you build on it

What these do not cover

Webhooks send events out. Writing back into the CRM from another tool is the JSON API, which every entity has and which the mobile app itself runs on.

No app in the Zapier or n8n catalogue

Both recipes use the generic webhook trigger each tool already has. There is no BottleCRM app to install in either, so there are no ready-made actions for writing back into the CRM; that direction is the API.

Not to your private network

A webhook URL has to be public HTTPS. Private, loopback and cloud-metadata addresses are refused when the URL is saved and again before every attempt. A receiver inside your network needs a public endpoint in front of it.

Four things have no importer

Accounts, deals, tasks and invoices cannot be imported from a file. They are created through the API, which is how a migration moves them.

Questions

Before you wire it up

Check for yourself

The event catalogue, the retry schedule and the address checks are all in the open repository.

Which events can I subscribe to?

Twenty-three, across leads, contacts, accounts, deals, tickets, invoices and tasks. Deals add won and lost, which fire when a deal enters a stage whose kind is won or lost in your own pipeline, whatever that stage is called. Tickets send public replies but never internal notes. Each webhook subscribes to the events it wants.

What is in a delivery?

A fixed envelope: an event id, the event name, a timestamp, your org id and a data object holding a fixed, explicit set of fields for that module. Secrets, password fields and an invoice's public link are never included, and an id from another organisation never appears.

What happens if my endpoint is down?

The delivery is retried five more times over about eight and a half hours and then marked failed, and you can redeliver it from the log once you are back. Delivery is at least once, so the same event can arrive twice; the event id is what you de-duplicate on.

Can a member of my team set one up?

No. Only an admin can see or change webhooks, and only from a signed-in session: a personal access token or the org API key is refused, whatever scopes it carries. A webhook keeps sending after the token that made it is revoked, so creating one is treated like creating a credential.

Can I import deals or accounts from a spreadsheet?

Not from a file. Leads, contacts and tickets import from CSV in the web app and the phone app; accounts, deals, tasks and invoices go in through the API. Every one of the six main lists exports to CSV.

Connect it to the tools you already run

No per-integration fee and no event quota. Host it yourself, or let MicroPyramid run it.

MIT licensed Signed webhooks 100% data ownership