This file describes the schemata used for notmuch's structured output format (currently JSON). []'s indicate lists. List items can be marked with a '?', meaning they are optional; or a '*', meaning there can be zero or more of that item. {}'s indicate an object that maps from field identifiers to values. An object field marked '?' is optional. |'s indicate alternates (e.g., int|string means something can be an int or a string). Common non-terminals -------------------- # Number of seconds since the Epoch unix_time = int # Thread ID, sans "thread:" threadid = string # Message ID, sans "id:" messageid = string notmuch show schema ------------------- # A top-level set of threads (do_show) # Returned by notmuch show without a --part argument thread_set = [thread*] # Top-level messages in a thread (show_messages) thread = [thread_node*] # A message and its replies (show_messages) thread_node = [ message|null, # null if not matched and not --entire-thread [thread_node*] # children of message ] # A message (format_part_json) message = { # (format_message_json) id: messageid, match: bool, filename: string, timestamp: unix_time, # date header as unix time date_relative: string, # user-friendly timestamp tags: [string*], headers: headers, body?: [part] # omitted if --body=false } # A MIME part (format_part_json) part = { id: int|string, # part id (currently DFS part number) encstatus?: encstatus, sigstatus?: sigstatus, content-type: string, content-id?: string, # if content-type starts with "multipart/": content: [part*], # if content-type is "message/rfc822": content: [{headers: headers, body: [part]}], # otherwise (leaf parts): filename?: string, content-charset?: string, # A leaf part's body content is optional, but may be included if # it can be correctly encoded as a string. Consumers should use # this in preference to fetching the part content separately. content?: string, # If a leaf part's body content is not included, the content-length # may be included instead. content-length?: int } # The headers of a message or part (format_headers_json with reply = FALSE) headers = { Subject: string, From: string, To?: string, Cc?: string, Bcc?: string, Date: string } # Encryption status (format_part_json) encstatus = [{status: "good"|"bad"}] # Signature status (format_part_sigstatus_json) sigstatus = [signature*] signature = { # (signature_status_to_string) status: "none"|"good"|"bad"|"error"|"unknown", # if status is "good": fingerprint?: string, created?: unix_time, expires?: unix_time, userid?: string # if status is not "good": keyid?: string # if the signature has errors: errors?: int } notmuch search schema --------------------- # --output=summary summary = [thread*] # --output=threads threads = [threadid*] # --output=messages messages = [messageid*] # --output=files files = [string*] # --output=tags tags = [string*] thread = { thread: threadid, timestamp: unix_time, date_relative: string, # user-friendly timestamp matched: int, # number of matched messages total: int, # total messages in thread authors: string, # comma-separated names with | between # matched and unmatched subject: string, tags: [string*] } notmuch reply schema -------------------- reply = { # The headers of the constructed reply reply-headers: reply_headers, # As in the show format (format_part_json) original: message } # Reply headers (format_headers_json with reply = TRUE) reply_headers = { Subject: string, From: string, To?: string, Cc?: string, Bcc?: string, In-reply-to: string, References: string }