Groundbase

A workflow is a small rule: when this happens, do these things. A deal moves to Closed Won, so create a follow-up task. A contact gets the tag hot, so text them. A form on your website posts a lead, so add them and open a deal. Each workflow reacts to one trigger and runs its steps once, top to bottom, for the record the trigger was about.

Find them in the sidebar under Automations → Workflows.

The three parts of a workflow

Every workflow has the same shape. The editor shows them as three blocks.

  1. WHEN — the trigger. What has to happen for the workflow to start.
  2. ONLY IF — an optional condition. If it is false for this run, the workflow is skipped and nothing happens.
  3. THEN — the steps, in order. Each step either does something (send a text, apply a tag, create a task) or controls the flow (wait, branch).

Save switches the workflow on. From that moment every matching event starts a run.

The record a run is about

Almost everything in a workflow refers back to the record the trigger fired on. When a contact is created, the record is that contact. When a deal is won, it is that deal. When a tag is applied, it is whatever got tagged. The engine loads that record at the start of the run and makes it available as entity in conditions and templates, and steps that need a record (apply tag, create note, text this person) use it automatically.

Two kinds of run start without a record: scheduled runs and Run now on a workflow that has no contact picked. In those runs a step that needs a record is skipped with a note in the history, not failed. If you want a scheduled workflow to text or email someone, put a literal number or address in the step's To field.

Triggers

When something happens — an event inside Groundbase. Pick one from the list.

EventFires whenRecordExtra values on trigger.payload
contact.createdA contact is added by any route: the app, import, a form, the APIthe contactfirst_name, last_name, email, phone
contact.updatedA contact is editedthe contactchanged_fields (list of column names), source
contact.deletedA contact is deletednonecontact_id
company.created / company.updated / company.deletedSame for companiesthe companyname, industry, website; changed_fields on update
deal.createdA deal is openedthe dealtitle, value_cents, stage_id, contact_id, company_id
deal.updatedA deal is editedthe dealchanged_fields
deal.stage_changedA deal moves between stagesthe dealfrom_stage_id, to_stage_id, to_stage_name, is_won, is_lost, title, contact_id
deal.won / deal.lostA deal moves into a stage marked Won or Lostthe dealsame as stage changed
deal.deletedA deal is deletednonedeal_id
task.created / task.updated / task.completed / task.deletedTasks, events and meetingsthe tasktitle, kind, due_at, contact_id, deal_id
note.createdA note is added to a contact, company or dealthe notebody, entity_type, entity_id, source
tag.applied / tag.removedA tag is added to or removed from a contact, company or dealthe tagged recordtag_name, tag_id, entity_type, entity_id
sms.sentYou send a text (by hand, by a workflow, by a campaign)the contactbody, to_number, from_number, segments, message_id
sms.receivedA text arrives on one of your numbersthe contact, when the number matched onebody, from_number, to_number, keyword, is_opt_out
sms.delivered / sms.failedTwilio reports the outcome of a textthe contactto_number, twilio_sid; error_message on failure
email.sentYou send an email from a connected inboxthe contactto, cc, bcc, subject, from
call.completedA call endsthe contact, when the call matched onedirection, status, duration_seconds, from_number, to_number, twilio_call_sid
voicemail.receivedA voicemail landsthe contact, when the caller matched onefrom_number, to_number, duration_seconds, recording_url
invoice.issued / invoice.voidedAn invoice is issued or voidedthe invoice's contactnumber, total, currency, contact_id, company_id
invoice.paidAn invoice's balance reaches zero. A deposit is payment.recorded, not thisthe invoice's contacttotal
payment.recordedAny payment is recorded against an invoicenoneamount, balance, method

On a schedule — once at a date and time, or every hour, day or week, in the timezone you pick. The editor shows the next four run times as you edit. There is no record in a scheduled run.

Inbound webhook arrives — an outside system (a form builder, Zapier, your own site) posts to one of your inbound webhooks from Settings → Connections. The record is the contact the webhook created or matched, and the whole posted body is on trigger.payload, so {{trigger.payload.data.first_name}} reads a field from the post.

I run it manually — nothing starts it but the Run now button.

Conditions

A condition is one or more comparisons. Choose all of these (every line must be true) or any of these (one is enough). Each line is a field, a comparison, and usually a value.

Fields you can compare

WriteMeaning
entity.<column>A column on the record the run is about. See the column legend below.
entity.tagsThe record's tags. Use with includes tag.
contact.<column>The contact the run is about. On a deal, task or note that is its contact; on a contact it is the record itself. contact.tags and contact.cf.<key> work too.
cf.<field_key>One of your custom fields, by its key (Settings → Custom fields).
trigger.payload.<key>A value the event carried, from the table above. On tag.applied that is trigger.payload.tag_name.
trigger.eventThe event name, for example deal.won.
trigger.entity_type / trigger.entity_idWhat kind of record the run is about, and its id.
steps.<step id>.output.<key>Something an earlier step in the same run produced. See step outputs below.
A bare column name such as sourceShort for entity.source.

Write trigger.payload.tag_name, not payload.tag_name. The editor refuses the short form because the engine would read it as empty every time and the workflow would silently never run.

Comparisons

ComparisonReads asNeeds a value
equals / not equalsexact match, ignoring caseyes
contains / not containsthe value appears anywhere in the fieldyes
starts with / ends withignoring caseyes
is setthe field has any valueno
is empty / is not emptythe field is blank, or is notno
includes tagthe record carries this tag (use with entity.tags)yes, a tag name
greater than / greater or equal / less than / less or equalas numbers when both sides are numbers, otherwise as text, which sorts dates correctlyyes
older than (days) / newer than (days)the field is a date more (or less) than this many days agoyes, a number of days

