---
title: "openemail drafts"
description: "Every command in this namespace, with its arguments, flags and examples."
url: "https://openemail.uk/docs/cli/reference/drafts"
area: "CLI"
category: "Reference"
---

# openemail drafts

Every command in this namespace, with its arguments, flags and examples.

## Commands

### `openemail drafts list`

List one page of drafts

```bash
openemail drafts list [flags]
```

Returns one page of saved drafts, most recently saved first. A row is only `object` and `id`, so call `get` for recipients, subject and body. A draft is stored as a thread labelled `DRAFT`, so this reads the same index as `threads.list({ folder: 'draft' })`.

`query` takes the same search syntax as `threads.list`. Plain words must all appear and match loosely, ignoring case, accents and separators, against the draft's subject, its sender and the first 4,000 characters of its body with markup stripped, while a quoted phrase is matched as written apart from case and accents, so `"ben jamin"` does not find "Ben-Jamin". Filler words such as `the` or `emails` are dropped when something else is left to search for. Recipients are stored as one list without roles and are not written for a draft, so `to:`, `cc:` and `bcc:` match nothing here. `subject:`, `body:` and `from:` narrow the search, and `after:`, `before:`, `newer_than:` and `older_than:` read the time the draft was last saved, in UTC, with `after:` including the day it names and `before:` excluding it. A draft saved with no subject is stored as `(no subject)`, so `subject:"no subject"` finds it. The drafts folder always applies, so `in:` and folder `is:` operators such as `is:sent` cannot widen the search beyond drafts, `in:anywhere` included.

The API pages with an opaque `pageToken`, which the SDK hands back as `nextCursor` and accepts as `--cursor`. A page holds 25 drafts unless `--limit` says otherwise.

Add `--all` to walk every page: a table on a terminal, one JSON object per line when piped or with `--ndjson`, and one `{ items, hasMore, nextCursor }` document with `--json`. `--max <n>` stops after that many items.

- Scopes: `drafts:read`.
- Needs a sign-in.
- Aliases: `ls`.

**Flags**

- `--query <value>`: Mailbox search over the subject, sender and body preview. Plain words must all appear and match loosely, a quoted phrase has to appear as written, filler words are dropped when something else is left to search for, and operators such as `subject:` and `older_than:30d` narrow it. `to:`, `cc:` and `bcc:` match nothing on a draft, and the search cannot leave drafts.
- `--limit <n>`: Drafts per page, a whole number from 1 to 100. Defaults to 25.
- `--cursor <value>`: The `nextCursor` of the previous page, passed back unchanged.
- `--all`: Fetch every page and stream the items as they arrive.
- `--max <n>`: Stop after this many items. Implies `--all`.
- `--ndjson`: Print every item as one JSON object per line. Implies `--all`

**Examples**

```bash
openemail drafts list
```

With optional flags

```bash
openemail drafts list --query subject:proposal --limit 20
```

Walk every page and stop after 100 items

```bash
openemail drafts list --all --max 100
```

One JSON object per line when piped

```bash
openemail drafts list --all > drafts.ndjson
```

