@@ -43,16 +43,18 @@ async def oauth_example():
4343 )
4444 print (f " Visit: { auth_url} " )
4545
46- # Step 2: Exchange code for tokens (after user authorization)
46+ # Step 2: Exchange code for tokens (after user authorization).
47+ # The request body uses camelCase keys.
4748 token_data = await client.oauth.get_access_token({
48- " client_id " : " your_client_id" ,
49- " client_secret " : " your_client_secret" ,
50- " grant_type " : " authorization_code" ,
49+ " clientId " : " your_client_id" ,
50+ " clientSecret " : " your_client_secret" ,
51+ " grantType " : " authorization_code" ,
5152 " code" : " authorization_code_from_callback" ,
52- " redirect_uri" : " https://your-app.com/callback"
5353 })
54-
55- # Tokens are automatically stored in session storage
54+
55+ # token_data is the raw token response, with camelCase keys:
56+ # accessToken, refreshToken, expiresIn, userType, and locationId or companyId.
57+ # Persist it via your session storage to authenticate later requests.
5658 print (" OAuth flow completed successfully!" )
5759
5860asyncio.run(oauth_example())
@@ -115,6 +117,26 @@ async def handle_ghl_webhook():
115117 return jsonify({" status" : " success" }), 200
116118```
117119
120+ ### Webhook Signature Verification
121+
122+ Incoming webhooks are verified before they are processed. Configure the public key
123+ (available in your app settings) as an environment variable. If no supported signature
124+ header and matching key are present, the middleware logs a warning and skips the
125+ webhook ** without processing it** — so configuring a key is required for webhooks to work.
126+
127+ | Scheme | Header | Environment variable | Notes |
128+ | --------| --------| ----------------------| -------|
129+ | Ed25519 | ` x-ghl-signature ` | ` WEBHOOK_SIGNATURE_PUBLIC_KEY ` | Preferred. Used when present. |
130+ | RSA-SHA256 | ` x-wh-signature ` | ` WEBHOOK_PUBLIC_KEY ` | Legacy fallback. |
131+
132+ ``` bash
133+ # CLIENT_ID is also required — the webhook's appId is matched against it before processing.
134+ export CLIENT_ID=" your_client_id"
135+ export WEBHOOK_SIGNATURE_PUBLIC_KEY=" your_ed25519_public_key"
136+ # Optional legacy fallback:
137+ export WEBHOOK_PUBLIC_KEY=" your_rsa_public_key"
138+ ```
139+
118140## Documentation
119141
120142- [ Official API Documentation] ( http://marketplace.gohighlevel.com/docs/ )
0 commit comments