Leads
created, updated, deleted
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.
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.
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.
created, updated, deleted
created, updated, deleted
created, updated, deleted
created, updated, deleted, won, lost
created, updated, public reply added
created, updated, paid
created, updated, deleted
Step-by-step recipes for each are in the docs. None of them needs anything installed on the CRM side.
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.
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.
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.
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.
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 likeFrom 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.
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.
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.
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.
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.
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.
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.
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.
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.
Accounts, deals, tasks and invoices cannot be imported from a file. They are created through the API, which is how a migration moves them.
The event catalogue, the retry schedule and the address checks are all in the open repository.
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.
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.
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.
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.
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.
No per-integration fee and no event quota. Host it yourself, or let MicroPyramid run it.