Also available in: API [`GET /drafts`](https://openemail.uk/docs/api/reference/drafts#get-drafts); SDK [`drafts.list()`](https://openemail.uk/docs/sdk/reference/drafts#list).

### `openemail drafts get`

Read a draft's recipients, subject and body

```bash
openemail drafts get <id> [flags]
```

Returns the fields a draft was saved with: `to`, `cc`, `bcc`, `subject`, the body as `html`, the `from` address, the `threadId` it replies to and its attachment list. The id must belong to a thread labelled `DRAFT`, so an ordinary thread id is a 404 here even though `threads.get` opens it.

Values come back normalised rather than as sent. Recipients are bare addresses with display names dropped, an empty subject reads as `(no subject)`, and `from` is the address the draft was saved with. It is reported only while the workspace can still send as the stored sender, so a draft saved from an address that has since gone reads `from: null`, as does a draft saved without a sender. A draft saved with `text` and no `html` returns that text in `html`, unconverted.

`threadId` is null for a draft that does not reply to anything. `attachments` carries only `filename` and `contentType`, because draft attachments are stored as names and types without content.

- Scopes: `drafts:read`.
- Needs a sign-in.
- Aliases: `show`, `view`.

**Arguments**

- `<id>` (required): Draft id, which starts with `draft-`.

**Examples**

```bash
openemail drafts get draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8
```

Print the raw JSON

```bash
openemail drafts get draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --json
```

Also available in: API [`GET /drafts/{id}`](https://openemail.uk/docs/api/reference/drafts#get-drafts-id); SDK [`drafts.get()`](https://openemail.uk/docs/sdk/reference/drafts#get).

### `openemail drafts create`

Save a new draft

```bash
openemail drafts create [flags]
```

Saves an unsent message to the mailbox and returns its id. Every field is optional, so an empty object saves a blank draft. The body is strict: any key outside the fields below is a 422 `invalid_parameter`, and there is no field for attachments.

Nothing is validated beyond length. Addresses in `to`, `cc` and `bcc` may carry a display name, as in `Ada Lovelace <ada@acme.com>`, and `from` is stored as given. A draft saved without `from` has no sender, and `get` reads `from` back as null. `subject` is capped at 998 characters, and `html` and `text` at 1,000,000 each. When both bodies are sent only `html` is kept.

`--thread-id` records the conversation the draft replies to, but the draft is stored as a thread of its own under its new id. It shows up in `threads.list({ folder: 'draft' })`, not inside the original thread.

- Scopes: `drafts:write`.
- Needs a sign-in.
- Aliases: `new`, `add`.

**Flags**

- `--to <a,b>` (repeatable): Recipient addresses, bare or with a display name.
- `--cc <a,b>` (repeatable): Copy recipients, bare or with a display name.
- `--bcc <a,b>` (repeatable): Blind copy recipients, bare or with a display name.
- `--subject <value>`: At most 998 characters. Empty is stored as `(no subject)`.
- `--html <value>`: Body markup, at most 1,000,000 characters. Kept over `text` when both are set.
- `--text <value>`: Body used only when `html` is absent, at most 1,000,000 characters. Stored as is and read back in `html`.
- `--from <value>`: Sender address, optionally with a display name. Left out, the draft is saved with no sender.
- `--thread-id <value>`: Id of the thread this draft replies to.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

```bash
openemail drafts create
```

With optional flags

```bash
openemail drafts create --to grace@example.com --subject 'Engine notes for Thursday' --html '<p>Agenda below, comments welcome.</p>'
```

Also available in: API [`POST /drafts`](https://openemail.uk/docs/api/reference/drafts#post-drafts); SDK [`drafts.create()`](https://openemail.uk/docs/sdk/reference/drafts#create).

### `openemail drafts update`

Change fields on a saved draft

```bash
openemail drafts update <id> [flags]
```

A partial update: each field you send replaces the stored value and each field you leave out keeps it. Arrays replace wholesale, so sending `to` with one address drops the rest. The limits and the strict body are the same as `create`.

The draft must already exist. An unknown id, or the id of a thread that is not a draft, is a 404 rather than a new draft. The returned `id` is the one to keep using, and it is always the id you passed.

Sending `text` without `html` replaces the stored body with that text. An update also empties the draft's attachment list, because draft attachments are stored as names and types without content and only entries with content are carried over.

- Scopes: `drafts:write`.
- Needs a sign-in.
- Aliases: `edit`.

**Arguments**

- `<id>` (required): Draft id, which starts with `draft-`.

**Flags**

- `--to <a,b>` (repeatable): Replacement recipients. An empty array clears them.
- `--cc <a,b>` (repeatable): Replacement copy recipients.
- `--bcc <a,b>` (repeatable): Replacement blind copy recipients.
- `--subject <value>`: Replacement subject, at most 998 characters.
- `--html <value>`: Replacement body markup, at most 1,000,000 characters.
- `--text <value>`: Replacement body used only when `html` is absent.
- `--from <value>`: Replacement sender. An empty string clears it, leaving the draft with no sender.
- `--thread-id <value>`: Thread the draft replies to. An empty string detaches it.
- `--data <json|@file|->`: The whole `body` as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

**Examples**

With optional flags

```bash
openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --to grace@example.com,charles@example.com --subject 'Engine notes for Thursday, revised'
```

Print the raw JSON

```bash
openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --to grace@example.com,charles@example.com --subject 'Engine notes for Thursday, revised' --json
```

Also available in: API [`PATCH /drafts/{id}`](https://openemail.uk/docs/api/reference/drafts#patch-drafts-id); SDK [`drafts.update()`](https://openemail.uk/docs/sdk/reference/drafts#update).

### `openemail drafts delete`

Delete a draft permanently

```bash
openemail drafts delete <id> [flags]
```

Removes the draft, its stored body and its attachment entries from the mailbox. It does not go to the Bin and there is no undo.

The id must belong to a thread carrying the `DRAFT` label, so an ordinary thread id is a 404. Use `threads.trash` to remove real mail.

- Scopes: `drafts:write`.
- Needs a sign-in.
- Asks you to confirm.
- Aliases: `rm`, `del`, `remove`.

**Arguments**

- `<id>` (required): Draft id, which starts with `draft-`.

**Examples**

```bash
openemail drafts delete draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8
```

Skip the confirmation, for scripts

```bash
openemail drafts delete draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --yes
```

Also available in: API [`DELETE /drafts/{id}`](https://openemail.uk/docs/api/reference/drafts#delete-drafts-id); SDK [`drafts.delete()`](https://openemail.uk/docs/sdk/reference/drafts#delete).
