# Mailbox Refresh (/reference/mailbox-refresh)

Ask for a mail check of your mailboxes now, and follow it until it ends.

## Get mailbox Refresh status

`GET https://api.meetwillow.cx/api/v1/inbox/refresh`

Requires `inbox:refresh` on an API key; a sign-in session or an MCP sign-in is refused with `403` `An API key is required`. tRPC `context.inbox.refreshStatus`, MCP `get_inbox_refresh`.

Reports each reachable mailbox's latest check, and any older check still open, with `retryNotBefore`. Poll every few seconds while a check is `queued` or `running`; it never starts a check. `available` is false when no enabled mailbox you may reach syncs the inbox's folder, so a check would bring nothing in.

### Response

object

- `available` (boolean): Whether a check can bring mail into the inbox: an enabled mailbox you may reach syncs the inbox's folder.
- `unavailableReason` (string or null): Why available is false, or null.
- `checks` (object[]): Each reachable mailbox's latest check, plus any older check still open.
  - `id` (string): The check's id. Repeat calls inside the wait return the same id.
  - `state` (`queued` | `running` | `mapped` | `partial` | `failed`): queued and running are open; mapped means the mailbox's new mail is stored; partial means the check ended before all of it was; failed means it did not run or the mailbox's sync failed.
  - `requestedAt` (string): When the check was first asked for.
  - `reason` (`scope` | `incomplete` | `sync_failed` | `expired` | `trigger_failed` or null): Why a check ended partial or failed: scope (the mailbox's sync leaves out the inbox's folder), incomplete, sync_failed, expired (it waited too long to start) or trigger_failed. Null otherwise.
- `retryNotBefore` (string or null): When a new check can start. A call before then joins the open or just-ended checks and starts nothing. Null when there is no check to wait for.

### Errors

`400` Bad request, `401` Unauthorized, `403` Forbidden, `500` Internal server error.

## Refresh mailboxes

`POST https://api.meetwillow.cx/api/v1/inbox/refresh`

Requires `inbox:refresh` on an API key, which includes `inbox:read`; a sign-in session or an MCP sign-in is refused with `403` `An API key is required`. tRPC `context.inbox.refresh` (a mutation), MCP `refresh_inbox`. Only owners and admins can add `inbox:refresh` to a key.

Asks for a mail check of each enabled mailbox the key may reach, the same check a member's Refresh in the inbox starts, and answers at once with the checks; it does not wait for mail. Poll `GET /inbox/refresh` until no check is `queued` or `running`; new support mail then shows in `GET /tickets` and the Needs reply feed once it is classified. Send no body, or `{}`.

- A call while a mailbox's check is open, or within 10 seconds after it ends, joins that check and starts nothing; `retryNotBefore` says when a new check can start. Repeating a call is safe.
- A key limited to some connections checks only their mailboxes. A mailbox with no connection, as on organizations connected before connections existed, is out of every key's reach. `checks` is empty when the key reaches none.
- A check reads the mailbox; it never sends email or changes a message.

After a `500`, read the status before calling again: the check may have started.

### Response

object

- `checks` (object[]): One check per enabled mailbox you may reach, plus any older check still open. Empty when you reach none.
  - `id` (string): The check's id. Repeat calls inside the wait return the same id.
  - `state` (`queued` | `running` | `mapped` | `partial` | `failed`): queued and running are open; mapped means the mailbox's new mail is stored; partial means the check ended before all of it was; failed means it did not run or the mailbox's sync failed.
  - `requestedAt` (string): When the check was first asked for.
- `retryNotBefore` (string or null): When a new check can start. A call before then joins the open or just-ended checks and starts nothing. Null when there is no check to wait for.

### Errors

`400` Bad request, `401` Unauthorized, `403` Forbidden, `415` Unsupported media type, `500` Internal server error.

## Error body

- `code` (string): The error code: BAD_REQUEST or PARSE_ERROR (400), UNAUTHORIZED (401), FORBIDDEN (403), NOT_FOUND (404), UNSUPPORTED_MEDIA_TYPE (415), TOO_MANY_REQUESTS (429) or INTERNAL_SERVER_ERROR (500).
- `message` (string): What went wrong. A 401 does not say which part of the key failed; a 403 names what is missing, such as the permission; every 5xx says Request failed.
- `issues` (object[], optional): For the message Input validation failed, each problem with the input.
