Linje

Mailgun inbound email alternative

Keep Mailgun for sending. Make each reply address an application resource.

Mailgun provides flexible inbound Routes and a scalable Forwards API. Linje is narrower: it gives each application object an opaque reply address with immutable metadata, explicit lifecycle, and an inspectable webhook delivery history.

Mailgun already does inbound

The question is which routing model your application needs.

Mailgun Routes combine filters with forward(), store(), and stop() actions. Its newer Forwards API matches recipient patterns and sends messages to email addresses, URLs, or temporary storage. Both are useful when the routing rule itself is the product primitive.

Linje uses a different primitive: a project-scoped route representing one order, ticket, claim, case, or other application object. The callback contains the immutable metadata supplied when that route was created.

Read the official Mailgun Routes documentation. Read the official Mailgun Forwards documentation.

A narrower boundary

Use Linje when correlation and lifecycle are the core job.

Concern Mailgun inbound Linje reply route
Matching Route expressions, headers, catch-all filters, or forward patterns One opaque generated address for one application object
Application context Your application maps the matched recipient or captured value Immutable caller metadata travels with the inbound event
Inbound payload URL-encoded or multipart form fields, with raw MIME available Versioned JSON plus attachment download references
Delivery Signed request, automatic retries, optional temporary storage Signed delivery, stored artifact, attempt history, and manual replay
Lifecycle Manage the route or forward rule and your mapping state Expire, disable, enable, and list reply-route resources

Application context

Create the address when you create the conversation.

curl -fsS \
  -H "Authorization: Bearer $LINJE_PROJECT_TOKEN" \
  -H "Idempotency-Key: 018f47d2-89ab-4cde-8123-456789abcdef" \
  -H "content-type: application/json" \
  -d '{
    "inbox-id":"claims",
    "metadata":{
      "claim_id":"claim_123",
      "customer_id":"cus_17"
    }
  }' \
  https://api.linje.systems/v1/reply-routes
{
  "reply-route":{
    "id":"route_...",
    "address":"r+012345...@in.linje.systems",
    "metadata":{
      "claim_id":"claim_123",
      "customer_id":"cus_17"
    },
    "active":true
  }
}

No outbound migration

Keep the Mailgun send path unchanged.

curl --user "api:$MAILGUN_API_KEY" \
  https://api.mailgun.net/v3/mg.example.com/messages \
  -F from='Claims <claims@example.com>' \
  -F to=customer@example.com \
  -F h:Reply-To=r+012345...@in.linje.systems \
  -F subject='Claim claim_123' \
  -F text='Reply with the requested document.'

Mailgun continues to send the message. Linje receives only the reply and delivers a signed JSON event containing claim_id and customer_id to your application.

Decision guide

Routes, Forwards, or reply routes?

Use Mailgun Routes

You need expression-based filters and multi-action inbound processing.

Use Mailgun Forwards

You need scalable recipient-pattern forwarding without complex conditional logic.

Use Linje reply routes

You need each address to carry managed object context and its own lifecycle.

See the event payload and complete route lifecycle.

Pricing

Free during preview. Paid plans start at $5/month.

Create an account and test the complete reply flow without entering payment details. Creating and keeping reply routes does not consume message usage. Each customer reply counts once when Linje accepts it; webhook retries and replay are included. After preview, choose 500 messages free, 5,000 for $5/month, or 50,000 for $25/month.

See pricing and usage details.

Self-service quickstart

Add correlated replies to one Mailgun email flow.

Keep the existing send, set one Linje route as Reply-To, and process the reply using the returned metadata.

Add replies to a Mailgun flow Read the API docs