What does an integration need?
Most integrations follow the same pattern. Something happens in one system, a webhook arrives (or a scheduled job notices the change), and your code updates another system. The hard parts are around the edges: checking the signature, storing the event so it isn't lost, retrying when the other side is down, and catching what slipped through.
Webhook gateways such as Svix and Hookdeck handle delivery, then hand the event to your backend. Codehooks is that backend. The endpoint, the database, the queue and the cron job that reconciles at night all live in one project.
Signature checks use webhook-verify, our open source package that covers more than 20 providers with one call.
Shopify orders into your CRM
The endpoint verifies and stores each order, then a worker sends it on. If the CRM is down, the order is still in the database with synced set to false.
import { app, Datastore } from 'codehooks-js';
import { verify } from 'webhook-verify';
// Shopify calls this endpoint, so it skips the API key check
app.auth('/webhook/*', (req, res, next) => next());
app.post('/webhook/shopify', async (req, res) => {
const secret = process.env.SHOPIFY_WEBHOOK_SECRET;
if (!verify('shopify', req.rawBody, req.headers, secret)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const conn = await Datastore.open();
const saved = await conn.insertOne('orders', { order: req.body, synced: false });
await conn.enqueue('toCrm', { id: saved._id });
res.json({ ok: true }); // reply fast, do the work in the worker
});
app.worker('toCrm', async (req, res) => {
const conn = await Datastore.open();
const { order } = await conn.getOne('orders', req.body.payload.id);
await fetch(process.env.CRM_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: order.email, total: order.total_price }),
});
await conn.updateOne('orders', req.body.payload.id, { $set: { synced: true } });
res.end();
});
export default app.init();
Webhooks and integration guides
Handlers for specific providers, and complete templates for the common integration jobs.
Payments, subscriptions and invoices, with signature verification.
Orders, products and customers from your store.
Pushes, pull requests and issues, verified and stored.
Discord, Slack, Twilio, PayPal, SendGrid, Mailgun, Jira, OpenAI and more.
Keep two systems in step with queues, per-client state and a nightly check.
Send signed webhooks to your own users, with retries and delivery logs.
Catch, inspect and replay incoming webhooks while you build.
Guides for React, Next.js, Svelte, MongoDB, Auth0, AWS S3 and others.
Questions about integrations
Common questions about building with Codehooks.
Which webhook providers are supported?
Can I send webhooks to my own customers?
How do I keep two systems in sync?
How is this different from Svix or Hookdeck?
Building with a coding agent
Ask your agent to start from a webhook template with coho create --template, set the secrets with coho set-env, deploy, and check incoming events with coho log -f.
Connect your first service
Deploy a webhook handler from a template and point your provider at it.