# Gmail changelog

What changed in each Gmail simulator release, newest first.

What changed in each Gmail simulator release, newest first.

## v0.0.5 — 2026-11-06

1. **The docs say what the one mailbox holds.** The limitations list the messages, labels and threads that belong to it.

## v0.0.4 — 2026-11-05

1. **The docs read more plainly, and each difference from Gmail is marked where it's described.** Sentences are shorter, and a "Differs from Gmail" line sits beside each behavior that departs from Gmail, such as the JSON 404 for an unknown path and the upload size cap. Rules with several outcomes, such as the history feed's records and the label conflicts, are tables. The search page lists the query readings not yet checked against Gmail. Sign-in, seeding and reset keep only what is particular to this simulator and link the shared pages for the rest.

## v0.0.3 — 2026-11-05

1. **A slow client no longer holds up the others.** The simulator reads a request's whole body before it starts serving it and sends the answer after, so a client that uploads slowly, or reads a large answer slowly, no longer delays other clients' requests. Answers are unchanged; one larger than 4 MiB still makes other requests wait while it is sent.

2. **The call log shows what each call asked for and whether it succeeded.** Each `GET /_rystic/calls` entry now carries `args`, the call's query and body arguments with credentials redacted (long values cut, file contents left out), and `ok`, false for an answer that is not 2xx. A path the simulator does not serve is marked `unknown_route: true`. `?tail=N` returns only the last N calls, and `dropped` counts the calls the log no longer keeps.

3. **The docs are one page, with a page per feature.** The archive ships `README.md` in place of `HOWTO.md` and `SCENARIOS.md`, with the same sections in the same order as every Rystic simulator's page, and `CHANGELOG.md` beside it. Messages and threads, drafts, labels, search, the history feed, uploads, the mailbox settings and the sent-mail log each have their own page under `docs/features/`, and every example on these pages runs as written against a fresh simulator.

4. **The docs page links the admin token section.** The page now sends you to the admin token's section of the shared-simulators page.

5. **Scenario descriptions use customer terms.** The Scenarios table and `--list-scenarios` describe each scenario in American spelling, with no internal references.

6. **The Scenarios table is easier to scan.** Each row says in a line what the scenario is for, and a list below the table says what each scenario holds.

7. **Pro starts with a 14-day trial.** Free has ended, so every simulator is on Pro and Enterprise, and the docs name only those plans.

8. **Limitations is shorter to read.** It opens with the known issues and one sentence counting the rest. The detailed lists follow, and the website folds them behind "Show all limitations".

9. **The page has no Plans section.** The Quickstart names the plans that run the simulator, and the pricing page lists what each plan includes.

## v0.0.2 — 2026-10-29

1. **Every send records one egress event.** Each send Gmail would deliver, by `messages.send` or `drafts.send` and by JSON or upload, now records one event in `GET /_rystic/egress`: effect `eff_send_mail`, type `message.sent`, with the sent message's `messageId`, `threadId`, `from`, `subject` and `raw`, and its recipients as lists of addresses in `to`, `cc` and `bcc`. A test can assert what an agent sent, and to whom, whichever route it used; `messages.send` as JSON or multipart used to record nothing, and the other routes each recorded their own effect and fields.

## v0.0.1 — 2026-10-25

1. **A local Gmail for your mail clients, sync jobs and the agents that read and send mail.** The first release of the Gmail twin: the Gmail API v1 for one mailbox — messages, threads, drafts, labels, the history feed, search and the mailbox's settings — answered on the `/gmail/v1` and `/upload/gmail/v1` paths of `gmail.googleapis.com` on one port, from a model validated against live Gmail. Point Google's client libraries at it (`HOWTO.md` shows how for Node and Python) or curl it with any bearer token; no Google Cloud project, OAuth client or token is involved, nothing reaches Google, and no message is delivered.

2. **Messages and threads, as Gmail stores them.** `messages.insert`, `import` and `send` take the whole RFC 5322 message as base64url `raw`, and `messages.get` answers it in `format` `full` (the MIME part tree, attachments as `attachmentId`), `metadata`, `minimal` or `raw`, with Gmail's `snippet` and `sizeEstimate`, and `attachments.get` answers an attachment's bytes by that `attachmentId`. A message joins a thread only by the `threadId` you send; `send` labels it `SENT`, and an insert from the mailbox's own address does too. `modify`, `trash`, `untrash`, `delete`, `batchModify` and `batchDelete` change messages, and the threads routes list, read, modify, trash, untrash and delete a whole conversation. An unknown ID answers 404 `notFound` in Gmail's JSON error envelope.

3. **Drafts, and messages sent as uploads.** Drafts are created, listed, read, replaced, sent and deleted; `drafts.send` answers the sent message, labeled `SENT`, and the draft is gone. Insert, import, send and a draft's create and update also take the message itself through `/upload/gmail/v1`, as `uploadType=media` or `multipart`, the way Google's client libraries send a media body.

4. **Labels with live counts, search, the profile and the history feed.** Every mailbox holds Gmail's 14 system labels. Labels are listed, created, read, updated, patched and deleted, and `labels.get` answers `messagesTotal`, `messagesUnread`, `threadsTotal` and `threadsUnread` as soon as a write answers; a name in use answers 409 `aborted`, and deleting a label strips it from every message. `messages.list` and `threads.list` search with `q` — bare words, quoted phrases, `from:`, `to:`, `cc:`, `bcc:`, `subject:`, `label:`, `category:`, `is:`, `in:`, `has:attachment`, `filename:`, `larger:`, `smaller:`, the date operators, `-`, `OR` and `{…}` groups — and leave trash and spam out unless asked. `getProfile` answers the mailbox's address, its live message and thread totals and the `historyId` to poll from, and that address works as `userId` beside `me`. `history.list` lists `messagesAdded`, `messagesDeleted`, `labelsAdded` and `labelsRemoved` after a `startHistoryId`, filtered by `historyTypes` and `labelId`, with no lag.

5. **The mailbox's settings.** Filters are listed, created, read and deleted; IMAP, POP, language and vacation settings are read and replaced whole; auto-forwarding is read; the mailbox's send-as addresses are listed, read, patched and updated, and its forwarding addresses listed and read. An empty filter or forwarding-address list answers 204, as Gmail does, and no auto-reply, forward or filter action ever leaves the twin.

6. **Five mailboxes to boot straight into.** `gmail_busy_inbox` (nine messages in six threads under system and user labels, one with a PDF and a CSV attachment), `gmail_draft_bench` (three drafts, one a reply inside a live thread), `gmail_filter_desk` (four standing filters and the mail they routed), `gmail_vacation_relay` (forwarding and send-as addresses in every verification state) and `gmail_fresh_mailbox` (the 14 system labels and no mail). `--scenario` boots one, `POST /_rystic/scenario` loads one without a restart, and `SCENARIOS.md` describes each. Without one, the twin boots an empty mailbox.

7. **Measured against live Gmail.** The newest full-suite round, of 2026-10-25 (`20261025T212918Z`), matched 635 of 652 probes against live Gmail (97.4%), none inconclusive. `HOWTO.md` states the differences this release ships with: among them, a world's settings read as their defaults, an upload holds at most 1 MiB, `history.list` runs none of its route's refusals, and an imported message joins no thread.

---

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