site logo

Marico's space

GoHighLevel API 入门指南:Auth、Webhooks 与常见陷阱

前端技术 2026-10-08 17:33:59 6

最近折腾 GoHighLevel(也叫 HighLevel,母公司卖的叫 LeadConnector)对接,给客户做数据同步。踩了几个坑才摸清楚,这篇把认证、Webhooks 和常见问题说清楚。

先选对认证方式

HighLevel 目前的 API(V2 和新版 v3)支持两种认证。旧版 V1 API 在 2025 年 12 月 31 日已经停止支持,新项目别再碰它。

  • Private Integration Token(PIT,私有集成令牌)。适合自己写的脚本、内部工具,只操作一个代理商或一个子账户。去 Settings > Private Integrations 创建,按需选 scopes,只显示一次记得复制。如果菜单没找到,官方文档说要去 Labs 里开启这个功能。
  • OAuth 2.0。做 Marketplace 应用、供多家代理商或子账户安装的必备方案。用户安装时审批 scopes,然后拿返回的 code 换 token。

套餐等级也要注意。Starter 和 Unlimited 只有基础的位置级访问权限,代理商级 token 和高级 OAuth 功能需要 Agency Pro。设计跨代理商功能(比如创建子账户)之前先确认好套餐。

第一次请求

调用地址是 https://services.leadconnectorhq.com,发 JSON,两个关键 headers: bearer token 和 Version。来个 Contact upsert 示例,参数自己替换:

curl -X POST "https://services.leadconnectorhq.com/contacts/upsert" \ -H "Authorization: Bearer <YOUR_PRIVATE_INTEGRATION_TOKEN>" \ -H "Version: <API_VERSION_FROM_DOCS>" \ -H "Content-Type: application/json" \ -d '{ "locationId": "<YOUR_LOCATION_ID>", "firstName": "Jane", "email": "jane@example.com" }'

Upsert 会根据子账户的重复联系人设置来决定是新建还是更新,按 email 或 phone 匹配。在正式接入线索之前先用那个设置测一遍。

坑 1:Version header 是必填的

HighLevel 的 API 版本控制靠请求里的 Version header 实现。文档里写的是日期格式如 2021-07-28、2023-02-21,还有 2026 年 6 月 11 日发布的命名版本 v3。每个版本有独立的文档页面,很容易在看一个版本的文档但实际调的是另一个版本。在文档切换器里选好一个版本,写进配置文件,每个请求都带上。

坑 2:OAuth token 会过期,而且 refresh token 用一次少一次

Access token 有效期大约 24 小时。Refresh token 有效期是一年或者用到为止,所以每次刷新都会返回新的 refresh token,必须保存。重复使用旧 token,下次刷新就失败了。在服务端刷新,把 refresh token 加密存储,还要防止两个 worker 同时刷新同一个安装实例。

Token 分两个级别:Company(代理商)和 Location(子账户)。代理商 token 可以通过 /oauth/locationToken 接口申请子账户 token,一个应用管多个客户的时候很方便。

PIT 不过期,但 HighLevel 建议每 90 天轮换一次。轮换期间新旧 token 可以同时生效 7 天,实现无缝切换。

坑 3:验证 Webhooks 要用原始请求体

Marketplace 应用可以订阅 Webhook 事件,比如 ContactCreate、AppointmentCreate。HighLevel 用 Ed25519 对每个 payload 签名,放在 X-GHL-Signature header 里。老的 RSA 签名 X-WH-Signature header 原本计划 2026 年 9 月 1 日废弃,只用那个 header 的验证逻辑需要更新了。

经典错误是用解析后的 JSON 来验证。签名是对发送的原始字节做校验,所以要用原始请求体:

import express from "express";
import crypto from "node:crypto"; const app = express();
const GHL_PUBLIC_KEY = process.env.GHL_ED25519_PUBLIC_KEY; // PEM from HighLevel's webhook guide app.post("/webhooks/ghl", express.raw({ type: "application/json" }), (req, res) => { const signature = req.get("x-ghl-signature"); if (!signature) return res.sendStatus(401); const valid = crypto.verify( null, // Ed25519 takes no separate digest req.body, // raw Buffer, not parsed JSON GHL_PUBLIC_KEY, Buffer.from(signature, "base64") ); if (!valid) return res.sendStatus(401); const event = JSON.parse(req.body.toString("utf8")); // hand the event to a queue, then acknowledge quickly res.sendStatus(200);
});

别把这个跟 Workflow Webhooks 搞混了。Inbound Webhook 触发器和 Custom Webhook 动作是 HighLevel 工作流里的功能,按次收费:无代码胶水代码挺好用,但它是另一套系统。

坑 4:限流是按应用、按资源分别计数的

公共 V2 API 用 OAuth 的限流规则:突发限制 100 请求/10 秒,日限额 200,000 请求。两个数字都是按 Marketplace 应用对每个 Location 或 Company 单独计数的,每个安装实例独立配额。响应头里有 X-RateLimit-Remaining 和 X-RateLimit-Daily-Remaining。收到 429 之前就主动降速,尤其是批量导入的时候。

几个小知识点

  • 日历空闲时段接口接收毫秒时间戳作为起止日期,单次调用不能跨超过 31 天。
  • HighLevel 客服不帮忙调试 API 代码,官方文档(marketplace.gohighlevel.com/docs)和开发者社区是你的好朋友。
  • 用测试子账户开发,token 别往前端代码和 Git 里塞,日志里记得脱敏。

总结

选对 token、请求里固定 Version header、每次刷新保存新 refresh token、用原始请求体验证 Webhook、留意限流响应头——做到这几点,上线第一周的 bug 基本能躲过去。关于各套餐的访问权限详情、端点表格、以及 API 与 Zapier、Workflow Webhooks、MCP 的对比,可以看我们更详细的 GoHighLevel API 指南。