diff --git a/reaction-mailcreate/createMails.py b/reaction-mailcreate/createMails.py
index 966ab9f1f4cf5db9d16b93e5e3453cb296131dba..97d87aebdedf4197d5aeb5f48826e89896341b81 100755
--- a/reaction-mailcreate/createMails.py
+++ b/reaction-mailcreate/createMails.py
@@ -52,7 +52,7 @@ parser.add_argument('-f', '--from',       dest='sender',     default='Nobody <no
 parser.add_argument('-F', '--force',      dest='force',      default=False, action='store_true', help='force insecure login without TLS/SSL (default: False)')
 parser.add_argument('-H', '--hashstring', dest='hashstring', default='{salt}{campaign}{infix}-{site}', help='string to be hashed for the URL (default: "{salt}{campaign}{infix}-{site}" where "{salt}" is a random string)')
 parser.add_argument('-i', '--input',      dest='input',      default='{basedir}/{campaign}/Input{infix}.lst', help='input file (default: "{basedir}/{campaign}/Input{infix}.lst")')
-parser.add_argument('-o', '--output',     dest='output',     default='{basedir}/{campaign}/{site}/Mail{infix}.eml', help='output file name template (default: "{basedir}/{campaign}/{site}/Mail{infix}.eml")')
+parser.add_argument('-o', '--output',     dest='output',     default='{basedir}/{campaign}/{site}/{timestamp}{infix}.eml', help='output file name template (default: "{basedir}/{campaign}/{site}/{timestamp}{infix}.eml")')
 parser.add_argument('-R', '--reply-to',   dest='replyto',    default=None, help='reply-to mail address (default: None)')
 parser.add_argument(      '--salt',       dest='salt',       default=None, help='salt to use for hashing (default: random 8-byte hex string)')
 parser.add_argument(      '--sign',       dest='sign',       default='', choices=['', 'gpg', 'gpgsm', 'openssl'], help='signature method (one of "", "gpg", "gpgsm", "openssl"; default: "")')
@@ -64,6 +64,7 @@ parser.add_argument(      '--smtpuser',   dest='smtpuser',   default=None, help=
 parser.add_argument(      '--smtppass',   dest='smtppass',   default=None, help='SMTP password to login with (default: none); implies TLS (port 465) unless STARTTLS is set as well; will be queried interactively if set to "-"')
 parser.add_argument(      '--starttls',   dest='starttls',   default=False, action='store_true', help='login using STARTTLS (default: False); implies port 587')
 parser.add_argument('-t', '--template',   dest='template',   default='{basedir}/{campaign}/Mail.template', help='mail template file (default: "{basedir}/{campaign}/Mail.template")')
+parser.add_argument(      '--timestamp',  dest='timestamp',  default='%Y-%m-%dT%H:%M:%SZ', help='timestamp format used for {timestamp} keyword (default: "%Y-%m-%dT%H:%M:%SZ")')
 parser.add_argument('-T', '--to',         dest='to',         default='{firstname} {lastname} <{email}>', help='recipient mail address (default: "{firstname} {lastname} <{email}>")')
 parser.add_argument('-u', '--url',        dest='url',        default='{webserver}/{campaign}{infix}-{hash}', help='URL template to use (default: "{webserver}/{campaign}{infix}-{hash}"')
 parser.add_argument('-U', '--createurl',  dest='createurl',  default='{webserver}/{campaign}{infix}-{hash}/create', help='URL template to use for creation URL (default: "{webserver}/{campaign}{infix}-{hash}/create"')
@@ -167,6 +168,7 @@ if args.verbose:
         print(f'Using no signature method.')
     print(f'Using "{args.subject.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as mail subject.')
     print(f'Using "{args.template.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as template file.')
+    print(f'Using "{args.timestamp.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as timestamp format.')
     print(f'Using "{args.to.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as recipient mail address.')
     print(f'Using "{args.url.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as URL template.')
     print(f'Using "{args.createurl.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))}" as URL template.')
@@ -247,7 +249,7 @@ def signMail(message):
 
 # Assemble and send the actual mail
 def createMail(data):
-    output = args.output.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
+    output = args.output.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
     directory = os.path.dirname(output)
 
     # Generate email body and attachments
@@ -261,15 +263,15 @@ def createMail(data):
     message = signMail(message)
 
     message['Date'] = formatdate(localtime=True)
-    message['Subject'] = args.subject.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
-    message['From'] = args.sender.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
+    message['Subject'] = args.subject.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
+    message['From'] = args.sender.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
     if args.replyto:
-        message['Reply-To'] = args.replyto.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
-    message['To'] = args.to.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
+        message['Reply-To'] = args.replyto.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
+    message['To'] = args.to.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
     if args.cc:
-        message['Cc'] = ', '.join(args.cc).format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
+        message['Cc'] = ', '.join(args.cc).format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
     if args.bcc:
-        message['Bcc'] = ', '.join(args.bcc).format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL']))
+        message['Bcc'] = ', '.join(args.bcc).format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash'], URL=data['URL'], timestamp=data['timestamp']))
 
     # Record mail
     print(f'Writing mail to {output}')
@@ -307,11 +309,12 @@ def createMail(data):
             requests.get(f'{data["CreateURL"]}')
 
 
-# Generate hash, URL, and CreateURL
-def generateHashAndURL(data):
+# Generate site-specific data: hash, URL, CreateURL, timestamp
+def generateIndividualData(data):
     data['hash'] = hashlib.sha256(args.hashstring.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'])).encode('utf-8')).hexdigest()
     data['URL'] = args.url.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash']))
     data['CreateURL'] = args.createurl.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt, site=data['site'], firstname=data['firstname'], lastname=data['lastname'], email=data['email'], hash=data['hash']))
+    data['timestamp'] = datetime.datetime.now(datetime.UTC).strftime(args.timestamp)
 
 
 # Main loop
@@ -322,5 +325,5 @@ with open(args.input.format_map(SafeDict(basedir=args.basedir, campaign=args.cam
            (row['firstname'] != 'firstname') or \
            (row['lastname'] != 'lastname') or \
            (row['email'] != 'email'):
-            generateHashAndURL(row)
+            generateIndividualData(row)
             createMail(row)