# Send from GHL workflows

> Trigger Beam texts from a GoHighLevel workflow, test without sending, and avoid duplicate messages.

Keep your triggers, delays and conditions in GoHighLevel. Let Beam send the message from your assigned business line.
AvailabilityThe Custom Webhook integration is the setup described below. A selectable Marketplace action named Send with Beam still requires publisher configuration and GHL publication; do not assume it is available just because Beam appears in your conversation inbox. Test your own contact before enabling any customer workflow.

## Choose the right action

| What you want | Use | 
| Manually reply inside GHL | Select Beam in the conversation inbox. | 
| Send your chosen message from a workflow | Custom Webhook to the workflow endpoint below. | 
| Send Beam's configured first introduction to a new lead | The existing opt-in webhook. It skips already-contacted leads, so it is not a follow-up action. | 
GHL's regular Send SMS action does not select an additional Beam conversation channel. It continues using your default SMS provider. Do not switch that default just to configure this integration.

## Before you start

- Connect the correct GHL location in Beam Settings → CRM inbox messaging.- Have an active assigned Beam line and a test contact in that same GHL location.- In Beam Settings → Developer access, create a workspace-specific token with Send real messages. Also grant Control automation only if you want the workflow to pause the assistant.- Keep the token in the workflow's authorization header. Never include it in screenshots, contact fields, public URLs, or this guide. Tokens expire and can be revoked; update the header when rotating one.- Confirm the contact has consented. Beam also checks GHL DND and local opt-out state.

## Add the workflow step

In GHL → Automation → Workflows, open a draft test workflow. Add Custom Webhook and name the step Send with Beam. GHL may charge separately for premium workflow actions.

| Setting | Value | 
| Method | POST | 
| URL | https://beam.aisync.link/api/crm/workflows/send | 
| Authorization header | Bearer YOUR_BEAM_WORKSPACE_TOKEN | 
| Content-Type header | application/json | 
Use this JSON body. Replace the location ID and sender with your own values; use GHL's contact-value picker for contact ID and first name. The sender must include its country code.

```
{
  "location_id": "YOUR_GHL_LOCATION_ID",
  "contact_id": "{{contact.id}}",
  "workflow_id": "welcome-v1",
  "from": "+15551234567",
  "message": "Hi {{contact.first_name}}, thanks for reaching out. How can we help?",
  "request_key": "{{contact.id}}.welcome-v1.step-1",
  "consent": true,
  "assistant_mode": "preserve",
  "dry_run": true
}
```

Recipient safety: Beam retrieves the phone number from this exact GHL contact in the connected location. You do not paste a separate destination number. A conflicting duplicate-contact mapping stops the send for review.

## First validate, then send one test

- Keep dry_run: true. Run only your own test contact. Expect status: validated and queued: false. No message is sent and the assistant is not paused.- Change dry_run to false and run that test contact. Expect a Beam message ID and status: queued. This is acceptance, not delivery.- Verify one message arrives on your phone from the selected line. Check Beam's status and the same contact's GHL timeline.- Repeat the exact same request with the same send key. It should return the same message ID with duplicate: true, without another text.- Only then add the step to your real workflow. Keep the workflow draft until your test passes. Never bulk-enroll clients as a test.

## How send keys prevent duplicates

The key identifies one intended message, not just one contact. The example sends the welcome step once per contact. A later step needs a different suffix, such as step-2. For recurring reminders, include a stable appointment or business-event ID selected through GHL's value picker, plus the reminder step. Re-enrolling the same event must reuse its key. Do not generate a new timestamp or random key on every retry.
If you reuse a key with different text or settings, Beam returns request_key_conflict instead of guessing. Check the existing message before creating a new send. Keys remain scoped to the workspace and workflow identifier.

## iMessage, text and replies

Beam chooses iMessage when the recipient is eligible and your selected line supports it; otherwise it uses text when that line can reach the recipient. This action does not force iMessage or guarantee RCS. Sender capability and recipient reachability still matter. Sending hours, line pacing, billing readiness and opt-outs still apply.
assistant_mode: preserve leaves your current assistant setting alone. Use pause only when GHL or another agent should own replies; it requires Control automation permission and pauses only this contact. There is no automatic unpause. Stop follow-ups when a contact replies using your tested GHL workflow rules. Do not run two automated responders in the same conversation.
Outbound acceptance does not prove inbound replies are working. Validate inbound and CRM sync separately before relying on reply-triggered workflows.

## If a step fails

| Error | Next action | 
| unauthorized / permission_denied | Check token expiry, workspace and send permission. | 
| crm_contact_not_verified / crm_location_not_connected | Check the location connection and contact ID. | 
| sender_not_available | Choose an active line assigned to this Beam workspace. | 
| contact_opted_out | Stop; do not bypass the opt-out. | 
| duplicate_crm_contact_requires_review | Resolve the duplicate CRM contact identity before retrying. | 
| rate_limited / request_failed | Wait and retry with the same key. Check Beam before assuming no send occurred. | 

## Share and screenshot

Pin this guide for your team. Capture the workflow step with the Authorization value hidden, the successful validation response, and the received test message. Do not include customer conversations or tokens in training screenshots.

## Official GHL references

- Conversation providers and workflow limitations- Creating a native Marketplace workflow action- Marketplace installation and premium-action requirements
