# Update read or starred state

Source: https://docs.maylee.app/api-reference/emails/update-email

`PATCH https://api.maylee.app/api/v1/emails/{emailId}`

Scope: `write`.

Provide at least one of `isRead` or `isStarred`. A body with neither is rejected rather than silently ignored.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `emailId` | path | string | yes |  |

## Request body

`application/json`, optional.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `isRead` | boolean | no |  |
| `isStarred` | boolean | no |  |

## Example request

```bash
curl -X PATCH "https://api.maylee.app/api/v1/emails/<emailId>" \
  -H "Authorization: Bearer $MAYLEE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "isRead": true
}'
```

## Responses

### 200

The updated email.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | Email | yes | One email or draft with its metadata, without its body (see `GET /emails/{emailId}/body`). Maylee labels are not included: they are the `tags` of list items. |
| `email.attachments` | array of Attachment | no | Metadata only. |
| `email.bcc` | array of EmailAddress | no | Present here, absent from list items. |
| `email.cc` | array of EmailAddress | no |  |
| `email.date` | string (date-time) | no |  |
| `email.folderId` | string | no | Folder the email lives in. |
| `email.from` | EmailAddress | no |  |
| `email.hasAttachments` | boolean | no |  |
| `email.id` | string | no | Maylee id of the email. |
| `email.inReplyTo` | string or null | no | RFC `In-Reply-To` header. |
| `email.isAutoForward` | boolean | no | Sent automatically by an auto-forward rule. |
| `email.isAutoReply` | boolean | no | Sent automatically by Maylee's auto-reply. |
| `email.isDraft` | boolean | no |  |
| `email.isRead` | boolean | no |  |
| `email.isStarred` | boolean | no |  |
| `email.labels` | array of string | no | Labels as known by the provider (for example Gmail's `INBOX` or `IMPORTANT`), not Maylee labels. |
| `email.mailboxId` | string | no | Mailbox the email lives in. |
| `email.messageId` | string | no | RFC `Message-ID` header. Needed to reply in the thread. |
| `email.references` | array of string | no | RFC `References` header. |
| `email.scheduledSendAt` | string (date-time) or null | no | For a scheduled draft: when it will be sent. `null` otherwise. |
| `email.scheduledStatus` | string or null | no | For a scheduled draft: its sending state. `null` otherwise. |
| `email.snippet` | string | no | Short text preview. |
| `email.subject` | string | no |  |
| `email.threadId` | string or null | no | Provider conversation id, when the provider has one. |
| `email.to` | array of EmailAddress | no |  |
| `email.waitingForReply` | boolean | no | On an email you sent: Maylee estimates that it still expects an answer. |

```json
{
  "email": {
    "attachments": [
      {
        "filename": "brief.pdf",
        "mimeType": "application/pdf",
        "size": 48213
      }
    ],
    "bcc": [],
    "cc": [],
    "date": "2026-08-25T13:47:02.000Z",
    "folderId": "cmfd1a2b3c4d5e6f7g8h9i0j",
    "from": {
      "email": "client@acme.com",
      "name": "Jane Client"
    },
    "hasAttachments": true,
    "id": "cmemx1a2b3c4d5e6f7g8h9i0",
    "inReplyTo": null,
    "isAutoForward": false,
    "isAutoReply": false,
    "isDraft": false,
    "isRead": false,
    "isStarred": false,
    "labels": [
      "INBOX",
      "IMPORTANT"
    ],
    "mailboxId": "cmbx1a2b3c4d5e6f7g8h9i0j",
    "messageId": "<CAF3k9x1@mail.example.com>",
    "references": [],
    "scheduledSendAt": null,
    "scheduledStatus": null,
    "snippet": "Hello, could you send us a quote for the annual plan?",
    "subject": "Quote request",
    "threadId": "18c2f5a9e7b1d3c4",
    "to": [
      {
        "email": "contact@your-company.com",
        "name": null
      }
    ],
    "waitingForReply": false
  }
}
```

### 400

Neither field provided.

### 401

Missing, malformed, revoked or expired API key.

### 403

Key lacks the required scope, or outbound sending is not enabled on it.

### 404

Not found, or belongs to another workspace.

### 429

Per-minute rate limit (`RATE_LIMIT_EXCEEDED`) or monthly quota (`QUOTA_EXCEEDED`) exhausted.

Errors use the format `{ "code", "error", "details" }`: see [Errors](/errors.md).
