Developers
Quickstart in 2 minutes. Full REST API. Webhook payloads you can actually read.
Sign up for free at streamhook.in. No credit card required.
Paste your database connection URI. We validate permissions and discover tables automatically.
curl -X POST https://api.streamhook.in/v1/sources \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Postgres",
"type": "postgresql",
"connection_uri": "postgres://user:pass@host:5432/mydb",
"tables": ["orders", "users", "payments"]
}' Point us to your webhook endpoint. Optionally set a signing secret for HMAC verification.
curl -X POST https://api.streamhook.in/v1/sources/src_xyz/destinations \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/streamhook",
"secret": "whsec_your_signing_secret",
"headers": { "Authorization": "Bearer your_token" }
}' That's it. Every INSERT, UPDATE, DELETE on your selected tables will hit your endpoint in real time.
// Your endpoint receives events like this:
app.post('/webhooks/streamhook', (req, res) => {
const event = req.body;
console.log(event.operation); // "INSERT"
console.log(event.source.table); // "orders"
console.log(event.after); // { id: 42, total: 99.00, status: "paid" }
res.status(200).send('ok');
}); Every event delivered to your webhook follows this structure:
{
"id": "evt_a1b2c3d4e5f6",
"timestamp": "2026-03-13T10:30:00.123Z",
"source": {
"database": "myapp_production",
"schema": "public",
"table": "orders"
},
"operation": "UPDATE",
"before": {
"id": 42,
"status": "pending",
"amount": 99.00,
"updated_at": "2026-03-13T10:29:50.000Z"
},
"after": {
"id": 42,
"status": "shipped",
"amount": 99.00,
"updated_at": "2026-03-13T10:30:00.000Z"
},
"metadata": {
"source_id": "src_xyz789",
"connector": "postgresql",
"lsn": "0/1A2B3C4",
"snapshot": false
}
} id Unique event ID. Use for idempotent processing. timestamp ISO 8601 timestamp of when the change occurred. source Database, schema, and table where the change happened. operation One of: INSERT, UPDATE, DELETE. before Row state before the change (null for INSERT). after Row state after the change (null for DELETE). metadata Internal tracking info: source ID, connector type, LSN offset. Content-Type application/json X-StreamHook-Event-ID evt_a1b2c3d4e5f6 X-StreamHook-Signature sha256=... X-StreamHook-Timestamp Unix timestamp of delivery User-Agent StreamHook/1.0 If you configured a signing secret, verify the HMAC-SHA256 signature on every request:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expected}`)
);
}
app.post('/webhooks/streamhook', (req, res) => {
const signature = req.headers['x-streamhook-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the verified event...
res.status(200).send('ok');
}); Base URL: https://api.streamhook.in/v1. Authenticate with X-API-Key header.
/sources /sources /sources/:id /sources/:id /sources/:id /sources/:id/destinations /sources/:id/destinations /sources/:id/destinations/:did /sources/:id/destinations/:did /events /events/:id/retry Get your API key in 30 seconds. 50K events/month free.
No credit card required. Free forever on the Free plan.