Knowledge base

Hand a message to a webhook instead of a receiver

http-delivery queue type
A handler that can live anywhere

A queue of the http-delivery type hands a message not to a receiver or a program but to a network address: with a POST request of type application/json, one message per request. The body is a JSON object with the raw message and the envelope addresses.

Success is only a 2xx response. Everything else counts as a temporary failure: the message stays in the queue and is retried, and bounce-after decides when it bounces. This is the fundamental difference from the pipe type: there the handler’s unavailability is indistinguishable from its breakage, here it honestly turns into a queue.

What comes in the body. The email_rfc822 field is the message itself; msg_from and rcpt_to are the envelope addresses; headers is an array of headers as “name — value” pairs. If the message contains a character outside 7-bit ASCII, the whole message is encoded in base64, and email_rfc822_is_base64 with the value true appears next to it.

The main trap is a handler that responds 200 to everything. Then the node considers delivered even what the handler could not parse, and the message is lost without a trace. The opposite mistake is just as common: the handler responds 4xx to a message it does not like, and the node treats this as a temporary failure and retries it right up to the bounce deadline.
What the Hub does. It does not use it, but this is the delivery type closest to it: the Hub already has a bounce and complaint handler, and it lives over HTTP. The only difference is that today messages do not reach it directly from the node. When the time comes, this is the type to use, not pipe: it survives the Hub’s unavailability with a queue rather than with loss.
Example configuration
# complaints go to the handler, authorization comes from the headers file
<domain feedback.example.com>
    type http-delivery
    http-delivery-url https://hub.example.com/api/v1/feedback    http-delivery-extra-headers /etc/pmta/http-delivery-headers.txt
</domain>
The address must be absolute, with the http or https scheme, without credentials, a query string or a fragment. The default port is 443 for https and 80 for http.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends3 mistakes▶

The handler responds 200 to everything

§ 8.5

What it costsThe node considers everything delivered, including what the handler could not parse. Messages disappear without a trace — they are neither in the queue nor among bounces.
How to spot itAccounting shows nothing but deliveries, while the handler has less data than there were messages.
How to do it rightRespond with 2xx only after successful processing; for parsing that failed, use a code outside 2xx.

Responding 4xx to a message the handler does not need

§ 8.5

What it costsThe node treats any response outside 2xx as a temporary failure and retries the message until the bounce deadline. An unwanted message will keep knocking on the handler for days.
How to spot itThe same messages arrive at the handler again and again.
How to do it rightAccept such messages with a 2xx response and discard them on your side — this type makes no distinction between “cannot” and “will not.”

Not handling base64

§ 8.5

What it costsWhen there is a character outside 7-bit ASCII, the whole message is encoded, and email_rfc822 stops being readable text. A handler that does not look at the flag will parse garbage.
How to spot itSome messages are parsed incorrectly — usually the ones with Cyrillic in them.
How to do it rightCheck the email_rfc822_is_base64 field; its absence means the message is not encoded.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
How to check on the node
Whether the handler works is visible from the queue: with the address unavailable it grows instead of losing messages:
pmta show settings feedback.example.com/vmta1 | grep -E '^type|^http-delivery'
pmta show queues | grep -i feedback.example.com
A growing queue means responses outside the 2xx family — the handler is unavailable or responds with an error. The Hub does not use this type yet.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Receiving inbound mail · Tracking infrastructure