> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ruber.me/llms.txt
> Use this file to discover all available pages before exploring further.

# List mailboxes

> GET /v1/mailboxes — every mailbox your organization owns, with its mode, status and storage use.

Returns every mailbox your organization owns. This is usually the first call an
integration makes, because every other endpoint takes an address and this is
where the valid ones come from.

```
GET https://app.ruber.me/api/v1/mailboxes
```

**Required permission:** Mailboxes → Read (`mailboxes:read`)

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl https://app.ruber.me/api/v1/mailboxes \
    -H "Authorization: Bearer rk_your_key_here"
  ```

  ```js Node theme={null}
  const response = await fetch("https://app.ruber.me/api/v1/mailboxes", {
    headers: { Authorization: `Bearer ${process.env.RUBER_API_KEY}` },
  });

  const { data } = await response.json();
  ```

  ```python Python theme={null}
  import os, requests

  response = requests.get(
      "https://app.ruber.me/api/v1/mailboxes",
      headers={"Authorization": f"Bearer {os.environ['RUBER_API_KEY']}"},
  )

  data = response.json()["data"]
  ```
</CodeGroup>

This endpoint takes no parameters. It returns every mailbox on the organization
the key belongs to — there is no pagination, because an organization has tens of
mailboxes, not thousands.

## Response

```json theme={null}
{
  "data": [
    {
      "address": "billing@yourdomain.com",
      "display_name": "Billing",
      "mode": "smart",
      "quota_bytes": 10737418240,
      "status": "active",
      "used_bytes": 284119402
    },
    {
      "address": "legal@yourdomain.com",
      "display_name": null,
      "mode": "private",
      "quota_bytes": 10737418240,
      "status": "active",
      "used_bytes": 1048576
    }
  ]
}
```

<ResponseField name="data" type="array">
  Every mailbox the organization owns, sorted by address.

  <Expandable title="properties" defaultOpen>
    <ResponseField name="address" type="string">
      The full email address, always lowercase. This is the value other
      endpoints expect.
    </ResponseField>

    <ResponseField name="display_name" type="string | null">
      The name shown beside the address, or `null` if none was set.
    </ResponseField>

    <ResponseField name="mode" type="string">
      `smart`, `private`, or `migrating_to_private`.

      Only `smart` mailboxes can be read or sent from through the API — see
      [Private mailboxes](/api/introduction#private-mailboxes-are-not-readable).
    </ResponseField>

    <ResponseField name="status" type="string">
      `active`, `provisioning`, or `suspended`.

      Mailboxes that are not active are included on purpose, so you can tell
      "you do not own this" from "you own it and it is not ready" — two very
      different problems.
    </ResponseField>

    <ResponseField name="quota_bytes" type="integer | null">
      The mailbox's storage limit in bytes, or `null` where no limit is set.
    </ResponseField>

    <ResponseField name="used_bytes" type="integer">
      Storage currently used, in bytes.
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  **Both non-active and Private mailboxes are listed.** Filtering them out would
  be worse than including them: an integration would report a mailbox as missing
  when it exists and is simply unreadable, or not ready yet. `mode` and `status`
  tell you which endpoints will accept it.
</Note>

## Errors

| Code             | HTTP  | Cause                                             |
| ---------------- | ----- | ------------------------------------------------- |
| `unauthorized`   | `401` | Missing, malformed, unknown or revoked key.       |
| `forbidden`      | `403` | The key lacks `mailboxes:read`.                   |
| `rate_limited`   | `429` | Over 600 requests in a minute. See `Retry-After`. |
| `internal_error` | `500` | The lookup failed on our side. Safe to retry.     |

A key with no permissions at all — possible only for keys created before
permissions existed — authenticates and then fails here with `forbidden`. The
key list in **Settings → API keys** marks those; revoke and recreate them.

See [Errors](/api/introduction#errors) for the full response shape.
