@editframe/create 0.44.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +16 -28
- package/dist/index.js.map +1 -1
- package/dist/skills/editframe-brand-video-generator/README.md +155 -0
- package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
- package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
- package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
- package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
- package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
- package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
- package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
- package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
- package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
- package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
- package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
- package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
- package/dist/skills/editframe-composition/SKILL.md +169 -0
- package/dist/skills/editframe-composition/references/audio.md +483 -0
- package/dist/skills/editframe-composition/references/captions.md +844 -0
- package/dist/skills/editframe-composition/references/composition-model.md +73 -0
- package/dist/skills/editframe-composition/references/configuration.md +403 -0
- package/dist/skills/editframe-composition/references/css-parts.md +105 -0
- package/dist/skills/editframe-composition/references/css-variables.md +640 -0
- package/dist/skills/editframe-composition/references/entry-points.md +810 -0
- package/dist/skills/editframe-composition/references/events.md +499 -0
- package/dist/skills/editframe-composition/references/getting-started.md +259 -0
- package/dist/skills/editframe-composition/references/hooks.md +234 -0
- package/dist/skills/editframe-composition/references/image.md +241 -0
- package/dist/skills/editframe-composition/references/r3f.md +580 -0
- package/dist/skills/editframe-composition/references/render-api.md +484 -0
- package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
- package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
- package/dist/skills/editframe-composition/references/scripting.md +606 -0
- package/dist/skills/editframe-composition/references/sequencing.md +116 -0
- package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
- package/dist/skills/editframe-composition/references/surface.md +329 -0
- package/dist/skills/editframe-composition/references/text.md +627 -0
- package/dist/skills/editframe-composition/references/time-model.md +99 -0
- package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
- package/dist/skills/editframe-composition/references/timegroup.md +457 -0
- package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
- package/dist/skills/editframe-composition/references/transcription.md +47 -0
- package/dist/skills/editframe-composition/references/transitions.md +608 -0
- package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
- package/dist/skills/editframe-composition/references/video.md +506 -0
- package/dist/skills/editframe-composition/references/waveform.md +327 -0
- package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
- package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
- package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
- package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
- package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
- package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
- package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
- package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
- package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
- package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
- package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
- package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
- package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
- package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
- package/dist/skills/editframe-editor-gui/references/play.md +370 -0
- package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
- package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
- package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
- package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
- package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
- package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
- package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
- package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
- package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
- package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
- package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
- package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
- package/dist/skills/editframe-motion-design/SKILL.md +101 -0
- package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
- package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
- package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
- package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
- package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
- package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
- package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
- package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
- package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
- package/dist/skills/editframe-webhooks/SKILL.md +126 -0
- package/dist/skills/editframe-webhooks/references/events.md +382 -0
- package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
- package/dist/skills/editframe-webhooks/references/security.md +418 -0
- package/dist/skills/editframe-webhooks/references/testing.md +409 -0
- package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
- package/dist/templates/html/AGENTS.md +13 -0
- package/dist/templates/react/AGENTS.md +13 -0
- package/dist/utils.js +15 -16
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/tsdown.config.ts +4 -0
- package/dist/detectAgent.js +0 -89
- package/dist/detectAgent.js.map +0 -1
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Testing Webhooks
|
|
3
|
+
description: Test Editframe webhook endpoints locally using ngrok tunnels, webhook.site inspection, and the CLI test command.
|
|
4
|
+
type: how-to
|
|
5
|
+
nav:
|
|
6
|
+
parent: "Testing"
|
|
7
|
+
priority: 4
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Testing Webhooks
|
|
11
|
+
|
|
12
|
+
Test your webhook endpoint before deploying to production using local tunneling, test services, and the Editframe dashboard.
|
|
13
|
+
|
|
14
|
+
## Local Testing with ngrok
|
|
15
|
+
|
|
16
|
+
Test webhooks locally by exposing your development server with ngrok:
|
|
17
|
+
|
|
18
|
+
### 1. Install ngrok
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# macOS (Homebrew)
|
|
22
|
+
brew install ngrok
|
|
23
|
+
|
|
24
|
+
# Or download from https://ngrok.com/download
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Start Your Local Server
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Start your application
|
|
31
|
+
npm run dev
|
|
32
|
+
|
|
33
|
+
# Server running on http://localhost:3000
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Create ngrok Tunnel
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Expose port 3000
|
|
40
|
+
ngrok http 3000
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
ngrok will output:
|
|
44
|
+
```
|
|
45
|
+
Forwarding https://abc123.ngrok.io -> http://localhost:3000
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 4. Configure Webhook URL
|
|
49
|
+
|
|
50
|
+
Update your API key's webhook URL to the ngrok URL:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
https://abc123.ngrok.io/webhooks/editframe
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You can do this via:
|
|
57
|
+
- Editframe dashboard → API Keys → Edit
|
|
58
|
+
- Or programmatically via API
|
|
59
|
+
|
|
60
|
+
### 5. Trigger Test Webhooks
|
|
61
|
+
|
|
62
|
+
Trigger events to test your endpoint:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { Client, createRender } from "@editframe/api";
|
|
66
|
+
|
|
67
|
+
const client = new Client(process.env.EDITFRAME_API_KEY);
|
|
68
|
+
|
|
69
|
+
// Create a render - triggers render.created webhook
|
|
70
|
+
const render = await createRender(client, {
|
|
71
|
+
html: `<ef-timegroup mode="contain" class="w-[1920px] h-[1080px]">
|
|
72
|
+
<ef-text>Test</ef-text>
|
|
73
|
+
</ef-timegroup>`,
|
|
74
|
+
width: 1920,
|
|
75
|
+
height: 1080,
|
|
76
|
+
fps: 30,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Wait for completion - triggers render.completed webhook
|
|
80
|
+
console.log("Check your local server for webhook events");
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 6. Monitor Requests
|
|
84
|
+
|
|
85
|
+
View all webhook requests in the ngrok dashboard:
|
|
86
|
+
```
|
|
87
|
+
http://127.0.0.1:4040
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The dashboard shows:
|
|
91
|
+
- Request headers (including `X-Webhook-Signature`)
|
|
92
|
+
- Request body (webhook event)
|
|
93
|
+
- Response status and body
|
|
94
|
+
- Timing information
|
|
95
|
+
|
|
96
|
+
## Testing with webhook.site
|
|
97
|
+
|
|
98
|
+
Use webhook.site to inspect webhook payloads without writing code:
|
|
99
|
+
|
|
100
|
+
### 1. Get a Test URL
|
|
101
|
+
|
|
102
|
+
Visit [webhook.site](https://webhook.site) to get a unique URL:
|
|
103
|
+
```
|
|
104
|
+
https://webhook.site/abc-123-def
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 2. Configure Webhook
|
|
108
|
+
|
|
109
|
+
Set your API key's webhook URL to the webhook.site URL.
|
|
110
|
+
|
|
111
|
+
### 3. Trigger Events
|
|
112
|
+
|
|
113
|
+
Create renders or upload files to trigger webhooks.
|
|
114
|
+
|
|
115
|
+
### 4. Inspect Payloads
|
|
116
|
+
|
|
117
|
+
View webhook requests in webhook.site's interface:
|
|
118
|
+
- Full request headers
|
|
119
|
+
- JSON payload
|
|
120
|
+
- Signature verification (manual)
|
|
121
|
+
|
|
122
|
+
**Note**: webhook.site doesn't verify signatures. Use this for payload inspection only.
|
|
123
|
+
|
|
124
|
+
## Test Webhook from Dashboard
|
|
125
|
+
|
|
126
|
+
Send test webhooks directly from the Editframe dashboard:
|
|
127
|
+
|
|
128
|
+
### 1. Navigate to API Key
|
|
129
|
+
|
|
130
|
+
Go to your API key detail page:
|
|
131
|
+
```
|
|
132
|
+
https://editframe.com/resource/api_keys/<key-id>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 2. Send Test Webhook
|
|
136
|
+
|
|
137
|
+
1. Click "Test Webhook"
|
|
138
|
+
2. Select a topic (e.g., "render.completed")
|
|
139
|
+
3. Click "Send Test"
|
|
140
|
+
|
|
141
|
+
The dashboard will send a test webhook with sample data:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"topic": "webhook.test",
|
|
146
|
+
"data": {
|
|
147
|
+
"id": "your-api-key-id",
|
|
148
|
+
"org_id": "your-org-id"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 3. Verify Receipt
|
|
154
|
+
|
|
155
|
+
Check your webhook endpoint logs to verify:
|
|
156
|
+
- Request received
|
|
157
|
+
- Signature verified successfully
|
|
158
|
+
- Event processed
|
|
159
|
+
|
|
160
|
+
## Unit Testing
|
|
161
|
+
|
|
162
|
+
Test webhook signature verification in unit tests:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { describe, test, expect } from "vitest";
|
|
166
|
+
import crypto from "node:crypto";
|
|
167
|
+
import { verifyWebhookSignature } from "./webhooks";
|
|
168
|
+
|
|
169
|
+
describe("webhook signature verification", () => {
|
|
170
|
+
const secret = "test-webhook-secret";
|
|
171
|
+
|
|
172
|
+
test("verifies valid signature", () => {
|
|
173
|
+
const payload = JSON.stringify({
|
|
174
|
+
topic: "render.completed",
|
|
175
|
+
data: { id: "test-id" }
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const signature = crypto
|
|
179
|
+
.createHmac("sha256", secret)
|
|
180
|
+
.update(payload)
|
|
181
|
+
.digest("hex");
|
|
182
|
+
|
|
183
|
+
expect(verifyWebhookSignature(payload, signature, secret)).toBe(true);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("rejects invalid signature", () => {
|
|
187
|
+
const payload = JSON.stringify({
|
|
188
|
+
topic: "render.completed",
|
|
189
|
+
data: { id: "test-id" }
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const signature = "invalid-signature";
|
|
193
|
+
|
|
194
|
+
expect(verifyWebhookSignature(payload, signature, secret)).toBe(false);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("rejects tampered payload", () => {
|
|
198
|
+
const payload = JSON.stringify({
|
|
199
|
+
topic: "render.completed",
|
|
200
|
+
data: { id: "test-id" }
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const signature = crypto
|
|
204
|
+
.createHmac("sha256", secret)
|
|
205
|
+
.update(payload)
|
|
206
|
+
.digest("hex");
|
|
207
|
+
|
|
208
|
+
// Tamper with payload
|
|
209
|
+
const tamperedPayload = payload.replace("test-id", "hacked-id");
|
|
210
|
+
|
|
211
|
+
expect(verifyWebhookSignature(tamperedPayload, signature, secret)).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Integration Testing
|
|
217
|
+
|
|
218
|
+
Test webhook handling end-to-end:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { describe, test, expect } from "vitest";
|
|
222
|
+
import request from "supertest";
|
|
223
|
+
import crypto from "node:crypto";
|
|
224
|
+
import { app } from "./app"; // Your Express app
|
|
225
|
+
|
|
226
|
+
describe("webhook endpoint", () => {
|
|
227
|
+
const secret = process.env.EDITFRAME_WEBHOOK_SECRET!;
|
|
228
|
+
|
|
229
|
+
function signPayload(payload: object): string {
|
|
230
|
+
const body = JSON.stringify(payload);
|
|
231
|
+
return crypto
|
|
232
|
+
.createHmac("sha256", secret)
|
|
233
|
+
.update(body)
|
|
234
|
+
.digest("hex");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
test("accepts valid webhook", async () => {
|
|
238
|
+
const payload = {
|
|
239
|
+
topic: "render.completed",
|
|
240
|
+
data: {
|
|
241
|
+
id: "test-render-id",
|
|
242
|
+
status: "complete",
|
|
243
|
+
download_url: "https://example.com/video.mp4"
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const signature = signPayload(payload);
|
|
248
|
+
|
|
249
|
+
const response = await request(app)
|
|
250
|
+
.post("/webhooks/editframe")
|
|
251
|
+
.set("X-Webhook-Signature", signature)
|
|
252
|
+
.send(payload);
|
|
253
|
+
|
|
254
|
+
expect(response.status).toBe(200);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test("rejects invalid signature", async () => {
|
|
258
|
+
const payload = {
|
|
259
|
+
topic: "render.completed",
|
|
260
|
+
data: { id: "test-id" }
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const response = await request(app)
|
|
264
|
+
.post("/webhooks/editframe")
|
|
265
|
+
.set("X-Webhook-Signature", "invalid")
|
|
266
|
+
.send(payload);
|
|
267
|
+
|
|
268
|
+
expect(response.status).toBe(401);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test("rejects missing signature", async () => {
|
|
272
|
+
const payload = {
|
|
273
|
+
topic: "render.completed",
|
|
274
|
+
data: { id: "test-id" }
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const response = await request(app)
|
|
278
|
+
.post("/webhooks/editframe")
|
|
279
|
+
.send(payload);
|
|
280
|
+
|
|
281
|
+
expect(response.status).toBe(401);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Manual Testing Script
|
|
287
|
+
|
|
288
|
+
Create a script to send test webhooks:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
// scripts/send-test-webhook.ts
|
|
292
|
+
import crypto from "node:crypto";
|
|
293
|
+
|
|
294
|
+
const WEBHOOK_URL = "http://localhost:3000/webhooks/editframe";
|
|
295
|
+
const WEBHOOK_SECRET = process.env.EDITFRAME_WEBHOOK_SECRET!;
|
|
296
|
+
|
|
297
|
+
async function sendTestWebhook(topic: string, data: object) {
|
|
298
|
+
const payload = JSON.stringify({ topic, data });
|
|
299
|
+
|
|
300
|
+
const signature = crypto
|
|
301
|
+
.createHmac("sha256", WEBHOOK_SECRET)
|
|
302
|
+
.update(payload)
|
|
303
|
+
.digest("hex");
|
|
304
|
+
|
|
305
|
+
console.log(`Sending ${topic} webhook...`);
|
|
306
|
+
|
|
307
|
+
const response = await fetch(WEBHOOK_URL, {
|
|
308
|
+
method: "POST",
|
|
309
|
+
headers: {
|
|
310
|
+
"Content-Type": "application/json",
|
|
311
|
+
"X-Webhook-Signature": signature,
|
|
312
|
+
},
|
|
313
|
+
body: payload,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
console.log(`Response: ${response.status} ${response.statusText}`);
|
|
317
|
+
console.log(await response.text());
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Test render.completed
|
|
321
|
+
await sendTestWebhook("render.completed", {
|
|
322
|
+
id: "test-render-id",
|
|
323
|
+
status: "complete",
|
|
324
|
+
created_at: new Date().toISOString(),
|
|
325
|
+
completed_at: new Date().toISOString(),
|
|
326
|
+
failed_at: null,
|
|
327
|
+
width: 1920,
|
|
328
|
+
height: 1080,
|
|
329
|
+
fps: 30,
|
|
330
|
+
byte_size: 15728640,
|
|
331
|
+
duration_ms: 5000,
|
|
332
|
+
md5: "098f6bcd4621d373cade4e832627b4f6",
|
|
333
|
+
metadata: null,
|
|
334
|
+
download_url: "https://example.com/video.mp4"
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Run the script:
|
|
339
|
+
```bash
|
|
340
|
+
npx tsx scripts/send-test-webhook.ts
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Monitoring Webhook Logs
|
|
344
|
+
|
|
345
|
+
Check webhook delivery logs in the Editframe dashboard:
|
|
346
|
+
|
|
347
|
+
1. Go to your API key detail page
|
|
348
|
+
2. View "Webhook Deliveries" section
|
|
349
|
+
3. See:
|
|
350
|
+
- Delivery timestamp
|
|
351
|
+
- HTTP status code
|
|
352
|
+
- Response headers/body
|
|
353
|
+
- Retry attempts
|
|
354
|
+
- Success/failure status
|
|
355
|
+
|
|
356
|
+
Use these logs to debug webhook issues.
|
|
357
|
+
|
|
358
|
+
## Testing Checklist
|
|
359
|
+
|
|
360
|
+
Before deploying to production:
|
|
361
|
+
|
|
362
|
+
- [ ] Signature verification works correctly
|
|
363
|
+
- [ ] Endpoint responds with 200 OK within 30 seconds
|
|
364
|
+
- [ ] Invalid signatures are rejected with 401
|
|
365
|
+
- [ ] Events are processed idempotently
|
|
366
|
+
- [ ] Errors don't crash the server
|
|
367
|
+
- [ ] Events are logged for debugging
|
|
368
|
+
- [ ] Retry logic handles transient failures
|
|
369
|
+
- [ ] ngrok tunnel tested successfully
|
|
370
|
+
- [ ] Test webhook from dashboard works
|
|
371
|
+
- [ ] Integration tests pass
|
|
372
|
+
|
|
373
|
+
## Common Testing Issues
|
|
374
|
+
|
|
375
|
+
### ngrok URL Not Accessible
|
|
376
|
+
|
|
377
|
+
**Problem**: Webhooks aren't reaching your local server
|
|
378
|
+
|
|
379
|
+
**Solution**:
|
|
380
|
+
1. Check ngrok is running: `http://127.0.0.1:4040`
|
|
381
|
+
2. Verify ngrok URL in API key configuration
|
|
382
|
+
3. Check local server is running on correct port
|
|
383
|
+
4. Check firewall settings
|
|
384
|
+
|
|
385
|
+
### Signature Verification Fails
|
|
386
|
+
|
|
387
|
+
**Problem**: All webhooks rejected with 401
|
|
388
|
+
|
|
389
|
+
**Solution**:
|
|
390
|
+
1. Verify you're using the correct webhook secret
|
|
391
|
+
2. Hash the raw request body, not parsed JSON
|
|
392
|
+
3. Check secret isn't corrupted (no extra spaces/newlines)
|
|
393
|
+
4. Test with the manual testing script
|
|
394
|
+
|
|
395
|
+
### Webhooks Not Received
|
|
396
|
+
|
|
397
|
+
**Problem**: Events triggered but no webhooks received
|
|
398
|
+
|
|
399
|
+
**Solution**:
|
|
400
|
+
1. Check webhook URL is correct
|
|
401
|
+
2. Verify webhook events are selected in API key config
|
|
402
|
+
3. Check webhook delivery logs for errors
|
|
403
|
+
4. Test with webhook.site to isolate issues
|
|
404
|
+
|
|
405
|
+
## Next Steps
|
|
406
|
+
|
|
407
|
+
- [troubleshooting.md](references/troubleshooting.md) — Debug webhook issues
|
|
408
|
+
- [security.md](references/security.md) — Verify signatures correctly
|
|
409
|
+
- [events.md](references/events.md) — Understand webhook payloads
|