API Reference
Webhooks & Integrations
Connect form submissions to external services like Slack, Discord, Google Sheets, and more.
Custom Webhook
Send submission data to any URL. Great for connecting to Zapier, Make, or your own backend.
JSON
{
"event": "submission.created",
"form": {
"id": "abc-123",
"name": "Contact Form"
},
"submission": {
"id": "xyz-789",
"data": {
"name": "John Doe",
"email": "john@example.com",
"message": "Hello!"
},
"createdAt": "2024-01-15T10:30:00.000Z"
},
"meta": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"referer": "https://yoursite.com"
}
}🔐
Webhook Secret
If you set a secret, we'll include a X-Townhall-Signature header with an HMAC-SHA256 signature for verification.
Verifying Webhook Signatures
JavaScript
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return signature === `sha256=${expectedSignature}`;
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-townhall-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
console.log('Valid webhook:', req.body);
res.status(200).send('OK');
});Slack Integration
Get real-time notifications in Slack when forms are submitted.
- Go to Slack Apps and create an app
- Enable Incoming Webhooks
- Create a webhook for your channel
- Copy the webhook URL to your form settings
💡
Tip
Use the "Test" button in form settings to verify your webhook works before going live.
Discord Integration
Get submission notifications directly in Discord channels.
- Right-click your Discord channel → Edit Channel
- Go to Integrations → Webhooks
- Click New Webhook and copy the URL
- Paste in your form's Integrations settings
Google Sheets
Automatically add submissions to a Google Sheet using Apps Script.
- Open your Google Sheet
- Go to Extensions → Apps Script
- Paste the code below and click Deploy → New deployment
- Select Web app, set "Execute as" to Me, "Who has access" to Anyone
- Copy the Web App URL to your form settings
Google Apps Script
function doPost(e) {
const sheet = SpreadsheetApp.getActiveSheet();
const data = JSON.parse(e.postData.contents);
// Get or create headers
let headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
if (headers[0] === '') {
headers = ['Timestamp', 'Submission ID', ...Object.keys(data.submission.data)];
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
}
// Add row
const row = headers.map(h => {
if (h === 'Timestamp') return new Date().toISOString();
if (h === 'Submission ID') return data.submission.id || '';
return data.submission.data[h] || '';
});
sheet.appendRow(row);
return ContentService.createTextOutput(JSON.stringify({success: true}))
.setMimeType(ContentService.MimeType.JSON);
}Zapier / Make (Integromat)
Connect to 5,000+ apps using the custom webhook integration:
- In Zapier: Create a Zap with Webhooks by Zapier trigger (Catch Hook)
- In Make: Create a scenario with Webhooks module (Custom webhook)
- Copy the webhook URL they provide
- Paste it as your Custom Webhook URL in form settings
- Submit a test form to see the data structure
Email Services
Connect to email marketing platforms to add subscribers automatically:
Mailchimp
- Get your Mailchimp API key from Account → Extras → API keys
- Find your List ID in Audience → Settings → Audience name and defaults
- Use Zapier to connect TownHall webhook to Mailchimp
ConvertKit
- Get your ConvertKit API secret from Settings → Advanced
- Find your Form ID from the form URL
- Use Zapier or a custom webhook to add subscribers
Testing Webhooks
Use these tools to test your webhook integrations:
webhook.site - Inspect incoming webhook requests
RequestBin - Create temporary endpoints for testing
ngrok - Expose local servers for webhook testing