Documentation Index
Fetch the complete documentation index at: https://osforms.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Setup
- Go to Integrations in your osforms dashboard
- Click Connect next to Webhook
- Enter your endpoint URL (must be HTTPS)
- Copy the signing secret and store it securely — it’s shown once
- Click Save
osforms sends a POST request with Content-Type: application/json:
{
"submissionId": "64f1a2b3c4d5e6f7a8b9c0d1",
"formId": "64f1a2b3c4d5e6f7a8b9c0d2",
"formName": "Contact Form",
"submittedAt": "2026-03-27T12:00:00.000Z",
"data": {
"name": "Jane Smith",
"email": "jane@example.com",
"message": "Hello!"
}
}
data keys match the field IDs set in your form schema.
Verifying signatures
Every request includes an X-osforms-Signature-256 header:
X-osforms-Signature-256: sha256=<hex>
The signature is computed as HMAC-SHA256(requestBody, signingSecret) where requestBody is the raw JSON string.
Verify it in your endpoint:
import crypto from 'crypto';
function verifySignature(
rawBody: string,
signature: string,
secret: string
): boolean {
const expected =
'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// Express example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-osforms-signature-256'] as string;
if (!verifySignature(req.body.toString(), sig, process.env.WEBHOOK_SECRET!)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the submission...
res.json({ ok: true });
});
Always verify the signature before processing a webhook. Use timingSafeEqual
to prevent timing attacks.
Retry behavior
Webhooks do not automatically retry on failure. If your endpoint returns a non-2xx status or times out:
- The delivery is marked as failed in the integration log
- You receive an in-app notification and email alert
- You can view the error in Submissions → View Logs
Timeout
Webhook requests time out after 30 seconds. Ensure your endpoint responds within this window.
Testing
Click Send Test in the integration settings to send a sample payload to your endpoint and verify your signature verification logic.