# Drafts

Create, list, read, update, send and delete drafts, each backed by a DRAFT message that a send turns into a SENT one.

A draft is a message labeled `DRAFT` with an id of its own, so you can build a compose-and-send flow against it. Create a draft, replace its message, send it and watch it disappear:

```bash
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"gmail_busy_inbox"}' -o /dev/null
G=(-H 'Authorization: Bearer ya29.placeholder')
RAW=$(printf 'From: ada.lovelace@example.com\r\nTo: marcus.bell@northwind.example\r\nSubject: Draft one\r\n\r\nWork in progress.\r\n' | base64 | tr '+/' '-_' | tr -d '\n')
RAW2=$(printf 'From: ada.lovelace@example.com\r\nTo: marcus.bell@northwind.example\r\nSubject: Draft two\r\n\r\nReady.\r\n' | base64 | tr '+/' '-_' | tr -d '\n')
curl -s "$RYSTIC_URL/gmail/v1/users/me/drafts" "${G[@]}" -H 'Content-Type: application/json' -d "{\"message\":{\"raw\":\"$RAW\"}}" | jq -c '{id, labelIds: .message.labelIds}'
# -> {"id":"r7000000000000000001","labelIds":["DRAFT"]}
curl -s -X PUT "$RYSTIC_URL/gmail/v1/users/me/drafts/r7000000000000000001" "${G[@]}" -H 'Content-Type: application/json' -d "{\"message\":{\"raw\":\"$RAW2\"}}" | jq -c '{id}'
# -> {"id":"r7000000000000000001"}
curl -s "$RYSTIC_URL/gmail/v1/users/me/drafts/r7000000000000000001" "${G[@]}" | jq -c '{id, snippet: .message.snippet}'
# -> {"id":"r7000000000000000001","snippet":"Ready."}
curl -s "$RYSTIC_URL/gmail/v1/users/me/drafts/send" "${G[@]}" -H 'Content-Type: application/json' -d '{"id":"r7000000000000000001"}' | jq -c '{labelIds}'
# -> {"labelIds":["SENT"]}
curl -s "$RYSTIC_URL/gmail/v1/users/me/drafts/r7000000000000000001" "${G[@]}" | jq -c '.error | {code, status}'
# -> {"code":404,"status":"NOT_FOUND"}
```

### What each call does

| Request | What it does |
|---|---|
| `POST …/drafts` | makes a draft of the message in the body, labeled `DRAFT` |
| `GET …/drafts`, `GET …/drafts/{id}` | lists drafts or reads one |
| `PUT …/drafts/{id}` | replaces the draft's message |
| `DELETE …/drafts/{id}` | removes the draft with its message |
| `POST …/drafts/send` with the draft's `id` | sends it and returns the sent message, labeled `SENT`; reading the draft then returns 404 `notFound` |

A send records an event in the [sent-mail log](https://www.rystic.ai/docs/simulators/gmail/features/sent-mail.md).

### Drafts by upload

Creating, updating and sending a draft also take an upload ([Uploads](https://www.rystic.ai/docs/simulators/gmail/features/uploads.md)). A multipart `drafts.send` carries the draft's `id` in its metadata part. A media `drafts.send` carries none and returns 400 `invalidArgument`, "Invalid draft", as Gmail does.

### The draft bench

`gmail_draft_bench` boots three unsent drafts: an empty compose; a reply inside a live thread that carries an attachment; and one from a second send-as address. Each is backed by its own `DRAFT` message, so a read, update or send has a target without a setup write.

---

Source: https://www.rystic.ai/docs/simulators/gmail/features/drafts · Markdown: https://www.rystic.ai/docs/simulators/gmail/features/drafts.md
