Reply by Email API
Let customers reply by email without losing application context.
Give each order, claim, case, or workflow an opaque Reply-To address. When someone replies, Linje sends your application a signed event containing the original context, message content, and attachments.
Reply sidecar
Keep your current outbound provider.
Continue sending through Resend, SendGrid, Mailgun, SES, or your existing email stack.
Put the Linje-generated address in Reply-To; Linje handles the inbound
reply, correlation, signed delivery, retries, and replay. Moving outbound email to
Linje is optional.
Provider guides
Keep the sender you already use.
Use cases
Keep email replies inside the product that owns the context.
Attach a customer's answer to the claim or order that prompted it.
Turn the reply into a comment on the correct ticket or application case.
Receive requested files against the right application, claim, or review.
Why reply routes
Use an application abstraction instead of assembling correlation primitives.
Some email providers expose recipient tags or other inbound primitives. Linje manages the route, its immutable application context, and the delivery lifecycle as one project-scoped resource.
Route
Create a project-scoped reply address.
1. Create a generated inbox for your webhook
curl -fsS \
-H "Authorization: Bearer $LINJE_PROJECT_TOKEN" \
-H "content-type: application/json" \
-d '{"webhook-url":"https://app.example.com/linje/inbound"}' \
https://api.linje.systems/v1/inboxes/provision
Copy the returned inbox.id and store the one-time webhook secret.
2. Create a reply route for one application object
curl -fsS \
-H "Authorization: Bearer $LINJE_PROJECT_TOKEN" \
-H "Idempotency-Key: 018f47d2-89ab-4cde-8123-456789abcdef" \
-H "content-type: application/json" \
-d '{
"inbox-id":"<returned-inbox-id>",
"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
}
}
Use a fresh UUIDv4 as the idempotency key for each logical route. Concurrent and sequential exact retries return the same route and address; conflicting reuse returns 409. After retention cleanup, a retry returns 410 so a purged address cannot be revived or rebound.
Outbound
Use the generated address as Reply-To.
From: claims@example.com
To: customer@example.com
Reply-To: r+012345...@in.linje.systems
Subject: Claim claim_123
These are ordinary email headers. The message can be sent through Linje or another transactional email provider.
Inbound
The reply arrives with caller metadata.
POST https://app.example.com/linje/inbound
x-linje-inbound-id: ...
x-linje-delivery-id: ...
x-linje-timestamp: ...
x-linje-signature: sha256=...
{
"schema":"linje.inbound-email.v1",
"inbound-id":"...",
"inbox-id":"claims",
"route": {
"id":"route_...",
"metadata":{
"claim_id":"claim_123",
"customer_id":"cus_17"
}
},
"email": {
"from":[{"email":"customer@example.com"}],
"subject":"Re: Your order",
"in-reply-to":["<linje...@tx.example.com>"],
"references":[]
},
"content":{"text":"The requested photo is attached."},
"attachments":[
{
"filename":"photo.pdf",
"download":{"url":"https://api.linje.systems/..."}
}
]
}
Lifecycle
Expire or disable addresses without changing metadata.
curl -fsS -X PATCH \
-H "Authorization: Bearer $LINJE_PROJECT_TOKEN" \
-H "content-type: application/json" \
-d '{"active":false}' \
https://api.linje.systems/v1/reply-routes/route_...
Disabled, expired, malformed, and unknown routes do not reach the target inbox webhook and do not expose caller metadata.
Route listings accept inbox-id, cursor, and limit. The default page size is 100 and the maximum is 500. Responses use next-cursor pagination.
The complete address is returned only on creation and exact idempotent retries, so store it when you create the route. Metadata is immutable and limited to 16 KiB.
Disabled and expired routes can be removed after the configured retention window; Linje retains only a minimal hash tombstone.
The complete product
Want one system for both directions?
Linje also sends transactional email, with idempotent enqueueing, retries, delivery events, bounce handling, suppression, and inspectable timelines. Keeping your current sender is an adoption option, not a product limitation.
Boundary
Correlation is not workflow.
Linje tells your application which route received the email. Your application decides whether the message updates an order, creates a comment, or does nothing. Linje does not become a helpdesk, rules engine, or shared inbox.
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.
Self-service quickstart
Route one real reply back to the right object.
Keep your outbound provider, create one reply route, and verify that text and an attachment reach the correct application object through a signed webhook.