Overview
Cart Recovery emails guests who started a booking on your site but didn't finish it. CraftedStays watches booking activity, and when a guest leaves without completing checkout, we tell your GoHighLevel account to send them a recovery email with their dates, the property, and a one-tap link back to finish booking. If they complete their booking first, no email is sent.
You stay in control of the email itself: it sends from your GoHighLevel account, uses your sending domain, and follows GoHighLevel's unsubscribe rules. We give you a ready-made email design to start from (Step 5).
Before You Start
You'll need:
A GoHighLevel account with Automations (Workflows) available. Some agency-provisioned accounts have Automations turned off. If you don't see Automation in your GoHighLevel menu, ask your agency to enable it for your sub-account.
Cart Recovery enabled on your CraftedStays account. If you don't see Guest Marketing under your site settings, contact support to join the program.
About 20 minutes for the one-time setup.
Step-by-Step Process
Step 1: Create a Private Integration in GoHighLevel
In GoHighLevel, go to Settings → Private Integrations. If you don't see it in the Settings menu, open it directly at
app.gohighlevel.com/v2/location/YOUR_LOCATION_ID/settings/private-integrationsClick Create new integration and give it a name like "CraftedStays"
Select these scopes: View Contacts, Edit Contacts, View Custom Fields, Edit Custom Fields, View Tags, Edit Tags, and View Forms. Press Esc to close the scope dropdown, since an open dropdown blocks the Create button.
Click Create and copy the token it shows you (it starts with
pit-). GoHighLevel only shows it once.Copy your Location ID from Settings → Business Profile. It's also in your browser's address bar, right after
/location/
Step 2: Connect GoHighLevel to CraftedStays
In your CraftedStays dashboard, go to Site → Email Marketing
On the GoHighLevel card, click Connect
Paste your Private Integration Token and Location ID, then click Connect
Step 3: Turn On Email Capture
Cart Recovery can only email guests whose email address you have. The Lead Popup collects it.
Go to Site → Guest Marketing
On the Lead popup card, turn the popup on and adjust the copy to match your brand
We recommend turning on phone number collection. Many GoHighLevel accounts run cleanup automations that suppress contacts without a phone number, which can stop your recovery emails from sending.
Optionally, change Tag to apply (it defaults to
newsletter). Every signup is also taggedcs-newsletter-signup, which you can use to trigger a welcome workflow.Click Save popup
Step 4: Turn On Cart Recovery
On the same page, the Cart Recovery card shows a readiness checklist. All rows should be green.
Choose how long to wait before a booking counts as abandoned (1 hour is a good default)
Turn the switch on
Step 5: Create the Recovery Email Template
Start with our ready-made design. It shows the property photo, the guest's dates, guest count, and total, plus a button back to their booking. Everything fills in automatically for each guest.
In GoHighLevel, go to Marketing → Emails → Templates
Click New, choose Blank Template, then open the Code Editor
Delete anything already in the editor, copy the HTML below, and paste it in
Name the template something like "Abandoned Booking Recovery" and click Save template
<!DOCTYPE html>
<html>
<body style="margin:0;padding:0;background-color:#f4f2ee;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f4f2ee;padding:24px 0;">
<tr><td align="center">
<table role="presentation" width="600" cellpadding="0" cellspacing="0" style="max-width:600px;width:100%;background-color:#ffffff;border-radius:12px;overflow:hidden;font-family:Georgia,'Times New Roman',serif;color:#232323;">
<tr><td>
<img src="{{contact.cs_property_image}}" alt="{{contact.cs_property}}" width="600" style="width:100%;height:280px;object-fit:cover;display:block;">
</td></tr>
<tr><td style="padding:32px 40px 8px 40px;">
<p style="margin:0 0 4px;font-family:Arial,Helvetica,sans-serif;font-size:12px;letter-spacing:1px;text-transform:uppercase;color:#8a8378;">{{contact.cs_site_name}}</p>
<h1 style="margin:0 0 12px;font-size:26px;line-height:1.25;font-weight:normal;">Still thinking about {{contact.cs_property}}?</h1>
<p style="margin:0 0 20px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:1.6;color:#4a463f;">Hi there, you were one step away from booking. We saved your trip details, so if you're still planning to go, you can pick up right where you left off.</p>
</td></tr>
<tr><td style="padding:0 40px;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#faf8f4;border:1px solid #e8e3da;border-radius:8px;">
<tr>
<td style="padding:16px 20px;font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#8a8378;">Check-in<br><span style="font-size:15px;color:#232323;font-weight:bold;">{{contact.cs_checkin}}</span></td>
<td style="padding:16px 20px;font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#8a8378;">Check-out<br><span style="font-size:15px;color:#232323;font-weight:bold;">{{contact.cs_checkout}}</span></td>
<td style="padding:16px 20px;font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#8a8378;">Guests<br><span style="font-size:15px;color:#232323;font-weight:bold;">{{contact.cs_guests}}</span></td>
<td style="padding:16px 20px;font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#8a8378;">Total<br><span style="font-size:15px;color:#232323;font-weight:bold;">${{contact.cs_cart_value}}</span></td>
</tr>
</table>
</td></tr>
<tr><td align="center" style="padding:28px 40px 8px 40px;">
<a href="{{contact.cs_recovery_url}}" style="display:inline-block;background-color:#232323;color:#ffffff;font-family:Arial,Helvetica,sans-serif;font-size:15px;font-weight:bold;text-decoration:none;padding:14px 40px;border-radius:8px;">Finish your booking</a>
</td></tr>
<tr><td align="center" style="padding:4px 40px 32px 40px;">
<p style="margin:0;font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#8a8378;">Dates aren't held until you book, so finish soon to keep them.</p>
</td></tr>
<tr><td style="padding:20px 40px;border-top:1px solid #eee9e0;">
<p style="margin:0;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:1.6;color:#a39b8d;">{{contact.cs_site_name}} · Book direct with the people who care for the home.<br>{{email.unsubscribe_link}}</p>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>Making it yours: change the wording, the colors (the #232323 button and the #f4f2ee background), or the footer line however you like. Keep the merge fields as they are. Your total shows with a $ in front, so if your site uses another currency, replace that symbol.
The editor preview shows the merge fields as placeholder text and the photo as a broken image. That's expected. They fill in when the email sends to a real guest.
Step 6: Build the Recovery Workflow in GoHighLevel
When a guest abandons a booking, CraftedStays tags their GoHighLevel contact with cs-cart-abandoned and fills in the booking details. Your workflow reacts to that tag.
Go to Automation → Workflows → Create workflow → Start from scratch
Add the trigger Contact Tag, with the filter Tag added includes
cs-cart-abandoned. You can create the tag right in the picker.Add a Wait step of 5 to 10 minutes
Add an If/Else step: continue only if the contact still has the
cs-cart-abandonedtag. If the guest completes their booking, CraftedStays removes that tag and addscs-cart-recovered, so this check stops the email for guests who came back on their own.On the branch where the tag is still there, add a Send Email action. Under Create email, choose Select existing template and pick the template from Step 5. Add a subject line, such as Your trip is still waiting.
Publish the workflow. It only reacts to tags added after you publish.
Merge field reference
The template already uses all of these. If you write your own email instead, pick them from the merge-field picker under Contact custom fields.
What it shows | Merge field |
Your site name |
|
Property name |
|
Property photo (use as an image source) |
|
Check-in date |
|
Check-out date |
|
Guest count |
|
Booking total (a number, no currency symbol) |
|
Link back to finish booking |
|
The recovery link brings the guest back to the property page with their dates and guest count already filled in and the price ready, one tap from checkout.
Step 7: Test It
Open your own site in a private browser window
Sign up through the popup with a test email you can check
Pick dates on a property, enter your email at the booking step, and leave before paying
Within your chosen delay plus about 15 minutes, the contact appears in GoHighLevel tagged
cs-cart-abandoned, and your workflow sends the email
Troubleshooting
I don't see Automation in my GoHighLevel menu.
Your agency has turned it off for your account. Ask them to enable Automations for your sub-account.
The contact gets tagged but no email sends.
Check two things in GoHighLevel. First, open the contact and make sure Do Not Disturb isn't on for email. Second, open the workflow's Execution logs and check whether another automation removed the contact, usually one that cleans up contacts without phone numbers. Turning on phone collection in the CraftedStays popup prevents this.
The booking details or photo are blank in my email.
The custom fields are created automatically the first time a recovery is delivered, so a test send before then shows blanks. Run the test in Step 7, then check again. If you wrote your own email, re-select the merge fields from the picker so they use the exact field keys.
A guest booked and still got the email.
This shouldn't happen, because completed bookings cancel pending recovery emails automatically. If you see it, contact support with the guest's email address.
How do unsubscribes work?
GoHighLevel handles them. If a guest unsubscribed from your emails, GoHighLevel won't send to them, and CraftedStays never changes anyone's unsubscribe or Do Not Disturb settings.










