TYPES: d = dict l = list s = string i = int b = binary (True/False) o = object - pkey's dict key is the 40-char key ID of the primary key - "==>" indicates the next item is a dict and the current item may contain one or more elements of the same format, "++>" is a list, "-->" is a "flat" item (string, object, int, etc.) -"status" is one of "an UPGRADE", "a DOWNGRADE", or "a NEW TRUST". keys(d) ==> (40-char key ID)(s) ==> pkey(d) --> email(s) --> name(s) --> creation (o, datetime) --> key(o, gpg) --> trust(i) --> check(i) --> local(b) --> notify(b) ==> subkeys(d) ==> (40-char key ID)(s) --> creation --> change(b) --> sign(b) --> status(s) ==> uids(d) ==> email(s) --> name(s) --> comment(s) --> email(s) --> updated(o, datetime)* * For many keys, this is unset. In-code, this is represented by having a timestamp of 0, or a datetime object matching UNIX epoch. This is converted to a string, "Never/unknown". for email templates, they are looped over for each key dict as "key". so for example, instead of specifying "keys['748231EBCBD808A14F5E85D28C004C2F93481F6B']['pkey']['name']", you instead should specify "key['pkey']['name']". To get the name of e.g. the second uid, you'd use "key['uids'][(uid email)]['name']. e.g. in the code, it's this: {'748231EBCBD808A14F5E85D28C004C2F93481F6B': {'change': None, 'check': 0, 'local': False, 'notify': True, 'pkey': {'creation': '2013-12-10 ' '08:35:52', 'email': 'brent.saner@gmail.com', 'key': '', 'name': 'Brent Timothy ' 'Saner'}, 'sign': True, 'status': None, 'subkeys': {'748231EBCBD808A14F5E85D28C004C2F93481F6B': '2013-12-10 ' '08:35:52'}, 'trust': 2, 'uids': {'brent.saner@gmail.com': {'comment': '', 'name': 'Brent ' 'Timothy ' 'Saner', 'updated': 'Never/unknown'}, 'bts@square-r00t.net': {'comment': 'http://www.square-r00t.net', 'name': 'Brent ' 'S.', 'updated': 'Never/unknown'}, 'r00t@sysadministrivia.com': {'comment': 'https://sysadministrivia.com', 'name': 'r00t^2', 'updated': 'Never/unknown'}, 'squarer00t@keybase.io': {'comment': '', 'name': 'keybase.io/squarer00t', 'updated': 'Never/unknown'}}}} but this is passed to the email template as: {'change': None, 'check': 0, 'local': False, 'notify': True, 'pkey': {'creation': '2013-12-10 08:35:52', 'email': 'brent.saner@gmail.com', 'key': '', 'name': 'Brent Timothy Saner'}, 'sign': True, 'status': None, 'subkeys': {'748231EBCBD808A14F5E85D28C004C2F93481F6B': '2013-12-10 08:35:52'}, 'trust': 2, 'uids': {'brent.saner@gmail.com': {'comment': '', 'name': 'Brent Timothy Saner', 'updated': '1970-01-01 00:00:00'}, 'bts@square-r00t.net': {'comment': 'http://www.square-r00t.net', 'name': 'Brent S.', 'updated': 'Never/unknown'}, 'r00t@sysadministrivia.com': {'comment': 'https://sysadministrivia.com', 'name': 'r00t^2', 'updated': 'Never/unknown'}, 'squarer00t@keybase.io': {'comment': '', 'name': 'keybase.io/squarer00t', 'updated': 'Never/unknown'}}} (because the emails are iterated through the keys). the same structure is available via the "mykey" dictionary (e.g. to get the key ID of *your* key, you can use "mykey['subkeys'][0][0]"): {'change': False, 'check': None, 'local': False, 'notify': False, 'pkey': {'creation': '2017-09-07 20:54:31', 'email': 'test@test.com', 'key': '', 'name': 'test user'}, 'sign': False, 'status': None, 'subkeys': {'1CD9200637EC587D1F8EB94198748C2879CCE88D': '2017-09-07 20:54:31', '2805EC3D90E2229795AFB73FF85BC40E6E17F339': '2017-09-07 20:54:31'}, 'trust': 'ultimate', 'uids': {'test@test.com': {'comment': 'this is a testing junk key. DO NOT ' 'IMPORT/SIGN/TRUST.', 'name': 'test user', 'updated': 'Never/unknown'}}} you also have the following variables/lists/etc. available for templates (via the Jinja2 templating syntax[0]): - "keyservers", a list of keyservers set. [0] http://jinja.pocoo.org/docs/2.9/templates/