Examples: entity.source equals website. entity.phone is set, so a text step cannot fail. entity.tags includes tag VIP. entity.value_cents greater than 500000 for deals over $5,000. entity.last_contacted_at older than (days) 30.

Steps

Each step has a type, its own settings, and an On error choice: Stop workflow (the run fails at this step) or Continue to next step.

StepWhat it doesSettingsNeeds a record
Send SMSTexts through your Twilio number. Honours STOP opt-outs.Message body (required). To optional: blank texts the run's contact (on a deal, task or note, its contact), or type a number or {{contact.phone}}.A contact, unless To is filled in
Send emailEmails from your connected inbox.To optional: blank emails the run's contact, or an address or {{contact.email}}. Subject and Body required.A contact, unless To is filled in
Apply tag / Remove tagAdds or removes a tag on the record. The tag is created if it does not exist.Tag name (required). Optional entity type and id to target a different record.Yes
Create taskAdds a task, linked to the record: a contact links itself, a deal links the deal and its contact and company.Title (required), Description, Due in days (0 to 3650, lands at 9 am your time) or Due at (a date), Kind (task, event, meeting), Location.No, but unlinked without one
Create noteDrops a note on a contact, company or deal.Body (required).Yes
Update fieldChanges one native column on the record.Field and Value. Only these columns: first_name, last_name, email, phone, position, city, source, notes, primary_phone, company_id.Yes
Set custom fieldWrites one of your custom fields.Field key and Value.Yes
Fire webhookPOSTs to an outside URL: Slack, Zapier, your own service.URL (required), Method (GET, POST, PUT, PATCH, DELETE), Headers, Body. Private addresses and Groundbase's own hosts are refused.No
Add to campaignPuts the run's contact into an ongoing campaign, at its first step, under the campaign's own rules — skipped if they have unsubscribed or opted out, never added twice. The step fails if the campaign is one-time or not currently sending.Campaign (an ongoing one).A contact
WaitPauses the run. Up to 60 seconds happens inline; anything longer parks the run and it resumes within about a minute of the deadline, up to 30 days. A long wait can also end the run early: tick Replied, Booked a meeting or Opted out, and when the wait is over the run stops instead of continuing if the contact has done that since the run started. A stopped run shows as skipped with the reason.Amount and unit, plus the stop conditions. A wait inside a branch is capped at 60 seconds; put long waits at the top level.No
BranchIf this, then these steps, else those.A condition (same rules as above), a then list and an else list.No

A workflow may have up to 50 steps and branches three deep.

Templates: putting values into text

Any text field in a step can contain {{...}} placeholders. They are filled in when the step runs. Unknown placeholders come out empty rather than stopping the run.

PlaceholderGives you
{{first_name}}, {{last_name}}, {{full_name}}, {{email}}, {{phone}}Those columns on the record. In a text or email body, {{company_name}}, {{city}}, {{deal_value}} and {{my_name}} work too, the same as anywhere else in Groundbase.
{{entity.<column>}}Any column on the record. {{entity.title}} on a deal, {{entity.position}} on a contact.
{{cf.<field_key>}}A custom field.
{{trigger.event}}The event name.
{{trigger.payload.<key>}}A value the event carried. {{trigger.payload.to_stage_name}} on a stage change; {{trigger.payload.data.email}} from an inbound webhook post.
{{steps.<step id>.output.<key>}}Something an earlier step produced. Give the step an id in the editor so the reference survives edits.

Press Variable beside any field to insert one from a list instead of typing it.

Column legend: what entity. can reach

RecordColumns
Contactfirst_name, last_name, full_name, email, phone, phone_secondary, primary_phone, company_id, position, city, source, notes, last_contacted_at, created_at, updated_at, plus tags
Companyname, industry, website, city, state, country, notes, created_at, updated_at, plus tags
Dealtitle, value_cents (whole cents: $1,500 is 150000), stage_id, contact_id, company_id, close_date, notes, created_at, updated_at, plus tags
Tasktitle, description, due_at, end_at, kind, location, priority, contact_id, company_id, deal_id, completed_at, created_at, updated_at

Step outputs: what steps.<id>.output. can reach

StepOutput keys
Send SMSmessage_id, segments, status, to, contact_id
Send emailmessage_id, rfc_message_id, to, subject, contact_id
Apply tag / Remove tagtag_name, entity_type, entity_id
Create tasktask_id, title, due_at, contact_id
Create notenote_id, entity_type, entity_id, body
Update field / Set custom fieldentity_type, entity_id, field or field_key, value
Fire webhookurl, method, status_code, response_body
Add to campaigncampaign_id, contact_id, queued, already, skipped
Branchpassed (true or false), ran
Waitdelay_seconds, resumed_from (inline or cron)

Running one by hand

Run now on a workflow's row starts it immediately. For workflows that react to a record event it asks you to pick a contact first, and that contact becomes the record. Two things to know:

Reading the run history

Open a row's chevron to see its runs, newest first. Each run has a status and one line per step.

Run statusMeaning
CompletedEvery step ran or was skipped by design.
SkippedThe ONLY IF condition was false for this record. Nothing ran.
FailedA step errored with On error set to Stop. The line says which step and why.
WaitingThe run is parked on a Wait step. The row shows N waiting.

Step lines read ok with what happened ("created task … linked to deal", "applied hot to contact Jane Doe"), skipped with the reason, or failed with the error.

Pausing, editing and deleting

Ask the assistant instead

If you use Groundbase with Claude or ChatGPT through AI integrations, you can say what you want in a sentence ("when a deal is won, create a task to send the welcome kit") and the assistant will build it. It can also read the run history and tell you why a workflow skipped or failed.