Webhook Ingester

A self-hosted solution to store all your Reloop webhook events in your own database.

The Webhook Ingester is a self-hosted tool that allows you to store all your Reloop webhook events directly in your own database. This is ideal for long-term data retention, custom analytics, and building robust event-driven workflows without worrying about webhook delivery order or duplicate handling.

Why use the Webhook Ingester?

  • Signature Verification: Built-in verification to ensure webhook authenticity.
  • Idempotency: Safely handles duplicate webhook deliveries using unique event IDs.
  • Multiple Databases: Support for PostgreSQL, MySQL, MongoDB, and data warehouses.
  • Easy Deployment: One-click deployment to Vercel, Railway, or Render.

Deploy

You can run the ingester using our official Docker image:

docker pull ghcr.io/reloop-labs/reloop-webhooks-ingester

Supported Databases

We support a wide range of databases to store your webhook events:

  • PostgreSQL (including Supabase and Neon)
  • MySQL (including PlanetScale)
  • MongoDB
  • Data Warehouses (Snowflake, BigQuery, ClickHouse)

Quick Start

1

Clone and Install

Clone the repository and install dependencies:

git clone https://github.com/reloop-labs/reloop-webhooks-ingester.git
cd reloop-webhooks-ingester
pnpm install
2

Configure Environment Variables

Copy the example environment file and add your credentials:

cp .env.example .env.local

Required variables:

# Your Reloop webhook signing secret from the dashboard
RELOOP_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxx

# Database connection string
POSTGRESQL_URL=postgresql://user:password@host:5432/database
3

Set up your Database

Run the setup command to create the necessary tables/collections:

pnpm db:setup --postgresql # or --mysql, --mongodb
4

Deploy and Register Webhook

Deploy your instance and add the endpoint in the Reloop Dashboard. Your endpoint URL will be: https://your-app.com/postgresql (or your chosen connector).

Database Schemas

The ingester creates tables with a standardized schema for different event categories:

  • reloop_wh_emails: Stores all email-related events.
  • reloop_wh_contacts: Stores audience and contact events.
  • reloop_wh_domains: Stores domain verification events.

Core Fields

Every event includes these essential fields:

  • event_id: Unique webhook event ID for idempotency.
  • event_type: The type of event (e.g., email.delivered).
  • event_created_at: When the event occurred in Reloop.
  • webhook_received_at: When the webhook was stored in your database.
  • data: JSON object containing the full event payload.

Idempotency

The ingester uses the unique event ID provided by Reloop to ensure that even if a webhook is delivered multiple times, it is only stored once in your database.

Configuration Reference

Required Environment Variables

VariableDescription
RELOOP_WEBHOOK_SECRETThe signing secret used to verify webhook authenticity.

Database-Specific Variables

Supabase / PostgreSQL

POSTGRESQL_URL=postgresql://user:password@host:5432/database

MongoDB

MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/
MONGODB_DATABASE=reloop_webhooks

Example Queries

Once your data is in your database, you can run powerful queries:

Count daily events by type:

SELECT 
  DATE(event_created_at) AS day, 
  event_type, 
  COUNT(*) AS count 
FROM reloop_wh_emails 
GROUP BY DATE(event_created_at), event_type 
ORDER BY day DESC;

Data Retention

Since the data is in your own database, you have full control over retention. You can set up TTL indexes in MongoDB or use a cron job to purge old data:

DELETE FROM reloop_wh_emails 
WHERE event_created_at < NOW() - INTERVAL '90 days';

Troubleshooting

  • Signature failing: Ensure RELOOP_WEBHOOK_SECRET matches your dashboard secret.
  • Connection errors: Check your database firewall rules and connection string.
  • Webhooks not received: Verify your endpoint is publicly accessible and returning a 200 OK.

Learn More

Was this page helpful?

Edit this page