Connections are how other tools talk to Groundbase without anyone retyping anything. A form on your website posts a lead and it becomes a contact. A booking on Calendly becomes a contact and a meeting. A deal moves to Closed Won and a message lands in your Slack channel. Two directions, one page: Settings → Connections.
- Into Groundbase — a link you paste into another tool. Whatever that tool posts to the link becomes contacts, notes, tasks and tags here.
- Out of Groundbase — a link from another tool that we post to whenever something happens here.
Both directions run on the server, so they work whether or not you have the app open.
Into Groundbase: pick a card, paste a link
Open Into Groundbase and pick the tool you are connecting. Each card is a ready-made recipe: it knows the shape that sender posts and where each field should land. Give it a name, click Create webhook, and you get a link. Paste that link where the sender asks for a webhook URL. The steps for the sender's side are listed under the link.
The link is shown once. Save it before you close the dialog. If you lose it, rotate the webhook from its row and you get a fresh one; the old link stops working.
| Card | What it does | What arrives |
|---|---|---|
| Website form | Any form builder that can POST. Reads the usual field names: name, email, phone, message. | Contact, message kept as a note, tagged Website lead |
| Typeform | Reads answers by question type, so your question titles do not matter. | Contact, long-text answer kept as a note, tagged Website lead |
| Jotform | Reads the submission Jotform posts as form data. Field paths are your form's question ids (q3_name.first, q4_email, and so on) — change them if your form's ids differ. | Contact, message as a note, tagged Website lead |
| Google Forms | Google Forms cannot post to a link on its own. The card gives you a ten-line Apps Script to paste into the form's script editor. Question titles must be Name, Email and Phone, or change the paths. | Contact, tagged Website lead |
| WordPress forms | Gravity Forms, WPForms and Contact Form 7. They send form data, not JSON, which is fine. Paths are Contact Form 7's defaults (your-name, your-email, your-phone, your-message). | Contact, message as a note, tagged Website lead |
| Wix or Squarespace | Both have a native send-to-webhook option. | Contact, tagged Website lead |
| Calendly | Subscribe the link to invitee.created in Calendly's webhook settings. | Contact tagged Booked a call, plus a meeting at the booked time linked to them |
| Facebook Lead Ads | Facebook will not post to us directly; this goes through Zapier or Make with a ready-made recipe. | Contact, tagged Facebook lead |
| Zapier, Make or n8n | The catch-all. Their webhook action posts our own event shape, so nothing needs mapping. | Whatever you send |
| Another Groundbase account | Point the other account's outbound connection at this link. | Contacts copied between accounts you own |
| Something else | A blank link in mapping mode. Send one real submission, paste its body into the editor, and map the fields yourself. | Whatever you map |
A single name field such as "Jo Bloggs" is split into first and last name for you.
When the sender already has the person. Every recipe uses find or create: if a contact with that email or phone already exists, they are updated with the tag rather than duplicated. Their existing fields are left alone, so a second message from the same person is not written over their record.
Two modes: native and mapped
Every inbound link is in one of two modes. The cards pick the right one for you.
Native. The sender posts Groundbase's own shape and nothing needs mapping:
{ "event": "contact.find_or_create",
"data": { "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "phone": "+14165550123", "tags": ["lead"] } }
One event per post. The events you can send:
| Event | Fields |
|---|---|
contact.create | first_name (or name), last_name, email, phone, phone_secondary, company_id, position, city, source, notes, tags |
contact.update | id or email or phone to find them, then any of the fields above |
contact.find_or_create | Same fields as create. Matches by email, then phone; creates if nothing matches |
company.create, company.find_or_create | name, website, industry, notes |
deal.create | title, value_cents, contact_id, company_id, stage_id, notes |
note.create | body, and contact_id, company_id or deal_id |
task.create | title, description, due_at, end_at, kind (task, event, meeting), location, contact_id, company_id, deal_id |
tag.apply, tag.remove | tag_name, and entity_type + entity_id |
Mapped. The sender posts whatever shape it likes and you tell Groundbase where each field is. A mapping is a list of actions; each action is one of the events above plus, for each field, the path to read it from in the sender's body. Paste a real submission into the sample box and every path in it is listed for you to pick from.
Paths are written like this:
| Path | Reads |
|---|---|
email | a top-level key |
data.field:email | a nested key, with a colon in its name |
namedValues.Name[0] or namedValues.Name.0 | the first item of a list |
form_response.answers[type=email].email | the item in a list whose type is email, then its email |
form_response.answers[field.type=long_text].text | the item whose nested field.type is long_text |
payload.name | works even when the sender's body has no payload wrapper — the prefix is tried with and without |
Each action can also carry static values set on every arrival whatever the payload says. The cards use this for the tag.
Actions chain. When a mapping has more than one action, later actions target the record the earlier one created or matched. A contact action followed by a task action links the task to that contact without mapping an id. This is how the Calendly card makes the meeting.
Form data and JSON both work. Senders that post application/x-www-form-urlencoded or multipart/form-data are read the same way as JSON: bracket keys nest (q3_name[first] becomes q3_name.first), repeated keys become lists, and Jotform's rawRequest JSON is unpacked so its question ids are reachable directly.
Watching a link
Each row shows when the link last received something and the last HTTP status. Open the row for the delivery log: every post, what it created or matched, or why it failed. A link that fails fifty times in a row is paused for you and the row says so; fix the sender and resume it.
Optional protections on a link: a signing secret (the sender includes X-Groundbase-Signature, an HMAC-SHA256 of the body, and we refuse posts that do not match) and an IP allowlist.
Out of Groundbase: pick where events go
Open Out of Groundbase and pick a card. Paste the URL that tool gave you, choose the events you want, and click Add webhook. The signing secret is shown once.
| Card | What it does |
|---|---|
| Slack | A message in a channel. Paste an Incoming Webhook URL from your Slack workspace apps. |
| Discord | Same, in a Discord channel. Channel settings → Integrations → Webhooks. |
| Google Sheets | A row per contact or deal change, via Make or Zapier — Sheets cannot receive a webhook itself. |
| Zapier, Make or n8n | Every event we emit, for you to route however you like. |
| Custom URL | Your own endpoint. We POST our event JSON, signed, and retry on failure. |
What we post. For Slack and Discord we post a readable line — 🎉 Deal won: Roof replacement, New contact: Jane Doe (jane@example.com), 💰 Invoice #12 paid: 1,500.00 CAD — in the shape each of them expects. That is decided by the URL's host, so a Slack URL pasted into Custom URL behaves the same as the Slack card.
Everything else gets the event envelope:
{ "id": "…", "type": "deal.won", "created_at": "2026-09-13T15:06:02Z",
"user_id": "…", "entity_id": "<the deal's id>",
"data": { "title": "Roof replacement", "contact_id": "…", "is_won": 1, … } }
data carries the same values the Workflows article lists per event under trigger.payload. Every request also has these headers: X-GB-Event (the event name), X-GB-Delivery (a unique id per attempt, for de-duplicating on your side) and X-GB-Signature (sha256=<hex>, the HMAC-SHA256 of the raw body using your signing secret — compute the same hash on your side and compare).
Events you can subscribe to. Any event from the Workflows trigger table, or * for all of them: contacts, companies, deals (including deal.won and deal.lost), tasks, notes, tags, texts, calls, voicemail, email, invoices and payments.
Retries. A delivery that does not get a 2xx back is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. After that it is marked dead. Open the row to see each delivery's status, HTTP code, attempt count and the receiver's response body; Retry re-queues a failed or dead one. Twenty failures in a row and the subscription is switched off for you — the row reads Paused by Groundbase — so a dead URL does not queue forever. Fix the receiver, then resume.
Test on a row sends one synthetic event to that subscription only, so you can check a URL without touching your other connections.
Connecting a form to a workflow
An inbound link can also be a workflow trigger. In the workflow editor pick Inbound webhook arrives and choose the link; the workflow runs after the link's actions, with the contact they created or matched as its record and the posted body on trigger.payload. "When a form comes in, text the lead" is the link's card plus a two-step workflow. See Workflows.
Ask the assistant instead
Through AI integrations, the assistant can create and update both kinds of connection, list deliveries, and change a mapping — say what the sender posts and where you want it to land.