Key Takeaways
- GoHighLevel + an Android SMS gateway webhook is CRM glue: GHL fires an outbound webhook, your worker POSTs /messages, our DLR HMAC comes back. We do not ship a GHL plugin.
- GHL’s docs own their webhook UI. Ours own Bearer JSON and X-SmsGateway-Signature.
- HTTP 2xx on send is accepted, not delivered. Update pipeline stages on DLR if “texted” must mean arrived.
- Keys per location. OTP deviceIds ≠ blast workflow.
- Service pricing is based on device count and total SMS sent through the gateway. You need a working Android phone with a SIM and SMS credit from your mobile operator. Operator message costs are yours—we do not sell carrier SMS balance.
GoHighLevel SMS Android gateway webhooks are two HTTPS paths, not a native CRM SMS product. A pipeline stage can POST to your worker; that worker calls our send API. Delivery events come back with HMAC. Do not paste our OpenAPI into a GHL “custom JS” box and call it an app we ship.
Service pricing is based on device count and total SMS sent through the gateway. Overview: GHL + Android gateway. Our webhooks: webhook feature / overview. GHL’s UI: GoHighLevel help. Contract: API docs.
If “Won” in GHL fires SMS and never waits for delivered, you told sales the customer was texted when the Pixel was asleep.
Glue, not a GHL marketplace app
Least-privilege keys per sub-account. You need a working Android phone with a SIM and SMS credit from your mobile operator. Operator message costs are yours—we do not sell carrier SMS balance.
Two webhook directions
| Direction | Job | Auth |
|---|---|---|
| GHL → you | Stage/opportunity payload | GHL’s secret / signature (their docs) |
| You → SMS Gateway | POST /messages | Bearer + Idempotency-Key |
| SMS Gateway → you | delivered / failed / received | X-SmsGateway-Signature |
| You → GHL | Custom field / note / stage | GHL API (their docs) |
GHL → your worker → SMS
curl -X POST "https://app.sms-gateway.app/api/v1/messages" \
-H "Authorization: Bearer $SMS_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1b0c8a-9d2e-4c77-9f5a-2b6d1e0f4a83" \
-d '{"to":["+14155552671"],"text":"Your verification code is 481920","type":"sms"}'Map GHL contact phone to E.164 in the worker. Do not send from a GHL browser snippet with the key in it.
Our DLR → GHL
{
"id": "evt_01K2F8QW3N4RXB7M",
"type": "message.delivered",
"createdAt": "2026-08-12T14:04:09Z",
"apiVersion": "2026-08-12",
"data": {
"message": {
"id": 41823,
"number": "+14155552671",
"text": "Your verification code is 481920",
"status": "Delivered",
"campaignId": 17,
"deviceId": 3,
"metadata": { "orderId": "1234" },
"sentAt": "2026-08-12T14:04:02Z",
"deliveredAt": "2026-08-12T14:04:09Z"
}
}
}Verify HMAC, dedupe event id, then PATCH the opportunity. Live event names: OpenAPI.
Do not hang login on a nurture workflow
Isolate deviceIds. OTP. Pipeline alerts.
Checklist
- No plugin SKU in the README.
- GHL signature verified; our HMAC verified.
- Keys per location.
- OTP workflow ≠ blast workflow.
- Stage updates wait on DLR when it matters.
Next steps
Fire a test stage to a staff handset, then forge a bad signature and prove both sides reject. Pair the app.
Related product pages
Jump to the live product docs for this topic—not another long-form article.
- SMS webhook integrationInbound and status events
- device and SMS volume pricingPlans and allowances
- Android SMS gateway product guideDefinition, product, and how to buy
- SMS API documentationLive endpoint reference





