Skip to main content
Edits a draft that has not been sent. Omitted fields keep their staged values; a supplied field replaces it; an empty recipient array clears that field. The draft id stays the same, and the previous version is not recoverable. JMAP makes a message’s content immutable — only its keywords and folder membership can be patched — so editing a draft means writing a new message and retiring the old one. The new message is written first and the old one retired only once it exists, so a rejected write (a quota error, say) leaves the original intact rather than losing the content. Each new message carries the draft’s id as a keyword, so the draftId create_draft returned keeps naming the current version in get_draft, update_draft, and send_draft. A draft staged by another mail client gets a draft id on its first edit; the result says so, and that id is the one to use from then on. On a reply, text and html are the new part only. The original is quoted below them again, the way create_draft quotes it, when the staged draft carried the quote. quoteOriginal: false drops the quote; quoteOriginal: true adds one to a bare reply. An edit that rewrites the body and also adds a recipient the original was never addressed to leaves the quote off unless quoteOriginal: true is passed, as create_draft does — re-attaching it would forward the original to them. An edit that only changes the recipients leaves the body, quote included, as it is; when it adds such a recipient and the original can still be read, the result says the quoted text now goes to them, and either dropping that recipient again or passing your own wording again — without the quoted part — with quoteOriginal: false takes it off. The same note comes back when the text an edit passes already carries the quote. Labels the user put on the draft are carried onto the replacement, so an edit does not quietly untag it. The sender and the reply threading are not editable here. Changing who a message is from, or which conversation it belongs to, makes it a different message — stage that with create_draft.

Parameters

string
required
The draft to edit, as returned by create_draft — edits do not change it — or a message id from search_emails with mailbox: "Drafts". Editing a draft found that way returns the draftId to use from then on.
string[]
Replace the recipients. Omit to keep them; pass [] to clear them. Bare address or Name <address> form.
string[]
Replace the carbon-copy recipients, same rules as to.
string[]
Replace the blind-copy recipients, same rules as to.
string
Replace the subject. Omit to keep it.
string
Replace the plain-text body. Omit to keep it. On a reply, write only the new part — the quoted original is re-attached below it, so do not paste the quote from get_draft back in. If the draft has both a plain-text and an HTML body, pass both or neither — see the note below.
string
Replace the HTML body. Omit to keep it. On a reply, write only the new part, as for text. If the draft has both bodies, pass both or neither.
boolean
On a reply, together with text or html: whether the original is quoted below the new text. Defaults to what the staged draft does. false drops the quote, true adds it to a bare reply. Passing it without text or html is refused.
object[]
Replace the attached files, same entry shape as create_draft: blobId or base64 content. filename is required with blobId — a blob carries no name of its own, and the one get_draft lists beside it is the one to pass — and optional but worth setting with content. mimeType is guessed from the filename’s extension when omitted.Omit to keep the files already attached — the rewrite re-references their blobs, so this transfers nothing. Pass [] to remove them all. Supplying a list replaces the whole thing, so to add a file, read the existing blobIds back with get_draft and list them alongside the new one.

Example

Call
Result

Notes

  • A draft with both bodies must have both replaced at once. Replacing only text on a text+HTML draft is refused, because mail clients render the HTML alternative: the tool would report the corrected body and deliver the old one.
  • A draft whose body is too large to read back in full is refused rather than edited, since re-staging a truncated read would silently amputate the message.
  • Attached files survive an edit that never mentions them. The rewrite re-references the blobs the draft already points at, so keeping them transfers nothing. Supplying attachments replaces the whole list instead — to add one more file, read the existing blobIds back with get_draft and list them alongside the new one; an empty array removes them all.
  • An attachment that cannot be re-referenced blocks the edit. A stored part with no blobId could not be carried onto the replacement, and the original is destroyed on the way, so the loss would be permanent and reported as a success. Such a draft is left unchanged — edit it in Langmail, or pass attachments explicitly to say what the edited draft should carry.
  • An edit that changes nothing is refused too: replacing a draft for no change would run the rewrite’s failure modes for no benefit.
  • A quote in another client’s format goes with the old wording. Only the quote Langmail writes is recognised; the result carries a note when a different one was replaced, and quoteOriginal: true quotes the original anew.
  • If the message a reply answers can no longer be found, the edit goes ahead without the quote and the result says so.

Errors

  • Draft not found: <id>. Find it with search_emails using mailbox "Drafts".
  • <id> is not a draft — it has already been sent or received, and cannot be edited.
  • Not a valid email address: … — a replacement recipient was malformed. Nothing was changed.
  • This draft has both a plain-text and an HTML body, and only \text` was given…` — pass both, or stage a fresh draft.
  • Draft <id> has a body too large to edit without risking losing part of it…
  • Draft <id> carries a file this tool cannot carry across an edit (<names>), so it was left unchanged.
  • The server refused this draft (invalidProperties). — most often an attachment blobId the server does not recognise; blobIds belong to one account and do not outlive the message they were read from. The draft is left unchanged.
  • No changes were given, so draft <id> was left exactly as it is.
  • `quoteOriginal` only applies together with a new `text` or `html` — nothing was changed.
  • Note: the pre-edit copy (message <id>) could not be removed and is still in Drafts… — appended to a successful result when the replacement landed but the superseded message couldn’t be retired. The draft id is taken off the old copy, so it names only the edited version, which is what send_draft with the draft id sends; the old copy should be removed with trash_emails once the user agrees.