What fires
Every successful ingest fires a grid.pushed event to all active webhooks on the account. The payload includes the handle, slug, new version, row count, and visibility.
{
"event": "grid.pushed",
"grid": {
"handle": "raihan",
"slug": "sales-q2",
"version": 4,
"rows": 12408,
"visibility": "public"
},
"timestamp": "2026-05-07T09:14:22.000Z"
}Registering a webhook
curl -X POST https://instadash.io/api/webhooks \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "my-listener",
"url": "https://your-server.com/hooks/instadash",
"secret": "choose-your-own-or-omit-for-auto"
}'
# → { "id": "…", "secret": "sha256-signing-secret", "events": ["grid.pushed"], … }Note: If you omit
secret, a UUID is generated and returned once. Store it — it is not shown again.
Verifying signatures
Every delivery includes an X-Instadash-Signature header: sha256= followed by the HMAC-SHA256 hex digest of the raw request body, keyed by your secret.
import { createHmac } from 'node:crypto'
function verify(rawBody, secret, header) {
const expected = 'sha256=' +
createHmac('sha256', secret).update(rawBody).digest('hex')
return expected === header
}
// Express example
app.post('/hooks/instadash', (req, res) => {
if (!verify(req.rawBody, process.env.WEBHOOK_SECRET,
req.headers['x-instadash-signature'])) {
return res.sendStatus(401)
}
const { event, grid } = req.body
console.log(event, grid.handle, grid.slug, 'v' + grid.version)
res.sendStatus(200)
})Listing and deleting
# List
curl https://instadash.io/api/webhooks \
-H "Authorization: Bearer sk_live_…"
# Delete
curl -X DELETE https://instadash.io/api/webhooks/<id> \
-H "Authorization: Bearer sk_live_…"Plan: Webhooks require the Builder plan or above. The registration endpoint returns HTTP 403 on free accounts.