Overview
Receiving email in a backend application traditionally meant running your own SMTP server, handling deliverability, managing MX records, writing a MIME parser, and dealing with spam filtering — a significant operational burden. Most developers avoid this by using a third-party service to handle the email reception layer.
JsonHook is that service. It exposes a simple API: create an inbound address, specify your webhook URL, and every email sent to that address is delivered to your backend as a structured JSON POST request within seconds. Your backend application only needs to implement a standard HTTP endpoint — no email-specific code, no SMTP, no MIME parsing.
This approach works with any backend language or framework. A Django view, an Express route, a FastAPI endpoint, a Rails controller, a Go HTTP handler — all are identical from JsonHook's perspective. If it speaks HTTP and returns 200, it can receive email.
Prerequisites
Before integrating JsonHook into your backend:
- Backend HTTP server — any framework in any language that can expose an HTTPS endpoint
- Public HTTPS URL — your webhook endpoint must be reachable from the internet. Use a tunnel (ngrok, Cloudflare Tunnel) in development.
- JsonHook account and API key
- Understand the payload schema — review the payload documentation before writing your handler
Add Email Reception to Your Backend
One API call, one HTTPS endpoint, and your backend receives email. Start free.
Get Free API KeyStep-by-Step Instructions
Integrate email reception into your backend in these steps:
- Add a new route to your backend. Create an endpoint at a path like
/webhooks/inbound-email. Initially, just log the raw request body to understand the payload structure. - Create a JsonHook address:
POST https://api.jsonhook.com/v1/addresses Authorization: Bearer YOUR_API_KEY Content-Type: application/json { "webhookUrl": "https://yourapp.com/webhooks/inbound-email" } - Store the returned secret securely in your environment variables (not in code).
- Implement signature verification in your route handler before processing any payload.
- Parse the JSON body and extract the fields your application needs.
- Return 200 immediately and defer heavy processing to a background job.
- Test end-to-end by sending an email to your JsonHook address and confirming your backend processes it correctly.
Code Example
A Ruby on Rails controller for receiving inbound email:
# app/controllers/webhooks_controller.rb
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:inbound_email]
before_action :verify_jsonhook_signature, only: [:inbound_email]
def inbound_email
payload = JSON.parse(request.raw_post)
email = payload["email"]
InboundEmailJob.perform_later(
from: email["from"],
subject: email["subject"],
text_body: email["textBody"],
delivery_id: payload["deliveryId"]
)
head :ok
end
private
def verify_jsonhook_signature
sig = request.headers["X-JsonHook-Signature"]
expected = OpenSSL::HMAC.hexdigest(
"SHA256",
ENV["JSONHOOK_SECRET"],
request.raw_post
)
head :unauthorized unless ActiveSupport::SecurityUtils
.secure_compare(sig, expected)
end
end
Note: perform_later enqueues a background job (Active Job / Sidekiq), ensuring the controller responds immediately and heavy work happens asynchronously.
Common Pitfalls
Common backend integration mistakes:
- CSRF protection blocking the webhook. Web frameworks often include CSRF protection that rejects POST requests without a CSRF token. Disable it specifically for your webhook route (while keeping it enabled for all user-facing routes).
- Body parser consuming raw bytes. HMAC verification requires the raw request body. Configure your framework to provide raw bytes to the webhook route, not a pre-parsed object. In Express, use
express.raw(); in Django, readrequest.body. - Secrets in code. Store your JsonHook webhook secret in environment variables or a secrets manager — never committed to your repository.
- No idempotency. A retry from JsonHook can cause duplicate processing. Log processed
deliveryIdvalues and skip duplicates. - Assuming the endpoint will never be attacked directly. Even with HMAC verification, enforce rate limiting on your webhook endpoint to prevent resource exhaustion attacks.