How to Route Emails by Recipient Address

Different addresses, different webhooks. Create one JsonHook address per email flow and route each message to exactly the right handler — with no shared logic and no fragile subject parsing.

Table of Contents
  1. Overview
  2. Prerequisites
  3. Step-by-Step Instructions
  4. Code Example
  5. Common Pitfalls

Overview

Recipient-based routing is the most reliable way to direct inbound emails to the right processing handler. The idea is simple: instead of one address that receives everything and then dispatches based on content, you create multiple inbound addresses — one per email category — each with its own dedicated webhook URL.

Examples:

This approach has several advantages over content-based routing: it is zero-maintenance (no regex to update), it is transparent (the routing is visible in the address configuration), and it scales — adding a new email category is simply provisioning a new address.

Prerequisites

What you need:

  • A JsonHook account with enough address quota (Starter: 5 addresses, Pro: unlimited)
  • A separate webhook endpoint URL for each email category
  • Control over the email sources (forms, ESPs, forwarding rules) to direct each email type to the correct address

Route Every Email to the Right Handler

One address per flow. Unlimited on Pro. Start with 5 on Starter.

Get Free API Key

Step-by-Step Instructions

Set up recipient-based routing from scratch:

  1. List your email categories and the handler endpoint for each.
  2. Create a JsonHook address for each category:
    # Support
    curl -X POST https://api.jsonhook.com/v1/addresses   -H "Authorization: Bearer $API_KEY"   -d '{"webhookUrl":"https://app.com/webhooks/support","label":"Support"}'
    
    # Orders
    curl -X POST https://api.jsonhook.com/v1/addresses   -H "Authorization: Bearer $API_KEY"   -d '{"webhookUrl":"https://app.com/webhooks/orders","label":"Orders"}'
  3. Note the returned email addresses — each will look like [email protected].
  4. Configure your email sources. Update your contact form's To field, your ESP's routing rules, or your MX-level forwarding to direct each category to the appropriate JsonHook address.
  5. Test each route by sending a test email to each address and verifying the correct handler is called.
  6. Optional: use a custom domain. On Starter/Pro plans, configure a custom inbound domain so your addresses look like [email protected] instead of @in.jsonhook.com.

Code Example

Script to provision multiple routing addresses via the JsonHook API:

#!/usr/bin/env node
// provision-routes.ts
import fetch from "node-fetch";

const API_KEY = process.env.JSONHOOK_API_KEY!;

const ROUTES = [
  { label: "Support",  webhookUrl: "https://app.com/webhooks/support"  },
  { label: "Orders",   webhookUrl: "https://app.com/webhooks/orders"   },
  { label: "Invoices", webhookUrl: "https://app.com/webhooks/invoices" },
  { label: "Leads",    webhookUrl: "https://app.com/webhooks/leads"    },
];

async function provisionRoutes() {
  for (const route of ROUTES) {
    const res = await fetch("https://api.jsonhook.com/v1/addresses", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(route),
    });

    const data = await res.json() as any;
    console.log(`${route.label}: ${data.email} (secret: ${data.secret})`);
    // Store data.secret in your secrets manager!
  }
}

provisionRoutes();

Common Pitfalls

Routing configuration issues to watch for:

  • Mismatched secrets across addresses. Each address has its own webhook secret. Make sure each handler uses the correct secret for its address — do not share one secret across all handlers.
  • Email sources sending to the wrong address. After changing routing configuration, verify by sending test emails and checking the delivery log to confirm the right webhook URL receives each test.
  • Not updating routing when handler URLs change. If you change a webhook handler URL, update the corresponding JsonHook address via PATCH /v1/addresses/{id}. Stale URLs cause delivery failures.
  • Forgetting to route catch-all emails. Emails that do not match any specific address (e.g., typos in the recipient address) go undelivered. Consider setting up a catch-all address to capture these.
  • Using per-user addresses on the free or Starter plan. If you need a unique address per user or per customer, you need the Pro plan's unlimited addresses. The free tier (1 address) and Starter (5 addresses) are not suitable for per-entity address schemes.

Frequently Asked Questions

Can I route based on the subdomain of the recipient address?

With a custom inbound domain on the Starter or Pro plan, you can create addresses like [email protected] and [email protected] — each with its own JsonHook configuration. Subdomain-based routing (e.g., [email protected]) requires wildcard MX records and is available with a custom domain setup on the Pro plan.

Can I route to different webhook URLs within the same application based on recipient?

Yes. Each JsonHook address specifies its own webhook URL independently. You can have all webhook URLs point to the same domain (e.g., https://app.com/webhooks/support and https://app.com/webhooks/orders) or to entirely different applications. The routing is per-address at the JsonHook level.

How do I list all my configured addresses?

Use the GET /v1/addresses API endpoint. It returns a paginated list of all your inbound addresses including their IDs, email addresses, labels, webhook URLs, and status. This is useful for programmatic management and monitoring.

What happens if I delete an address that is still receiving email?

Deleted addresses stop accepting new email immediately — senders receive a bounce notification. In-flight deliveries that arrived before deletion are still delivered to the webhook URL. It is best to deactivate (pause) an address before deleting it to allow any queued deliveries to complete.