GandiMail SIEVE filters
How to use SIEVE filters for email filtering
What is a sieve filter?
Sieve filters are email filters that you can set up so that they are run on the mail server instead of in your email application.
The advantage of sieve filters over “conventional” filters is that you only need to set them up once (on the server), and they will be active even if the mail application itself isn't in use.
This means that whether you're accessing your emails from your smartphone, webmail or email client, the emails will be delivered to the same location (your chosen directory), and will always be processed in the same way, without you needing to configure or update the filters for each application separately.
Getting started with Sieve
Basic introduction to SIEVE filters
Sieve filters are email filters that are applied directly to the mail server, unlike the usual filters, which are limited to the Mail application.
Advantages of Sieve filters
Unlike filters available with mail software (such as Thunderbird or Outlook for example), Sieve filters act on email directly on the mail server, which means that the filter will be accessible to any software or webmail you use. So if you use Outlook at work, for example, but SOGo at home, the filters will be active in both locations.
You don't need to do anything special with your domain name to get started. Your Gandi e-mail address is ready to use this feature.
How to get started with Sieve
Sieve filters exist as a single file on our server that contains all the filters you have created. To manage these filters, you'll need to use an external application.
Step 1. Choose a Sieve application
Sieve filters are created using a specific programming language, SIEVE. There are a number of applications that let you use this language to build your filters from scratch. There are also extensions or plug-ins that allow you to create filters without having to write a single line of code. Both types of application work in the same way, the only difference being the writing method. Advanced users or those with complex filters to set up will prefer to write their own code. Beginners will prefer a more interactive interface.
For users looking for a simplified interface, our two Webmail offerings, SOGo and Roundcube, both offer such an interface. The filters created using these two products are Sieve filters and will therefore be applied by all mail clients used by the email address in question. However, neither of them offers a way of setting up filters written in code; only the simplified interface is available.
To set up your own filters, Thunderbird users can use Thomas Shmidt's **Sieve** extension, which is perfectly suited to this purpose, but you can search for others if you wish or need to, on sieve.info for example.
Note
If you're using Sogo and have already created filters via this webmail, you'll see that a file (usually named “Sogo”) already exists. In that case, don't create a new file, but use the existing one.
Step 2. Activate Sieve for your email address
Once you've chosen the Sieve application you want to use, you need to make sure it's able to link to your mailbox.
If you're using the Thunderbird Sieve extension, this is done automatically: just select “Sieve Settings” in the settings for the email account in question, or choose “Sieve Filters” from the Thunderbird “Tools” menu, then select the email address in question.
If you need it, here are the connection details:
host: mail.gandi.net
port: 4190
login: full email address (e.g. name@domain.tld)
password: the password of the email address involved
Step 3. Create filters
Every email is made up of two parts: the body and the headers. The body contains what you think of as the content of the email. The headers contain information such as who sent the email, from which server, at what precise date and time, and so on. Sometimes the mailservers that process these emails will add extra headers for processing reasons. For example, Gandi's mailserver will analyze the email in question and create a header with the result of this analysis. You can then use this header added by our email servers to create your own anti-spam filters.
X-GND status
The X-GND status is a Mail header that categorizes email “types”. The table below explains each of the statuses used by Gandi.
If you create a Sieve filter via a Graphical User Interface, such as SOGo, you can filter by header by choosing “Header” from the list of “conditions”, then entering “X-GND-Status” in the header type, before specifying the filtering criteria.
The same filter, created in SIEVE code, will also send “Commercial” emails to a “Commercial emails” sub-directory.
# Filter E-mails classified as MCE or PCE in the commercial directory.
require “fileinto”;
if header :contains [“X-GND-Status”] [“MCE”, “PCE”] {
fileinto “E-mails Commercial”;
}
You can also use the code below to create a filter that will send all messages with a SPAM score above 200 to the “junk” folder:
# Filter Emails with a spam score greater than 200 into the Junk directory.
require [“fileinto”, “regex”];
if allof (header :contains [“X-GND-Status”] [“SPAM”], header :regex [“X-GND-Score”] [“[2-4][0-9][0-9]”] {
fileinto “Junk”;
}
Examples of SIEVE filters for e-mails
Send renewal emails in a “Renewals” directory
The filters below are written in “SIEVE” code. For more information on how to create your own SIEVE filters, please refer to Getting started with Sieve. You can also read the SIEVE Tutorials chapter for a step-by-step explanation of how to write your own SIEVE filters.
Note
Only one SIEVE file can be activated at a time, so it's important to include all the filters you want to use in the same SIEVE file.
Send renewal emails in a “Renewals” folder
The filters below are written in “SIEVE” code. For more information on how to create your own SIEVE filters, please refer to Getting started with Sieve. You can also read the SIEVE Tutorials chapter for a step-by-step explanation of how to write your own SIEVE filters.
Note
Only one SIEVE file can be activated at a time, so it's important to include all the filters you want to use in the same SIEVE file.
Send renewal e-mails to a “Renewals” folder
This filter will redirect all e-mail from “support-renew@gandi.net” to a subdirectory of your inbox called “Renewals”.
# Send E-mails from “support-renew@gandi.net” to my renew folder.
require “fileinto”;
if address :is [“from”, “sender”] “support-renew@gandi.net” {
fileinto “INBOX/Renewals”;
stop;
}
The directory name you use is “relative” to the root location: “INBOX/Renewals” therefore refers to a “Renewals” subdirectory of the inbox (“INBOX”).
The stop command stops filtering on the message in question, meaning that no further filters will be applied to this type of message after this action.
Automated out-of-office reply
This filter is an example of an automatic reply that you can use during an absence. It uses dates and relational extensions to define a filter activation period between two dates.
For more information on the “absence” extension, take a look at the proposed standards: (in English).
# Let's tell people I'll be away next week.
require [“vacation”, “date”, “relational”];
# If the date of receipt of the email received is greater than or equal to
# August 1st and less than or equal to August 15th
if allof (currentdate :value “ge” “date” “2025-08-01”, currentdate :value “le” “date” “2025-08-15”) {
vacation :subject “Gone fishing”
“Hello, I've gone fishing and I'll be back in 15 days. - Mr. Smith”;
}
Sub-address filtering
A “sub-address” is an email address that you create “on the fly” by adding “+tag” to the “name” part of an email address. For example if I want to create a new account on Amazon™ without giving my “real” email address, I can use “myaddress+amazon@example.com”. I'd still receive emails on “myaddresse@example.com”, but the email address specified in the “For:” (to:) will contain the tag, which allows me to know who's using that address and therefore filter and redirect those emails to a specific directory.
# Move emails from my +amazon address to an “amazon” directory.
require [“envelope”, “subaddress”, “fileinto”];
if envelope :detail “to” “amazon” {
fileinto “INBOX/amazon”;
}
The :user comparator checks the “name” part of the email address. So for my address “myaddress+amazon@example.com” it will check “myaddress”. The :detail comparator checks the additional part of the address, or “amazon” in this example. You can learn more about sub-addresses and its extension by reading this page.
With the filter below, you can redirect emails from several sub-addresses into directories with the same name (tag).
require [“variables”, “envelope”, “fileinto”, “subaddress”];
if envelope :is :user “to” “user” {
if envelope :matches :detail “to” “*” {
set :lower “name” “${1}”;
}
if string :is "${name}" "" {
fileinto "INBOX";
} else {
fileinto "INBOX/${name}";
}
}
Flag messages from a specific person
The filter below “marks” (labels) all messages from a specific email address.
# marks all emails received from “vip@example.com”
require [“imap4flags”, “envelope”];
if envelope “from” “vip@example.com” {
setflag “\\Flagged”;
stop;
}
More information
The following pages provide more information and examples of how to use Sieve filters:
https://fr.wikipedia.org/wiki/Sieve
https://www.telecom-sudparis.eu/s2ia/user/doutrele/sieve/sieve.html
https://p5r.uk/blog/2011/sieve-tutorial.html
https://protonmail.com/support/knowledge-base/sieve/
https://ceng.metu.edu.tr/server-side-mail-filtering-using-sieve
https://support.tigertech.net/sieve
https://doc.dovecot.org/configuration_manual/sieve/examples/
Spam management with Sieve
Managing spam with Sieve
You can create filters using parameters available in email headers.
Flag messages from a specific person
The filter below “marks” (labels) all messages from a specific email address.
# marks all emails received from “vip@example.com”
require [“imap4flags”, “envelope”];
if envelope “from” “vip@example.com” {
setflag “\\Flagged”;
stop;
}
More information
The following pages provide more information and examples of how to use Sieve filters:
https://fr.wikipedia.org/wiki/Sieve
https://www.telecom-sudparis.eu/s2ia/user/doutrele/sieve/sieve.html
https://p5r.uk/blog/2011/sieve-tutorial.html
https://protonmail.com/support/knowledge-base/sieve/
https://ceng.metu.edu.tr/server-side-mail-filtering-using-sieve
https://support.tigertech.net/sieve
https://doc.dovecot.org/configuration_manual/sieve/examples/
Managing spam with Sieve
Managing junk mail with Sieve
You can create filters using parameters available in email headers.
Filtering junk mail (spam)
To create a filter for unwanted email, you can use X-GND-Status and X-GND-Score, with the following conditions:
X-GND-Status header contains “SPAM” and X-GND-Score header corresponds to [2-4][0-9][0-9] // score is greater than 200.
It is also possible to create filters using the X-Spam-Flag and X-Spam-Levels headers with the following conditions:
X-Spam-Flag header is “true” and X-Spam-Flag header contains “******' // level greater than 6 asterisks,
Filter e-mails using tags
To create a Sieve filter using assigned tags, you can create a filter using the X-GND-Status header with the following condition:
X-GND-Status header contains {tag}
The system supports the following tags:
- X-GND-Status: PCE: Professional Commercial email detected by signature analysis. These are typically e-mail campaigns from a recognized professional platform (ESP) that adheres to the rules concerning email advertising, i.e. including unsubscribe links, list deletion, etc...
- X-GND-Status: MCE: Commercial email detected and following email marketing rules, but coming from an unknown platform.
- X-GND-Status: SOCIAL: Notifications and alerts from Social Networks
- X-GND-Status: PURCHASE: Internet purchase confirmation e-mails.
- X-GND-Status: ACCOUNT: Emails sent to confirm the creation or update of a user account.
X-GND-Status: TRAVEL: Emails sent to confirm travel (car rental, travel agency, hotel reservation). - X-GND-Status: FINANCE: Emails sent concerning financial information (bank transfer confirmation, account status, etc.).
- X-GND-Status: ALERTING: Emails sent to subscribe to an alert service (Google alerts, Yahoo alerts, real estate, etc.).
-
X-GND-Status: BOUNCE: Notification of an undeliverable email.
-
X-GND-Status: SUSPECT: A message whose subject may be potentially “harmful” (e.g. emails whose content refers to money transfers).
Supported Sieve extensions
List of SIEVE extensions supported by Gandi
Below is a list of SIEVE extensions available on Gandi's mail servers. For more information on how to use these extensions, follow the links on the extension name.
body | Vérifie la présence d’une ou plusieurs chaines de caractères dans le corps du message |
comparator-i;ascii-numeric | Extraits les chiffres d’un texte et les compare pour voir s’il y a concordance |
copy | Spécifie qu’une copie d’un E-mail doit être utilisée pour effectuer une action (comme transférer ou déplacer) |
date | Permet d’effectuer une action basé sur la date ou l’heure de réception ou d’envoi d’un E-mail |
duplicate | Teste si l’E-mail est un doublon |
encoded-character | Permet l’encodage de caractères spéciaux numériquement |
envelope | Permet de tester de parties de l’enveloppe, comme l’adresse « Pour : » ou « De: » |
extracttex | A utiliser avec « foreverypart », extrait une partie spécifique du texte et l’utilise comme une variable |
fileinto | Distribue le message dans un répertoire spécifique |
foreverypart | Permet d’effectuer des commandes sur chaque partie MIME d’un message |
ihave | Teste si une extension SIEVE est disponible et effectue une action selon le résultat |
imap4flags | Permet la configuration des Flags IMAP et des mots clés dans les messages |
include | Permet l’inclusion d’un script SIEVE dans un autre |
index | Permet la correspondance de champs des entêtes basée sur la position du texte dans la chaîne (par exemple à partir du 5ème caractère) |
mailbox | Vérifie qu’un répertoire spécifié existe |
mime | Permet des tests sur des parties MIME spécifiques d’un message |
regex | Permet l’utilisation d’expressions régulières |
reject | Refuse la distribution d’un message |
relational | Permet des comparaisons relationnelles de parties d’un message |
subaddress | Permet de tester des sous-parties d’une sous-adresse |
vacation | Permet les E-mails en réponse automatique |
variables |
Ajoute le support des variables |
Tutorial: Writing in Sieve code
Tutorial: Write your own SIEVE filters
This chapter is a tutorial to show you how to write scripts using the SIEVE language. It will cover the basics of how to use it. You'll learn how to create a script that :
Rejects messages above a certain size
Filters emails from a list in a specific directory
Filters emails with a “suspicious” subject in the “Junk” folder
There are many possible options with SIEVE, many of which will not be covered in this tutorial. But this tutorial should provide you with a basic understanding of how SIEVE filters work and how they are structured, so that you can create your own filters using the available commands. A list of the commands available on Gandi's mail servers is available here. Some examples of filters are also available here.
Note
Even if your email software is in another language, parts of messages or directories will be used with their "standard" name, i.e. in English, otherwise the filter won't be able to recognize them.
List the extensions used
The first thing to do when writing a SIEVE filter is to list the extensions that will be required by the filter.
The SIEVE core is made up of a few basic commands as well as extensions adding extra functionality. The first line of your script will therefore be the “require” command, followed by the list of extensions that will be used in the filter. In the filter created in this tutorial, you'll need the “fileinto” and “reject” extensions.
Your first line will therefore look like this:
require [“fileinto”, “reject”];
The list of orders available on Gandi's mail servers is available here.
Comments
When you write code, comments are text that is not interpreted (not taken into account) when the code is processed. It's a good idea to comment your code to explain to others what you're trying to do with the code, or even for you when you need to modify the code after a certain delay.
You can create comments in SIEVE by using the hash character (#) or “hashtag” to pass the following line as a comment, as below:
# This is a comment.
Or you can create a comment on a portion of a line, or on several lines, like this:
/* This is also a comment. */
/* This
* is
* a comment
* on several lines. */ with a non-comment section.
The filter you create in this tutorial includes comments to help explain each step. Your filter should look like this:
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
Creating filter criteria
The filter starts by blocking all e-mails larger than 2 MB. But first you need to tell the filter what you're looking for. To do this, you need to add an if (condition) command. Don't forget to add a comment too. With the comment and the condition, your filter should look like this:
# Messages larger than 2 MB will be rejected with an error message
if
Next, you need to tell the filter which part of the message to check. This could be the “To:” address, the “From:” address, the subject, the date sent, etc... In this case, the filter must check the size of the e-mail, i.e. size
# Messages larger than 2 MB will be rejected with an error message
if size
Then, you need to provide a criteria for the filter to compare the condition with the message content. This “comparator” must always be preceded by a colon. For this filter, you'll use :over. This tells the filter to look at messages whose size exceeds the specified size. In our case, the size must be 2000K, 2000 Kb or 2 MB.
We've provided the filter with a set of criteria to “compare”. To tell your filter that the condition is finished, use an open bracket: {. Your filter should now look like this:
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
Actions to be taken on a filtered message
Once you've defined which messages you're looking for, you need to tell the filter what to do with the messages it finds. This is done by setting an action between brackets ({ and }). All actions entered between these brackets will be applied if (and only if) the condition is met.
There are several possible actions on an email, such as moving it to a specific directory, deleting it, forwarding it, etc. This filter uses the reject command to refuse delivery of the message to the inbox.
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
After writing all the operations to be applied in the case of a verified condition, we “close” the part of the operations to be applied with a closed brace: }
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
}
After this step, you've created a fully functional SIEVE script! We could stop here, but there are more emails to filter, so let's get on with it.
Add other criteria
You'll probably want to filter your messages for other reasons. To add additional criteria you can use the elsif statement. This is short for else if and tells the script that other criteria can be applied to messages processed by the filter that don't match the first criterion.
Warning
When you use SIEVE code, all your filters must be in a single file. When you upload a new SIEVE file to the mail server, it will overwrite any existing file. In other words, don't create a new file for a new filter, but edit the existing file or your old filters will be lost.
For the next criterion, the filter will move all emails from a mailing list into a dedicated directory. To get started, use elsif :
# Emails from a mailing list will be put into the folder “mailinglist”
elsif
To do this, the filter needs to check the address part of the message. As you're looking for an exact match on the whole address you'll use the :is comparator.
# Emails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is
Now that you've specified which part of the email to check, you need to specify the criteria to look for in the comparison. The filter will check both the “To:” and “From:” addresses of the message and apply actions if one of them is “mailinglist@example.com”. This is done using square brackets ([ and ]) followed by the address:
# Emails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
When we add the “closed” bracket to close the condition, the script looks like this:
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
}
# Emails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
# E-mails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
fileinto “INBOX/mailinglist”;
}
At this stage, the complete filter should look like this:
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
}
# E-mails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
fileinto “INBOX/mailinglist”;
}
Test several criteria at once
To test multiple criteria at once, you can use the anyof (any) or allof (all) statements. The anyof statement will perform the action as long as at least one of the criteria conditions is valid. allof will only perform the operation if all criteria are valid. This filter will use anyof :
# if this e-mail is not addressed to me or if the subject contains “free money” “Nigerian
# prince" put it in spam.
elsif anyof
Next, place the various sorting criteria in brackets, separated by a comma. The first criterion will search for any email not directly addressed to your address (e.g. “myemailaddress@example.com”). To display a negative criteria (in this case any message not sent to your address), add not to the beginning of the criteria. As many emails are sent to more than one address, the filter uses :contains so that all “To:”, “Copy to:” or “Hidden copy to:” (to, cc, bcc) do not have to match exactly.
# if this email is not addressed to me or if the subject contains “free money” “Nigerian
# prince” put it in spam
elsif anyof (not address :all :contains [“To”, “Cc”, “Bcc”] “myemailaddress@example.com”,
The next criterion will search for keywords in the subject line. This time you'll use the :matches comparator. This is quite similar to :contains, but allows you to include wildcards. The wildcard * means that anything can replace this character. So *free money* looks for any combination of characters as long as “free money” appears somewhere in the text. The script with this criterion looks like this:
# if this email is not addressed to me or if the subject contains “free money” “Nigerian
# prince” put it in spam.
elsif anyof (not address :all :contains [“To”, “Cc”, “Bcc”] “myemailaddress@example.com”,
header :matches “Subject” [“\*free money\*”, “\*Nigerian Prince\*”]) {
The final step in this filter is to use fileinto to send these emails to the spam directory. With this part added, the script looks like this
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
}
# Emails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
fileinto “INBOX/mailinglist”;
}
# if this email isn't addressed to me or if the subject contains “free money” “Nigerian
# prince” put it in spam.
elsif anyof (not address :all :contains [“To”, “Cc”, “Bcc”] “myemailaddress@example.com”,
header :matches “Subject” [“\*free money\*”, “\*Nigerian Prince\*”]) {
fileinto “INBOX/spam”;
Send remaining emails to a directory
For the last command in the filter, we're going to send all emails that don't match any of the defined criteria to an “atrier” directory. Note that this is not a mandatory part of a SIEVE script. SIEVE basically considers that all emails that are not “intercepted” by a filter should simply remain in the inbox. This filter is just to show you how to deal with messages remaining after filtering.
# Put the remaining emails in a directory so that I can sort them later.
else {
fileinto “INBOX/sort”;
}
With this last command, our script is now finalized.
# my SIEVE filter
# List of extensions used by the script
require [“fileinto”, “reject”];
# Messages larger than 2 MB will be rejected with an error message
if size :over 2000K {
reject “I cannot accept messages larger than 2 MB”;
}
# Emails from or to “mailinglist@example.com will go to ‘Mailinglist’.
elsif address :is [“From”, “To”] “mailinglist@example.com”
fileinto “INBOX/mailinglist”;
}
# if this email isn't addressed to me or if the subject contains “free money” “Nigerian
# prince” put it in spam.
elsif anyof (not address :all :contains [“To”, “Cc”, “Bcc”] “myemailaddress@example.com”,
header :matches “Subject” [“\*free money\*”, “\*Nigerian Prince\*”]) {
fileinto “INBOX/spam”;
# Put the remaining mails in a directory for me to sort later.
else {
fileinto “INBOX/sort”;
}
By now, you should have grasped the basic principle of a SIEVE script and its components. Remember that a SIEVE script is flexible and that there are many options available. A list of commands available on Gandi's mail servers is available here :
https://docs.gandi.net/en/gandimail/sieve/sieve_extensions.html
Some examples of filters are also available here:
https://docs.gandi.net/en/gandimail/sieve/sample_filters.html