What You Get
- Contact sync — Import GHL contacts into Tuco with deduplication
- Owner mapping — Map GHL users to Tuco team members
- Tag sync — GHL contact tags imported automatically
- Custom field sync — Map GHL custom fields to Tuco custom fields or tags
- Campaign conditions — Use GHL tags in campaign branching and stop conditions
Connecting GoHighLevel
- Go to Integrations → CRM
- Enter your GHL API key and Location ID
- Click Test & Connect
- A full sync starts automatically
Only one CRM can be connected at a time. Disconnect HubSpot before connecting GHL.
Required API scopes
- Location access
- Contacts: search and read
- Tags: read location tags
Recommended scopes
- Users: read (for owner mapping)
- Custom fields: read (for field mapping)
- Contact tags: add/remove (for campaign automation)
- Conversations: create (for activity logging)
Contact Sync
How it works
- First sync — imports all GHL contacts into a “GHL Import” list
- Incremental sync — every 15 minutes, syncs recently modified contacts
- Deduplication — matched by phone number
- Tags — GHL contact tags are imported into Tuco’s tag system
What syncs
Owner Mapping
Same as HubSpot — map GHL users to Tuco members.- Integrations → CRM → Owner Mapping
- Map each GHL user to a Tuco member
- Save & Re-sync
Custom Field Mapping
Map GHL custom fields to Tuco tags or custom fields.- Integrations → CRM → Property Mapping
- Select a GHL custom field
- Choose Tag or Custom Field target
- Save & Re-sync
Channel control with tags
Use a GHL contact tag to control which channel a lead’s outbound messages go out on. Tags are read live on every send (workflow action and conversation-provider / CloseBot), so they take effect immediately — no sync, no custom field, no reinstall.
The tag name is matched loosely (case-insensitive, ignoring spaces/dashes/underscores), so
forcefallback, force-fallback, force_fallback, and Force Fallback all work.
forcefallback only changes the channel, not delivery. The lead must have a fallback
configured (Settings → When iMessage isn’t available). With no fallback set up the
send returns an error instead of silently delivering over iMessage. Add or remove the tag
any time to flip a lead between iMessage-first and SMS-only.Send iMessages from a GHL workflow
The simplest way to trigger a Tuco iMessage from a GHL workflow is a plain Webhook action pointed at the Send Message API — no Marketplace app or action secret, just your Tuco API key. GHL’s Webhook action already attaches the full contact payload, so the only thing you map is the message.- In your workflow, add a Webhook action — Method
POST, URLhttps://app.tuco.ai/api/messages. - Add a header:
Authorization=Bearer tuco_sk_xxxxxxxxxxxxx(your API key). - Under Custom Data, set
message(required). Optionally addlineId(pin a sending line) andattachmentUrls.
phone → recipient, contact_id → GHL contact, location.id → GHL
location, full_name → name, user.email → owner). You don’t map any of those.
Full field-by-field mapping and a copy-paste example are on the
Send Message → “Send straight from a GoHighLevel webhook”
reference. If the contact has no phone or email the send fails with
missing_recipient.Send a voice note from GHL
The Marketplace Send via Tuco (Send iMessage) action can deliver a native iMessage voice note — the recognizable play-button bubble, not a file link. You supply a clean audio URL and flip one toggle; Tuco transcodes the audio to the voice-note format for you.Get an audio URL
You need a publichttps://… link to an audio file (mp3, m4a, wav, aac, ogg,
or caf), ≤ 25 MB and ≤ 5 minutes. The easiest way to get one:
- In the dashboard, open /uploads (or the Upload audio etc tab on the Leads page), drag in your clip, and hit Copy to copy the link.
- Or upload it programmatically with
POST /api/attachments/upload.
Configure the action fields
In your GHL workflow, add the Send via Tuco action and set these fields:_attachment_only_ needs a real attachmentUrl to go with it. If you set the magic
word but leave the URL empty, the action returns
Used _attachment_only_ but no Attachment URL was provided. To send audio with a
caption, put your caption in message instead of the magic word.Check for Replies (Marketplace workflow action)
The Check for Replies action tells your workflow whether a contact has replied on iMessage since your last outbound message — and hands the recent conversation to later steps, so If/Else branches, AI steps, and webhooks can act on what was actually said. The action takes an optionalphone field; leave it blank to use the contact’s phone
automatically.
Response
Each
pastConversation item:
hasReplied and hasEverReplied answer different questions. hasReplied means
“replied since your last outbound” — after you (or Tuco’s AI copilot) send a
follow-up, it flips back to false. hasEverReplied never flips back: once the
contact has replied, it stays true. If your workspace has an auto-responder,
branch on hasEverReplied — the auto-reply usually lands within seconds, so
hasReplied will already be false by the time your workflow checks. Use
hasReplied only for strict wait-for-reply flows, and lastReply /
pastConversation for AI context.
If a line was later deleted, from/to may be empty for its messages — fromLineId
still identifies the line.Using GHL Data in Campaigns
Stop conditions
- GHL tag — stop if contact has/doesn’t have a tag (live API call)
Branching
- GHL has tag — branch based on GHL tags (live API call)
- GHL property — branch on custom field values