I've got several production servers running a LAMP stack. They each have a local Postfix server catching any mail from the system and from PHP, and relaying it via a smarthost (the SendGrid SMTP service).

I'd like to add a custom header to every outgoing message sent to the smarthost. This allows me to filter statistics per server in SendGrid. Something like:

X-SMTPAPI: {"category": "www1"}

The Postfix docs mention using the PREPEND action in a Postfix 'access' table. So, I added the following line to /etc/postfix/access:

PREPEND X-SMTPAPI: {"category": "www1"}

and hashed the access file with postmap.

However, I have no idea how to use the map. Something like the following doesn't work:

smtp_client_restrictions = check_client_access hash:/etc/postfix/access

How do I make Postfix prepend this header?

3 Answers 3


This answers your exact question: https://web.archive.org/web/20150706131729/http://hoursofop.tumblr.com/post/17760274650

Quick steps reported here:

  • create a file /etc/postfix/sendgrid_headers and add this line to it:

      /^From:/ PREPEND X-SMTPAPI: {“category” : “Category Name”}
  • update your master.cf file with the following line:

      smtp      unix  -       -       n       -       -       smtp 
        -o smtp_header_checks=regexp:/etc/postfix/sendgrid_header

It applies to a Ubuntu system and worked perfectly for me. Be careful to choose the right smtp line in master.cf. I used a tab to indent the -o line.

Also note that SendGrid strips out the X-SMTPAPI header from the email before it is sent on - so you won't find it there but you will see the category appear within the SendGrid dashboard.

  • It is 2023 and I was able to get this working. Additional things to watch out for.
    – wruckie
    Commented Mar 27, 2023 at 20:44
  • 1) You will need to change the smart quotes to normal ones ( “ > "). With smart quotes, SendGrid gave me This email was not sent because the SMTPAPI header was invalid. error.
    – wruckie
    Commented Mar 27, 2023 at 20:46
  • 2) For me the smtp unix... line already existed near the bottom. I tried to paste in both lines as instructed, but got warning: duplicate master.cf entry for service "smtp" (private/smtp) - using the last entry. So all I had to add was the second line starting with -o till it looked like the lines described here.
    – wruckie
    Commented Mar 27, 2023 at 20:46
  • 3) SendGrid did remove the header, but the category showed up in about 5 minutes.
    – wruckie
    Commented Mar 27, 2023 at 20:46

You seem to have mis-spelled header_checks as smtp_client_restrictions, which isn't even the correct spelling of the wrong parameter. ☺

This sort of thing is far better done with a simple shim around sendmail, that your PHP (or whatever) scripts are configured to use, you know. The shim script would be a simple exercise in the use of the cat and echo commands. The MTS is really the wrong place to be doing this.

  • Couldn't get it working with header_checks either. Also, that processes every single header so appears to be overkill for such a simple task. Thanks for the suggestion of using a wrapper, but that also seems like a kludge for something an MTA should be able to do with ease. Is there really no 'easy' way? Commented Jun 17, 2011 at 20:38
  • Yes, there's an easy way, and it's the way of the shim script. Concocting application-layer message content like this is the job of the MUA, not the MTS. This task is fully and squarely within the realm of PHP and the agents that it uses to concoct messages before submission, not in the MTS.
    – JdeBP
    Commented Jun 18, 2011 at 10:03

I had a similar problem with Sparkpost: I needed to add their custom header in order to set some delivery options.

This problem (adding a custom header to all emails) has many different solutions.

My solution is using Postfix header_checks and prepending the custom header to the "From" header.

  • Create a new file, named /etc/postfix/my_custom_header:

    /^From:/i X-MSYS-API: { "options" : {"transactional": true} }
  • Edit /etc/postfix/main.cf (appending to the bottom):

    # Add custom Sparkpost X-MSYS-API header to all mails
    header_checks = regexp:/etc/postfix/my_custom_header
  • reload Postfix configuration (this command is for Debian Wheezy, and may be different on your OS)

    service postfix reload

EDIT: Unfortunately, this method adds the header to all emails (incoming and outgoing). I am still searching for a method that adds the header only to outbound emails.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .