Knowledge base

Submitting a message over HTTP

transmissions submission
The second submission door

Accepts a message as a request instead of a mail session: recipients, substitution data and content arrive in one JSON.

The call is POST https://address:port/api/v1/transmissions to the <transmissions-api-listener> listener — only over HTTPS, so the listener needs a certificate. The header is Content-Type: application/json, and the key goes in the Authorization header; the body can be compressed by declaring Content-Encoding: gzip.

The keys are its own, not the monitor key: they are listed with api-key lines in <transmissions-api>, from 32 to 128 characters. Source properties for messages submitted this way are set by the named source {transmissions-api}.

A 200 response carries a count: how many recipients were accepted and how many rejected. Errors come as codes 400, 403, 404, 405 and 500.

The main trap is taking 200 for delivery to everyone. The code means the request was accepted, and rejection of some recipients is visible only in the body: total_rejected_recipients greater than zero with the same 200.
What the Hub does. It does not use it: the whole fleet submits mail over SMTP, and the Hub does not write a <transmissions-api-listener> listener.
Recommended values

What the response means:

Code When
200 the request is accepted; how many recipients were accepted and rejected is in the body
400 format error: a required field is missing, wrong type, an unsupported SparkPost field
403 no Authorization header or the key is wrong
404 wrong path
405 the method is not POST
500 internal error while parsing a valid request
The path, headers, compression, keys, the named source and the response codes come from the manual (§ 8.1.1–8.1.9). The trap analysis is ours.
Example configuration
# submit a message with a request: the key from <transmissions-api>
curl -s -X POST --insecure -H 'Content-Type: application/json' -H 'Authorization: KEY' --data @msg.json 'https://127.0.0.1:8585/api/v1/transmissions'
–insecure is needed only with the listener’s self-signed certificate. Port 8585 is from the manual’s example: the listener takes the port specified in its block.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
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
Check whether the listener is defined and whether it responds:
grep -n -A4 '<transmissions-api' /etc/pmta/config
curl -s -o /dev/null -w "%{http_code}\n" --insecure -X POST 'https://127.0.0.1:8585/api/v1/transmissions'
Without the blocks in the configuration there is no endpoint at all. Any HTTP code in the response means the listener is alive; 403 means the key was not accepted.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Address warm-up · Connect a sending platform