# CLI
Source: https://docs.getinboxzero.com/api-reference/cli
Use the Inbox Zero API CLI from npm or npx.
Use the Inbox Zero API CLI when you want a thin wrapper around the public API for scripts, bots, or local automation.
The package is published to npm as `@inbox-zero/api`, and the executable name is `inbox-zero-api`.
## Run with npx
Requires Node.js `18+`.
```bash theme={null}
npx @inbox-zero/api --help
```
You can also install it globally:
```bash theme={null}
npm install -g @inbox-zero/api
```
## Configure access
The CLI reads configuration in this order:
1. Command flags
2. Environment variables
3. `~/.inbox-zero-api/config.json`
Supported environment variables:
* `INBOX_ZERO_API_KEY`
* `INBOX_ZERO_BASE_URL` for self-hosted or custom API deployments
Example:
```bash theme={null}
inbox-zero-api rules list
```
`base-url` is optional. The CLI defaults to `https://www.getinboxzero.com` and only needs an override for self-hosted or custom deployments.
Set `INBOX_ZERO_API_KEY` in your shell or secret manager before running commands. Avoid passing API keys as CLI arguments because they can leak into shell history and process listings.
## Common commands
List rules:
```bash theme={null}
inbox-zero-api rules list
inbox-zero-api rules list --json
```
Get a rule:
```bash theme={null}
inbox-zero-api rules get rule_123 --json
```
Create a rule from JSON:
```bash theme={null}
inbox-zero-api rules create --file rule.json
cat rule.json | inbox-zero-api rules create --file -
```
Update a rule from JSON:
```bash theme={null}
cat rule.json | inbox-zero-api rules update rule_123 --file -
```
Delete a rule:
```bash theme={null}
inbox-zero-api rules delete rule_123
```
Read stats:
```bash theme={null}
inbox-zero-api stats by-period --period week --json
inbox-zero-api stats response-time --json
```
Fetch the live OpenAPI document:
```bash theme={null}
inbox-zero-api openapi --json
```
For bots, prefer `--json` so the output is stable and machine-readable.
# Delete rule
Source: https://docs.getinboxzero.com/api-reference/endpoint/delete-rules-id
DELETE /rules/{id}
Delete an automation rule for the scoped inbox account.
# List rules
Source: https://docs.getinboxzero.com/api-reference/endpoint/get-rules
GET /rules
List automation rules for the scoped inbox account.
# Get rule
Source: https://docs.getinboxzero.com/api-reference/endpoint/get-rules-id
GET /rules/{id}
Get a single automation rule for the scoped inbox account.
# Get stats by period
Source: https://docs.getinboxzero.com/api-reference/endpoint/get-statsby-period
GET /stats/by-period
Get email statistics grouped by time period. Returns counts of emails by status (all, sent, read, unread, archived, unarchived) for each period.
# Get stats response time
Source: https://docs.getinboxzero.com/api-reference/endpoint/get-statsresponse-time
GET /stats/response-time
Get email response time statistics. Returns summary stats, distribution, and trend data showing how quickly you respond to emails.
# Create rule
Source: https://docs.getinboxzero.com/api-reference/endpoint/post-rules
POST /rules
Create an automation rule for the scoped inbox account.
# Update rule
Source: https://docs.getinboxzero.com/api-reference/endpoint/put-rules-id
PUT /rules/{id}
Replace an automation rule for the scoped inbox account.
# Introduction
Source: https://docs.getinboxzero.com/api-reference/introduction
Use the Inbox Zero API to read inbox statistics and manage automation rules programmatically.
If you prefer a CLI wrapper for scripts or bots, see the [API CLI](/api-reference/cli).
## Supported Email Providers
Inbox Zero supports integration with:
* **Gmail** (Google Workspace and personal accounts)
* **Outlook** (Microsoft 365 and personal accounts)
## Getting Started
To begin using the Inbox Zero API, you'll need to obtain an API key. Here's how:
1. Log in to your Inbox Zero account
2. Navigate to the [Settings](https://www.getinboxzero.com/settings) page and scroll down to the `API Keys` section
3. Click on the `Create New Secret Key` button
4. Select the permissions (scopes) you need for your key
5. Choose an expiry period
API keys are scoped to a specific inbox account and only grant access to the permissions you select. Keep your key secure and do not share it publicly.
### Permissions
| Scope | Endpoints |
| ------------- | ------------------------------------------------------ |
| `STATS_READ` | `GET /stats/by-period`, `GET /stats/response-time` |
| `RULES_READ` | `GET /rules`, `GET /rules/{id}` |
| `RULES_WRITE` | `POST /rules`, `PUT /rules/{id}`, `DELETE /rules/{id}` |
A key may include more than one scope. Keys are also bound to one inbox account; they cannot read or change another inbox.
### Self-Hosting
If you are self-hosting Inbox Zero, set `NEXT_PUBLIC_EXTERNAL_API_ENABLED=true` and `API_KEY_SALT` before rebuilding the app. Generate the salt with `openssl rand -hex 32`. Use your deployment URL as the base URL for requests (for example, `https://your-domain.com/api/v1`).
## Base URL
All API requests should be made to the following base URL:
```
https://www.getinboxzero.com/api/v1
```
## Authentication
Include your API key in the header of each request:
```
API-Key: YOUR_API_KEY
```
For example:
```bash theme={null}
curl "https://www.getinboxzero.com/api/v1/rules" \
-H "API-Key: YOUR_API_KEY"
```
To create a rule:
```bash theme={null}
curl -X POST "https://www.getinboxzero.com/api/v1/rules" \
-H "API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"name": "Archive newsletters",
"runOnThreads": true,
"condition": {
"aiInstructions": "Newsletters and recurring promotional emails"
},
"actions": [{ "type": "ARCHIVE" }]
}'
```
### Errors
API errors are returned as JSON with an `error` message.
| Status | Meaning |
| ------ | ------------------------------------------------------------------------------------------------------ |
| `400` | Invalid query, path, or request body; an action may also be disabled by the deployment's feature flags |
| `401` | The `API-Key` header is missing, invalid, or expired |
| `403` | The key lacks a required scope or is not account-scoped |
| `404` | The requested rule does not exist in the key's inbox account |
| `500` | An unexpected server error occurred |
The `DELETE` rule action, which moves matching emails to trash, is available only when the deployment enables `NEXT_PUBLIC_DELETE_EMAIL_ACTION_ENABLED`. This feature flag is separate from `DELETE /rules/{id}`, which deletes a rule definition.
## Request New Endpoint
If you have a new endpoint that you would like to add to the API, open an issue on [GitHub](https://github.com/elie222/inbox-zero/issues/new).
# Contributing
Source: https://docs.getinboxzero.com/contributing
Set up Inbox Zero for local development
This guide is for developers who want to run Inbox Zero locally and contribute to the project.
## Prerequisites
* [Node.js](https://nodejs.org/) >= 24.0.0
* [pnpm](https://pnpm.io/) >= 10.0.0
* [Docker Desktop](https://www.docker.com/products/docker-desktop/) (for Postgres and Redis)
## Local Development Setup
### Option A: Devcontainer
The fastest way to get started is using [devcontainers](https://containers.dev/), supported by VS Code ([Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)) and JetBrains IDEs:
1. Open the project and select "Reopen in Container" when prompted
2. Wait for the container to build and `postCreateCommand` to complete
3. Configure at least one OAuth provider in `apps/web/.env` (see [Setup Guides](/hosting/setup-guides))
4. Run `pnpm dev`
### Option B: Manual Setup
1. **Start PostgreSQL and Redis:**
```bash theme={null}
docker compose -f docker-compose.dev.yml up -d
```
2. **Install dependencies:**
```bash theme={null}
pnpm install
```
3. **Optional: start the local Google emulator** if you want to develop against emulated Google OAuth/Gmail instead of real credentials:
```bash theme={null}
docker compose -f docker-compose.dev.yml --profile google-emulator up -d
```
4. **Optional: start the local Microsoft emulator** if you want to develop against emulated Microsoft OAuth/Graph instead of real credentials:
```bash theme={null}
docker compose -f docker-compose.dev.yml --profile microsoft-emulator up -d
```
5. **Set up environment variables** using one of these methods:
**Interactive CLI** (recommended) - guides you through each step and auto-generates secrets:
```bash theme={null}
pnpm run setup
```
**Manual** - copy the example file and edit it yourself:
```bash theme={null}
cp apps/web/.env.example apps/web/.env
# Generate secrets with: openssl rand -hex 32
```
To use the local Google emulator, set these values in `apps/web/.env`:
```bash theme={null}
GOOGLE_BASE_URL=http://localhost:4002
GOOGLE_CLIENT_ID=emulate-google-client.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=emulate-google-secret
```
To use the local Microsoft emulator, set these values in `apps/web/.env`:
```bash theme={null}
MICROSOFT_BASE_URL=http://localhost:4003
MICROSOFT_CLIENT_ID=emulate-microsoft-client-id
MICROSOFT_CLIENT_SECRET=emulate-microsoft-secret
```
6. **Run database migrations:**
```bash theme={null}
cd apps/web
pnpm prisma migrate dev
```
7. **Start the development server:**
```bash theme={null}
pnpm dev
```
The app will be available at [http://localhost:3000](http://localhost:3000).
## Configuration
You'll need to configure at least one OAuth provider and an AI provider. The setup CLI handles this interactively, but for manual configuration see the [Setup Guides](/hosting/setup-guides):
* [Google OAuth](/hosting/google-oauth)
* [Google PubSub](/hosting/google-pubsub)
* [Microsoft OAuth](/hosting/microsoft-oauth)
* [LLM](/hosting/llm-setup)
## Parallel Branch Development
If you regularly work in multiple Git worktrees or branch-specific local copies, use the dev setup helper instead of reusing a single shared app/database setup.
### Why this helps
* Each branch gets its own local Postgres database, so schema changes on one branch do not break another branch.
* The helper picks a branch-specific app port, which makes it easier to run multiple local copies at once.
* It can start local Postgres and Redis automatically when they are not already running.
* It wires emulator-based Google and Microsoft auth for local development, which is useful when you do not want to depend on real OAuth callbacks during day-to-day work.
### Shared env files
The helper expects shared local env files in `~/.config/inbox-zero` and symlinks them into `apps/web`:
* `~/.config/inbox-zero/.env.local`
* `~/.config/inbox-zero/.env.test`
* `~/.config/inbox-zero/.env.e2e`
This keeps secrets in one place while still letting each branch use its own derived runtime values, such as database name and local port.
### Common commands
Initialize the current branch for local development:
```bash theme={null}
pnpm dev-setup init
```
Start the current branch with the saved local settings:
```bash theme={null}
pnpm dev-setup dev
```
Start with a fresh empty database instead of cloning from the main local database:
```bash theme={null}
pnpm dev-setup init --db empty
```
Run against Conductor's assigned port:
```bash theme={null}
pnpm dev-setup dev --url conductor
```
Drop the branch-local database and remove cached state when you are done:
```bash theme={null}
pnpm dev-setup clean
```
### Recommended usage
* Use `clone-main` mode when you want realistic local data and faster setup.
* Use `empty` mode when you are working on schema changes or want a clean migration path.
* Use emulator auth for most local development.
* Reserve real OAuth flows for cases where you specifically need to test real provider behavior.
## Local Production Build
To test a production build locally:
```bash theme={null}
# Without Docker
pnpm build
pnpm --filter inbox-zero-ai start
# With Docker (includes Postgres and Redis)
NEXT_PUBLIC_BASE_URL=http://localhost:3000 docker compose --profile all up --build
```
## Finding Your Way Around
To understand the codebase, we recommend connecting the repo to an AI coding tool like [Claude Code](https://claude.ai/claude-code) or [Cursor](https://cursor.com/) and asking questions directly. Treat the code, schemas, and tests as the source of truth for how features work.
For troubleshooting common issues (rate limiting, OAuth errors, etc.), see the [Troubleshooting](/hosting/troubleshooting) page.
View open tasks in [GitHub Issues](https://github.com/elie222/inbox-zero/issues) and join the [Discord](https://www.getinboxzero.com/discord) to discuss what's being worked on.
# AI Chat
Source: https://docs.getinboxzero.com/essentials/ai-chat
Manage your inbox through a natural-language conversation.
AI Chat lets you search, understand, and manage your inbox in plain language. Open **Chat** in the left sidebar or visit [AI Chat](https://www.getinboxzero.com/assistant).
## What You Can Do
* **Search and understand email**: Find messages, summarize threads, read supported attachments, and ask what needs your attention.
* **Manage your inbox**: Archive, delete, mark read or unread, label, and unsubscribe from senders.
* **Write email**: Prepare new messages, replies, and forwards. You review and send them from a confirmation card.
* **Manage rules**: Create, update, enable, disable, and troubleshoot automation rules.
* **Configure features**: Update assistant settings and features such as Meeting Briefs and auto-file attachments.
* **Remember preferences**: Ask the assistant to remember information for future chats.
See [AI Personal Assistant](/essentials/email-ai-personal-assistant) for the full rule and action model.
## Images and Attachments
You can attach JPEG, PNG, WebP, or GIF images to a chat message, including by pasting an image. Chat uploads provide context for the conversation; they cannot be attached to an outgoing email.
The assistant can also read supported attachments already present on an email, including PDF, DOCX, plain text, CSV, and HTML files.
## Chat History
Use the history menu in the Chat header to reopen, rename, or delete a previous conversation. Start a new chat when you want a clean conversation context.
## Connected Channels
You can also chat with the assistant from a connected Slack, Microsoft Teams, or Telegram account. Connect and configure these apps on the **Channels** page. See [Slack Integration](/essentials/slack-integration) and [Telegram Integration](/essentials/telegram-integration) for setup details.
## Example Prompts
* "Show me the unread emails that need a reply."
* "Archive these newsletters and unsubscribe me from their senders."
* "Draft a reply to the latest message from Alex."
* "Create a rule that labels receipts and archives them after seven days."
* "Why was this email archived?"
* "Remember that I prefer 30-minute meetings in the afternoon."
# Use Your Own AI API Key
Source: https://docs.getinboxzero.com/essentials/api-keys
Choose an AI provider, model, and provider API key for Inbox Zero features.
Inbox Zero covers AI costs by default, but you can optionally use your own model-provider API key.
This setting is for the AI provider that powers Inbox Zero features. It is different from the developer API keys in the **Developer** settings section, which authenticate requests to the Inbox Zero API.
## Configure a Provider
1. Open the account menu at the bottom of the sidebar and choose **Settings**.
2. Expand the relevant email account.
3. Find the **AI Model** section.
4. Select a provider, enter the provider's model identifier and API key, then click **Save**.
5. Test the configuration on the **Assistant** or **Chat** page.
Leave the provider set to **Default** to use the AI service included with Inbox Zero.
## Providers in Settings
### Anthropic
Create a key in the [Anthropic Console](https://console.anthropic.com/settings/keys). Enter an Anthropic model identifier in the Model field.
### OpenAI
Create a key on the [OpenAI API keys page](https://platform.openai.com/api-keys).
### Azure OpenAI
Use an Azure OpenAI API key and enter the Azure deployment name in the Model field.
### Google
Create a Gemini API key in [Google AI Studio](https://aistudio.google.com/app/apikey) and enter the corresponding model identifier.
### Groq
Create a key in the [Groq Console](https://console.groq.com/keys) and enter a model available to your Groq account.
### OpenRouter
Create a key in [OpenRouter](https://openrouter.ai/settings/keys). Use OpenRouter's provider-qualified model identifier, such as `provider/model`.
### Vercel AI Gateway
Create an AI Gateway API key in Vercel and use the model identifier expected by [Vercel AI Gateway](https://vercel.com/ai-gateway). Provider-qualified identifiers are recommended.
## Usage and Billing
When you use your own provider key, the provider bills that account according to its pricing and limits. Click **View usage** in the AI Model section to review the usage recorded by Inbox Zero. Provider-side billing remains the source of truth for charges.
# Assistant Settings
Source: https://docs.getinboxzero.com/essentials/assistant-settings
Control drafting, reminders, writing style, knowledge, and safety settings for your AI assistant.
Open **Assistant** in the sidebar and select the **Settings** tab to control how the assistant drafts, learns, and notifies you. Settings apply to the currently selected email account, so review them separately when you connect multiple accounts.
## Drafting controls
### Auto draft replies
Enable this to create replies in your Drafts folder for messages that need a response. The assistant does not send these drafts automatically.
### Draft confidence
Choose how certain the assistant must be before it prepares a draft:
* **All emails**: draft whenever an email needs a reply, even when uncertain.
* **Standard**: skip drafting when the assistant is unsure how to respond.
* **High confidence**: draft only when it is very sure of the appropriate reply.
Use a stricter setting when correctness is more important than draft coverage.
## Updates
### Follow-up reminders
Enable reminders for messages where someone has not replied to you or where you have not replied. In **Configure**, set the delays and choose whether the assistant should prepare a follow-up draft.
### Digest
Schedule a daily summary of newsletter emails and choose which rules contribute to it. Digests require the **Plus plan or higher**. You can route a digest to a connected chat provider from [Channels](/essentials/channels).
## Your voice
### Writing style
Describe your typical length, formality, greetings, and other stylistic habits. This guidance is used when drafting replies in your voice.
### Personal instructions
Add stable information about yourself and how you want the assistant to handle email. Keep instructions general and durable; use assistant rules for specific matching conditions and actions.
### Email signature
Configure the signature appended to drafted messages.
## Knowledge and learning
### Draft knowledge base
Store facts that can help the assistant answer recurring questions. This control is available only while auto draft replies are enabled.
### Learned patterns
Inbox Zero learns when senders or email types consistently match the same rule. Open **Learned patterns** to view, edit, or remove those associations. Remove a pattern when it starts routing a sender incorrectly.
## Advanced settings
### Sync to browser extension
Sync label-based assistant rules to the Inbox Zero Tabs extension as Gmail tabs. This requires the configured Inbox Zero Tabs extension and a Chromium browser, and it applies to Gmail rather than Outlook. Select the label rules you want before starting the sync.
### Multi-rule selection
Allow the assistant to select multiple custom rules for one message.
### Include referral signature
Optionally append an Inbox Zero referral link to generated drafts.
### Allow hidden links in AI drafts
This permits anchor text such as “click here” instead of displaying the full URL. It reads more naturally, but it hides where a link leads. Leave it off when transparent links are important.
### Sensitive data protection
Choose how credentials and card numbers are handled before an AI request:
* **Off**: send content without scanning.
* **Redact**: hide detected credentials and card numbers, then send the remaining content to AI.
* **Block**: skip the AI request when sensitive data is detected.
## Troubleshooting
### A setting is missing
Some settings depend on your plan or email provider. Auto-draft controls appear only while auto-drafting is enabled, Digest requires the Plus plan, and extension sync requires the Inbox Zero Tabs extension.
### Drafts do not sound like me
Update **Writing style**, **Personal instructions**, and **Email signature**, then review the Draft knowledge base for stale facts. Editing generated drafts also helps the assistant learn over time.
### Too few or too many drafts are created
Adjust **Draft confidence**. Also review the rules that determine whether a message needs a reply and remove incorrect learned patterns.
### Follow-up reminders are missing
Confirm that at least one reminder delay is set, then run the scan from **Configure**. If reminders should arrive in chat, also verify the route on [Channels](/essentials/channels).
# Auto-File Attachments
Source: https://docs.getinboxzero.com/essentials/auto-file-attachments
Automatically organize email attachments in Google Drive or OneDrive.
Auto-File Attachments keeps your drive organized without you lifting a finger. Incoming email attachments are analyzed and saved to the right folders in Google Drive or Microsoft OneDrive/SharePoint automatically.
## Set Up Auto-Filing
### Connect a Drive
Open **Attachments** in the left sidebar and connect one of the supported storage providers:
* Google Drive
* Microsoft OneDrive or SharePoint
### Select Folders
Choose existing folders or create folders during setup. Give each folder a clear description so the assistant knows what belongs there.
| Folder | Example description |
| --------- | ------------------------------------------------------ |
| Receipts | Purchase receipts, invoices, and payment confirmations |
| Contracts | Signed agreements, proposals, and legal documents |
| Travel | Flight confirmations, hotel bookings, and itineraries |
You can also add general filing instructions and exclusions. Start with a small set of distinct folders; overlapping descriptions make the destination harder to determine.
### Review the Preview
The setup flow can preview recent attachments before auto-filing is enabled. Review the suggested destinations and correct them when needed, then enable the feature.
## How Filing Works
When a new attachment arrives, the assistant files it in the matching folder. If it isn't sure where a file belongs, it asks you for a destination instead of filing automatically.
## Corrections and Activity
Open **Attachments** to review Filing Activity and move a file to a different folder. Notification emails arrive in the source email thread, so you can also reply to approve a filing, move the file, or undo it. The assistant learns from these corrections.
## Delivery Settings
Use the **Delivery** button on the Attachments page to configure updates:
* **Email confirmations**: Receive an email when a file is sorted.
* **Connected apps**: Enable document-filing alerts for connected Slack, Microsoft Teams, or Telegram accounts. Configure or connect them on **Channels**.
For Slack, select a direct message or an allowed private channel. The selected Slack bot must already be invited to a private channel before it can post there.
# Booking Links
Source: https://docs.getinboxzero.com/essentials/booking-links
Share your availability and let guests schedule directly on your calendar.
Inbox Zero booking links give guests a public page where they can choose a free time, enter their details, and create a calendar event. The page respects your working hours, timezone, existing calendar conflicts, minimum notice, and meeting duration.
You can create one Inbox Zero booking link per email account. If you already use another scheduling service, you can instead save that external URL as your **Calendar Booking Link** so the AI can include it in scheduling replies.
## Requirements
* Connect at least one Google or Microsoft calendar.
* Enable the calendars that should block busy times.
## Set your availability
1. Open **Calendars** in the left sidebar.
2. Under **Availability**, choose the days and time windows when guests may book.
3. Confirm the timezone shown for the schedule.
4. Select **Save**.
This is the account's default availability. It also guides times the AI suggests in scheduling emails, even if you do not create an Inbox Zero booking link.
## Create a booking link
1. On **Calendars**, find **Booking link** and select **Create booking link**.
2. Enter the title guests will see and choose a unique URL slug.
3. Choose a duration and the destination calendar where new events should be created.
4. Optionally add a description and enable video conferencing.
5. Select **Create**.
Google calendars can create Google Meet links, and Microsoft calendars can create Microsoft Teams links.
After creation, copy the `/book/your-slug` URL and share it. The active Inbox Zero booking link is also the link the AI shares in scheduling replies.
## Configure or pause the link
Select **Configure** to edit the link's details, including the minimum notice before a meeting. The default notice is two hours.
Use the switch on the booking-link card to make the public page active or inactive. An inactive link cannot be booked and is not used by the AI. When an Inbox Zero link is active, it takes precedence over the external **Calendar Booking Link** field.
Deleting the link is permanent and also removes its booking history. Pausing the link is safer when you may want to use it again.
## What guests experience
Guests can:
1. View open slots in their chosen timezone.
2. Select a time and enter their name and email, plus an optional note.
3. Receive a calendar invite and confirmation email.
4. Use secure links from the confirmation to reschedule or cancel.
The host also receives booking notifications.
## Troubleshooting
### Create booking link is unavailable
Connect a calendar and make sure at least one calendar is enabled.
### No times appear on the public page
Check your weekly availability and timezone, minimum notice, and busy events across all enabled calendars. A disconnected calendar or temporary provider-availability failure can also hide all slots to prevent double booking.
### A video link was not added
Confirm that the destination calendar belongs to Google or Microsoft and that video conferencing is enabled in the booking-link configuration. Changing the destination calendar can also change which conferencing option is available.
### The AI shares the wrong scheduling link
Verify which Inbox Zero link is active. If no Inbox Zero link is active, review the external **Calendar Booking Link** field on the Calendars page.
# Bulk Archive
Source: https://docs.getinboxzero.com/essentials/bulk-archiver
Archive, mark as read, or delete email in bulk by category.
Bulk Archive cleans up years of accumulated mail in a few clicks. It groups your senders into categories such as newsletters, receipts, and notifications, so you can archive thousands of emails at once instead of selecting messages one by one.
Open **Bulk Archive** under Cleanup in the left sidebar, or visit [Bulk Archive](https://www.getinboxzero.com/bulk-archive).
## How It Works
1. If sender categorization is not enabled yet, follow the setup prompt and let Inbox Zero categorize your sender history.
2. Review the category cards and the senders assigned to each category.
3. Select the senders you want to process, or choose the entire category.
4. Run the configured bulk action.
Use **Categorize with AI** to categorize or refresh senders.
## Choose the Bulk Action
Open **Settings** on the Bulk Archive page to choose what the category buttons do:
* **Archive**: Remove matching messages from the inbox while keeping them searchable.
* **Mark as read**: Clear the unread state without moving the messages.
* **Delete**: Move matching messages to trash. Review the selected senders carefully before using this option.
# Bulk Unsubscribe
Source: https://docs.getinboxzero.com/essentials/bulk-email-unsubscriber
Review newsletter senders and unsubscribe, archive, or delete in bulk.
Bulk Unsubscribe finds every newsletter and marketing list you're subscribed to, shows you which ones you actually read, and lets you unsubscribe, archive, or delete in one click.
Open **Bulk Unsubscribe** under Cleanup in the left sidebar, or visit [Bulk Unsubscribe](https://www.getinboxzero.com/bulk-unsubscribe).
The video shows Gmail; the flow is the same for Outlook.
## Review Senders
The page groups newsletter and marketing email by sender, showing each sender's volume and how often you read them. Use the filters to narrow the list.
Open a sender to see its activity and individual messages. From the expanded view, you can also archive or delete previous messages from that sender.
## Sender Actions
* **Unsubscribe or Block**: Use the sender's supported unsubscribe or blocking mechanism.
* **Auto Archive**: Automatically archive future messages from the sender, optionally with a label.
* **Approve**: Keep the sender in your inbox and move it out of the unhandled list.
* **Archive**: Archive existing messages from the sender.
* **Delete**: Move existing messages from the sender to trash.
Use the checkboxes to apply these actions to several senders at once. The **Select suggested** shortcut selects subscriptions you rarely read. Review the selection before deleting, since deletion is harder to undo than archiving.
# Calendar Integration
Source: https://docs.getinboxzero.com/essentials/calendar-integration
Connect calendars for AI scheduling, availability, booking links, and meeting briefs.
Connected calendars let the assistant check your real availability when it drafts scheduling replies, so it can offer times that actually work. The **Calendars** page also manages weekly availability, booking links, timezone, and the calendars used for conflict checks.
## Connect a Calendar
1. Open **Calendars** in the left sidebar.
2. Connect Google Calendar or Microsoft Outlook Calendar and authorize access.
3. Choose which calendars should be checked for availability.
4. Confirm your timezone.
You can connect multiple calendars, such as separate work and personal calendars. Select the calendars that should block time so the assistant does not offer conflicting slots.
## Weekly Availability
In the **Availability** section, set the hours the assistant is allowed to suggest for each day of the week. These hours use the timezone shown on the **Calendars** page. Calendar events still block otherwise available time.
## Booking Links
You can either:
* Create an [Inbox Zero booking link](/essentials/booking-links), or
* Add an existing Calendly, Google Calendar, Microsoft Bookings, or other booking URL for the assistant to share.
Guests can book available times and use the booking page to reschedule or cancel.
## AI Scheduling
When an email asks about availability, the assistant can:
1. Check connected calendars for conflicts.
2. Restrict suggestions to your weekly availability.
3. Draft a response with available times or your configured booking link.
## Meeting Briefs
Connecting a calendar also enables [Meeting Briefs](/essentials/meeting-briefs), which prepares context before meetings with external guests.
# Call Webhook
Source: https://docs.getinboxzero.com/essentials/call-webhook
Send rule and email metadata to an external HTTP endpoint.
The **Call webhook** rule action sends a JSON request to an external service when an email matches a rule.
## Configure the Action
1. Open **Assistant** and edit a rule.
2. Add the **Call webhook** action.
3. Enter a publicly reachable HTTP or HTTPS endpoint.
4. Save the rule.
Inbox Zero validates webhook destinations and rejects unsafe or private-network addresses.
## Request Contract
* **Method:** `POST`
* **Content-Type:** `application/json`
* **Authentication header:** `X-Webhook-Secret`
* **Success response:** Any `2xx` status
* **Timeout:** 1 second
Inbox Zero does not wait for or parse the response body. A timeout, blocked destination, network failure, or non-`2xx` response is logged but does not stop the remaining rule actions. Webhook calls are not retried, so the endpoint should acknowledge quickly and queue longer work asynchronously.
## Payload
```typescript theme={null}
{
email: {
threadId: string;
messageId: string;
subject: string;
from: string;
cc?: string;
bcc?: string;
headerMessageId: string;
};
executedRule: {
id: string;
ruleId: string | null;
reason: string | null;
automated: boolean;
createdAt: string;
};
}
```
`threadId` and `messageId` are provider-specific Gmail or Outlook identifiers. `createdAt` is an ISO 8601 timestamp. `ruleId` can be `null` if the original rule no longer exists.
## Webhook Secret
Open **Settings**, find the **Developer** section, and generate a Webhook Secret. The secret is shown only when generated, so copy it before closing the dialog. Regenerating it immediately changes the value sent with future requests.
Every request includes the `X-Webhook-Secret` header. Your endpoint should compare the header to the stored secret before processing the payload.
# Channels
Source: https://docs.getinboxzero.com/essentials/channels
Connect Slack, Microsoft Teams, or Telegram and control what Inbox Zero delivers to chat.
The **Channels** page is the central place to connect chat apps and route Inbox Zero updates. You can receive rule notifications, draft replies, meeting briefs, follow-up reminders, digests, document-filing alerts, and scheduled check-ins.
## Connect a channel
1. Open **Channels** in the left sidebar.
2. Find **Slack**, **Microsoft Teams**, or **Telegram** and select **Connect**.
3. Complete the provider-specific flow:
* **Slack:** approve the Slack OAuth request and return to Inbox Zero.
* **Teams or Telegram:** copy the generated `/connect` command and send it in a direct message to the Inbox Zero bot.
4. Confirm that the provider displays a **Connected** badge.
## Route rule notifications
Under a connected provider, **Rule notifications** lists your enabled assistant rules. Turn on the rules that should post to that provider.
For each enabled rule, choose one of two modes from its menu:
* **Notify only** posts a notification when the rule matches.
* **Draft reply in chat** includes a generated draft for review.
Slack lets you choose a direct message or a Slack channel as the destination. Teams and Telegram deliver to your direct message with the bot.
### Provider differences
* **Slack** supports the richest interactive cards, including draft review and quick actions such as send, edit, archive, or mark as read.
* **Teams**: Draft editing and sending are not available yet. Review or send the draft in Inbox Zero. Other quick actions are view-only.
* **Telegram** can send a prepared draft from Telegram, but draft editing is not available there. Other quick actions such as archive and mark read are currently Slack-only.
## Route feature updates
Each connected provider can also show toggles for:
* **Meeting briefs**: a summary before meetings.
* **Follow-up reminders**: nudges for messages awaiting a reply.
* **Digests**: your scheduled newsletter digest. Digests require the **Plus plan or higher**.
* **Document filing alerts**: updates when attachments are filed.
* **Scheduled check-ins**: proactive assistant updates.
Configure the underlying feature using the settings button or linked feature page. For Slack, choose the target destination before enabling delivery.
## Chat with the assistant
You can direct-message the Inbox Zero bot in a connected provider. Slack also supports @mentions in channels where the bot is present. The assistant can use your connected email and calendar context.
## Disconnect a provider
Open the provider menu on **Channels** and select **Disconnect**. This stops delivery and removes that channel connection. It does not delete the underlying assistant rules, meeting-brief settings, digest schedule, or follow-up configuration.
## Troubleshooting
### Teams or Telegram will not link
Generate a new command from **Channels** and send it to the bot in a direct message within 10 minutes.
### A Slack destination is unavailable
Reconnect Slack if requested. Confirm that you still have access to the destination and that the Inbox Zero app is present in a private channel before selecting it.
### Notifications are missing
Check all three layers: the provider is connected, the individual rule or feature is enabled for that provider, and the feature itself is enabled. Also confirm the selected Slack destination or linked direct message still exists.
# Cold Email Blocker
Source: https://docs.getinboxzero.com/essentials/cold-email-blocker
Block cold emails and protect your inbox from spam using AI filters.
Cold Email Blocker keeps unsolicited sales pitches and outreach out of your inbox before you ever see them. The AI recognizes cold emails that traditional spam filters miss, while anyone who has emailed you before always gets through.
Open **Cold Email Blocker** in the left sidebar, or visit [Cold Email Blocker](https://www.getinboxzero.com/cold-email-blocker).
## Choose a Mode
You can run the Cold Email Blocker in three modes:
1. **List**: Show detected cold emails in the table on the page without changing your inbox.
2. **Auto label**: Label cold emails in your inbox with `Cold Email`.
3. **Auto archive and label**: Archive cold emails and label them with `Cold Email`.
Cold email detection applies only to new emails as they arrive; it does not reprocess older mail.
## Custom Prompts
Emails are classified using a prompt. The default works for most people, but you can adjust it by clicking **Edit Prompt**. Giving examples of what you do and don't consider a cold email works well.
## Testing
Click **Test** to open a side panel where you can paste in an email or test against previous emails to see if they would be marked as cold.
# Context Integrations
Source: https://docs.getinboxzero.com/essentials/context-integrations
Connect read-oriented business tools so drafts and meeting briefs can use relevant external context.
Context Integrations are in Early Access.
Context Integrations let Inbox Zero look up relevant information in connected services while preparing email drafts and meeting briefs. For example, the assistant may search for a sender in a CRM, fetch a Notion page, or check billing information in Stripe before it writes.
They are context sources, not general workflow automations.
## Requirements
* Early Access must be enabled for the account.
* Connecting an integration requires the **Plus plan or higher**.
## Available integrations
* **Notion**: search and fetch approved Notion content.
* **Stripe**: look up customers, invoices, subscriptions, and other billing data.
* **Linear**: look up issues, projects, and other workspace data (read-only access).
* **Attio**: look up people, companies, deals, notes, and tasks in your CRM.
* **Intercom**: look up conversations, contacts, companies, and Help Center articles.
* **Monday.com**: look up boards, board items, and workspaces.
* **Todoist**: write-only — adds tasks via the "Add Todoist task" rule action. Leave the task and description blank and the AI writes them from each matching email; fill them in to use your own wording. It is not used for drafting context.
* **Pipedream**: connect read-oriented tools from services such as HubSpot, Slack, Airtable, and Todoist.
## Connect a service
1. Open **Integrations** in the left sidebar.
2. Select **Connect** beside a service.
3. Review the provider's authorization screen and approve only the workspace and data you intend to share.
4. Return to Inbox Zero and confirm that the row says **Connected**.
That's it: read-oriented tools are enabled automatically after connecting. Expand **Tools** if you want to turn off specific lookups.
## How context is used
For email drafting, Inbox Zero searches enabled tools for information related to the sender and the current thread. For meeting briefs, enabled integration tools are available alongside email, calendar, and web-research context.
An integration may return stale, incomplete, or incorrectly matched information, so double-check consequential facts such as prices and payment state before sending a draft.
## Safety and access control
* Enable the smallest set of tools needed for your workflow.
* Prefer read-only tools. Do not enable tools that create, update, or delete data merely because their provider makes them available.
* Provider authorization controls which workspaces and records Inbox Zero can access; tool switches control which of those capabilities the assistant may call.
* Disconnecting removes the connection from Inbox Zero. It does not delete data in the external service.
* Pausing an integration from its row menu keeps the connection and your tool settings but stops its tools from being used until you resume it.
## Troubleshooting
### Integrations are not enabled
Select **Join Early Access** from the Integrations page.
### Connect asks for an upgrade
Context Integrations require Plus or higher. Upgrade the account that owns the selected email address, then restart the connection flow.
### A tool does not appear
Reconnect the service to resync its tool list. Some integrations intentionally allow only an approved subset, and Pipedream write-oriented tools may be filtered out.
### Drafts do not include expected context
Confirm that the integration is not paused, the relevant tool is enabled, and the connected provider account can access the record. The assistant only calls tools it judges relevant to the email or meeting.
### OAuth fails or is cancelled
Return to **Integrations** and start a fresh connection. If failure continues, disconnect the partial connection if present and retry.
# Deep Clean
Source: https://docs.getinboxzero.com/essentials/deep-clean
Preview an AI-assisted cleanup of older Gmail messages before applying it to the rest of your inbox.
Deep Clean is in Early Access and currently supports Gmail accounts.
Deep Clean reviews older inbox threads and decides which should stay and which can be archived or marked as read.
## Requirements
* Deep Clean currently supports **Google accounts only**. It does not appear for Outlook accounts.
* An active premium plan is required.
* Early Access must be enabled for your account.
## Run a cleanup
1. Open **Deep Clean** in the left sidebar.
2. Choose whether matching messages should be **Archived** or **Marked as Read**.
3. Select a time range, from all messages to messages older than one year. **Older than one week** is the recommended starting point.
4. Choose which mail must stay in the inbox:
* Emails needing replies.
* Starred emails.
* Future calendar events.
* Payment receipts.
* Mail matching your optional custom instructions.
5. Review the confirmation and select **Start Cleaning**.
Deep Clean processes an initial preview of 50 messages. Review the live results before selecting **Run on Full Inbox**.
## How messages are evaluated
AI classification can be wrong. Use the preview to confirm that your protected message types and custom instructions behave as expected.
## Safety and undo
Deep Clean does not delete email.
* **Archive** removes the Gmail Inbox label and adds an Inbox Zero archive label.
* **Mark as Read** removes the unread state and adds an Inbox Zero processed label.
* Every processed thread remains searchable in Gmail.
* Hover a completed action in the live results and select **Undo** to restore that thread to the inbox or mark it unread again.
* If Deep Clean chose **Keep**, hover the result to manually archive or mark the message as read.
After the first run, the Deep Clean page reuses your previous settings. Use **Edit settings** to change them, and **History** to review earlier cleanup jobs.
## Troubleshooting
### Deep Clean is missing
Confirm that the selected account is Gmail, the account has an active premium plan, and Early Access is enabled.
### Processing appears stuck
Large cleanups can take time. Keep the run page open or return through **History**. If nothing changes, refresh and confirm that the Gmail connection is still active.
### Important mail was cleaned
Use **Undo** on the affected result. Before another full run, enable the relevant protection or add a broader custom instruction, then start with a new 50-message preview.
### Too much mail is kept
Review which protections are enabled and simplify conflicting custom instructions. Use the preview result's manual action for individual messages before expanding the cleanup to the full inbox.
# Delayed Actions
Source: https://docs.getinboxzero.com/essentials/delayed-actions
Run supported rule actions after a configurable delay.
Delayed execution lets an assistant rule wait before applying an action. Use it for mail that should remain visible temporarily or for messages that should not be sent immediately.
## Add a Delay
1. Open **Assistant** and edit a rule.
2. Add or open a supported action.
3. Open the action's **More options** menu and choose **Add delay**.
4. Set a delay between 1 minute and 90 days, then save the rule.
The delay belongs to that specific action. Other actions in the same rule can still run immediately or use different delays.
## Supported Actions
You can delay:
* Archive
* Label
* Send reply
* Send email
* Forward
* Mark as read
* Star
* Delete
* Move to folder
Other actions cannot be delayed.
## Common Uses
* Archive newsletters after seven days.
* Send an automated reply after a short delay.
* Remove time-sensitive notifications from the inbox after they expire.
* Move older messages to a folder after a review window.
# AI Personal Assistant
Source: https://docs.getinboxzero.com/essentials/email-ai-personal-assistant
Create rules that automatically manage incoming email.
The AI Personal Assistant organizes your inbox for you. Describe how you want your email handled in plain English, and it labels, archives, forwards, and drafts replies automatically as mail arrives.
Open **Assistant** in the left sidebar or visit [Assistant](https://www.getinboxzero.com/automation). You can also create and manage rules through [AI Chat](/essentials/ai-chat).
## Getting Started
The video uses Gmail. Outlook users follow the same Assistant flow; label actions become Outlook categories, and messages can be moved to Outlook folders. See [Using Outlook](/essentials/outlook-guide).
### Create Rules from Instructions
1. Open **Assistant**.
2. Describe how you want your email handled in the instruction box.
3. Review the rules generated from your instructions.
4. Save the rules.
Use **Add rule manually** when you want to build the condition and actions yourself.
## How Rules Work
Each rule has a condition and one or more actions. When an incoming email matches the condition, Inbox Zero performs the configured actions.
### Conditions
Conditions can use AI instructions, static fields, or both.
* **AI condition**: Describe the meaning of the emails that should match, such as `Apply this rule if this email is asking me to set up a call.`
* **Static condition**: Match text in `From`, `To`, or `Subject`, such as `From` contains `@example.com`.
### Actions
A rule can contain multiple actions. Available actions can vary by email provider and connected apps:
* Label
* Move to folder
* Archive
* Delete
* Draft replies
* Send replies
* Forward
* Send email
* Mark as read
* Star
* Mark as spam
* Add to digest
* Call webhook
* Add Todoist task (requires a connected Todoist integration). Leave the task and description blank and the AI writes them from each matching email, or type your own wording to use it as-is.
* Notify in a connected Slack, Teams, or Telegram account
* Deliver a draft reply to a connected messaging account for review
* Notify the sender
See [Email Digest](/essentials/email-digest), [Call Webhook](/essentials/call-webhook), and [Delayed Actions](/essentials/delayed-actions) for actions that need additional configuration.
### AI-Generated Content
For actions with editable content, put an AI instruction inside double curly braces:
```text theme={null}
Hi {{name}},
{{write a response expressing interest in their proposal and ask about their timeline}}
Best regards
```
Inbox Zero generates the content inside each `{{...}}` placeholder from the email context. Text outside the placeholders remains as written.
### Delayed Execution
Supported actions can run after a delay instead of immediately. Open the action's **More options** menu and choose **Add delay**. Delays can range from 1 minute to 90 days. See [Delayed Actions](/essentials/delayed-actions).
### Apply to Threads
When **Apply to Threads** is disabled, the rule runs only on the first message in a conversation and is skipped for later replies. This is useful for standalone mail such as newsletters or receipts.
### When Multiple Rules Can Apply
By default, the assistant chooses one rule per email. Enable multi-rule selection in **Assistant** > **Settings** when you want several rules to match the same message.
## Learned Patterns
The assistant learns from corrections and from how you handle messages.
* Open a rule to review its learned patterns.
* Add or remove sender and domain patterns when you need explicit control.
* Use the History tab's **Fix** action to explain an incorrect match and update the rule.
## Test Rules
Open the [Test tab](https://www.getinboxzero.com/automation?tab=test) to run your rules against an email or free-form text. **Test All** evaluates the selected email against all rules without applying the actions.
## Assistant Settings
Open **Assistant** > **Settings** to configure behavior shared across rules, such as auto-drafting, writing style, and the email digest. See [Assistant Settings](/essentials/assistant-settings).
# Analytics
Source: https://docs.getinboxzero.com/essentials/email-analytics
Understand email volume, response time, and assistant activity.
Analytics shows you where your email time goes: who emails you most, how quickly you reply, and how much mail your assistant is handling for you.
Open **Analytics** under Cleanup in the left sidebar, or visit [Analytics](https://www.getinboxzero.com/stats).
## Available Metrics
Metrics cover email volume over time, top senders and recipients, response times, and the email your assistant has processed, archived, or deleted for you.
## Filter and Group Results
Use the date picker to select a preset or custom range. Use **Group by** to display results by day, week, month, or year.
## Load More History
Click **Load more** to import an older batch of email history and refresh the analytics. Repeat this if you want to analyze more of the account's history.
# Email Digest
Source: https://docs.getinboxzero.com/essentials/email-digest
Combine email from selected rules into a scheduled summary.
The digest collects emails matched by selected assistant rules and summarizes them in one scheduled update. It is useful for newsletters, notifications, reports, and other mail you prefer to review together.
The digest requires the **Plus plan or higher**. Adding an email to the digest does not archive it automatically; add an **Archive** action to the same rule if you also want it removed from the inbox.
## Set Up a Digest
1. Open **Assistant** in the left sidebar.
2. Open **Settings** and enable **Digest**.
3. Click **Configure**.
4. Select the rules whose matching messages should be included.
5. Choose a daily or weekly schedule. For a weekly digest, also choose the day.
6. Choose the delivery time and save.
You can also add the **Digest** action while editing an individual rule.
## Delivery
Email delivery is enabled by default and can be toggled in the Digest settings. The page shows when the next digest will be sent.
To receive the same scheduled digest in Slack, Microsoft Teams, or Telegram:
1. Connect the app on the **Channels** page.
2. Enable **Digests** for that connected account.
3. For Slack, select a direct message or an allowed private channel.
You can enable email and chat delivery at the same time, or turn off email after chat delivery is configured.
# FAQ
Source: https://docs.getinboxzero.com/essentials/faq
Frequently Asked Questions
Answers to common questions about Inbox Zero.
### How do I add more email addresses to my account?
To connect another mailbox for yourself, open the account switcher at the top of the sidebar and choose **Add or manage accounts**. On the Accounts page, choose **Add Account** and connect the Gmail or Outlook mailbox. You can also open [Settings](https://www.getinboxzero.com/settings) and choose **Add Account** in the Email accounts section.
Each connected mailbox has its own assistant rules and settings. Use the account switcher to move between them.
To share a subscription with another person, create or join an organization instead. In Settings, use **Invite members** under Team. Organization membership and connecting another mailbox are separate actions.
### How do I organize my Gmail inbox with multiple sections?
You have two options for organizing emails by type in Gmail:
1. **Use the [Inbox Zero Tabs Extension](/essentials/inbox-zero-tabs-extension)** - Our free browser extension adds custom tabs to Gmail, letting you organize emails by type (newsletters, receipts, to reply, etc.). It works great with our AI assistant which can automatically label emails for the tabs.
2. **Use Gmail's Multiple Inboxes feature**:
* Go to Gmail Settings → "See all settings" → "Inbox" tab
* Change "Inbox type" to "Multiple Inboxes"
* Create up to 5 sections using search queries like:
* `is:starred` for starred emails
* `label:Newsletter` for newsletters
* `is:unread` for unread messages
* `from:boss@company.com` for emails from specific senders
Both options help you see different types of emails at a glance instead of scrolling through one long list.
### How do I cancel my subscription?
Open the account menu at the bottom of the sidebar and choose [Settings](https://www.getinboxzero.com/settings). In the Billing section, click **Manage Subscription** and cancel in the billing portal.
### How do I delete my account?
Open the account menu at the bottom of the sidebar and choose [Settings](https://www.getinboxzero.com/settings). In the **Delete Account** section, click **Delete Account**.
### How do I revoke permissions to my email account?
To revoke permissions to your email account:
#### For Gmail accounts
* Visit the [Connections](https://myaccount.google.com/u/0/connections) page in your Google account
* Search for **Inbox Zero**, click on it, and then click **See Details**
* Click on the **Remove all access** button
#### For Microsoft/Outlook accounts
* Visit the [App permissions](https://account.microsoft.com/privacy/app-access) page in your Microsoft account, or open [Manage app consent](https://account.live.com/consent/Manage)
* Find **Inbox Zero** in the list and click on it
* Click **Remove** to revoke access
If you don't see **Inbox Zero** in the list, it means the account is not connected to Inbox Zero.
For Gmail, you can check your other accounts by clicking your profile picture in the top right corner and switching accounts.
### I see an error "You have exceeded the rate limit". How do I fix this?
This error is due to the fact that email providers (Gmail and Outlook) have rate limits per account.
If you've connected your account to other email services, it's possible that they are using up your rate limit.
#### For Gmail accounts
To check what other services have access to your Gmail account, visit your [Google Account Security page](https://myaccount.google.com/security). Under **Your connections to third-party apps & services**, click **See all connections**, then filter by **Access to Gmail**.
#### For Microsoft/Outlook accounts
Visit the [Microsoft App permissions page](https://account.microsoft.com/privacy/app-access) and review the apps that can access your email and data.
If there are any services there that you no longer use, click on them, and then click on **Delete all connections you have with this app** (for Gmail) or **Remove** (for Outlook).
### How do I find the message ID of an email in Gmail?
The message ID is a unique identifier for an email. It can be helpful to us when you report an issue to support.
1. In Gmail web, click on the email you want to find the message ID of.
2. In the top right corner, click on the three dots icon (vertical ellipsis).
3. Click on **Show original** button.
4. The **Message ID** field is the message ID. It will look something like this: ``.
# Getting Started
Source: https://docs.getinboxzero.com/essentials/getting-started
Connect your inbox and complete your first Inbox Zero workflow.
This guide takes you from a connected mailbox to a working AI assistant in a few minutes. Inbox Zero works with both Gmail and Outlook.
## 1. Connect an email account
Sign in at [getinboxzero.com](https://www.getinboxzero.com) and connect your Gmail or Outlook account. Approve the requested permissions so Inbox Zero can read and organize messages, create drafts, and send messages.
You can add another mailbox later from **Settings → Email Accounts**. Each mailbox has its own rules, assistant settings, analytics, and connected channels.
Using Outlook? The [Using Outlook guide](/essentials/outlook-guide) maps Gmail terms like labels to their Outlook equivalents.
## 2. Set up the Assistant
Open **Assistant** in the sidebar and complete the guided setup. Inbox Zero starts you with a smart set of default rules that file newsletters, marketing, and notifications out of the way and draft replies for emails that need one. Adjust the defaults, or describe new rules in plain English.
After saving a rule:
1. Open the rule and review its conditions and actions.
2. Use the **Test** tab to run it against example or recent messages.
3. Check **History** after new mail arrives to see what matched and why.
4. Use **Fix** or [Chat](/essentials/ai-chat) if the rule handled a message incorrectly.
Begin with labeling, archiving, or marking messages as read. Add outbound actions such as replies and forwarding after you are comfortable with how the rule matches.
## 3. Clean up existing mail
Use **Bulk Unsubscribe** to find noisy senders and **Bulk Archive** to organize older messages by sender category. These tools act on existing mail; Assistant rules handle new mail as it arrives.
Review the selected senders before applying a bulk action. Deleting mail is more difficult to recover than archiving or marking it as read.
## 4. Connect optional services
* Connect calendars for availability-aware drafts, booking links, and meeting features.
* Open **Channels** to connect Slack, Microsoft Teams, or Telegram.
* Gmail users can install the Inbox Zero Tabs browser extension.
* Teams can create an organization and invite members from **Settings → Team**.
## 5. Personalize drafts
Open **Assistant → Settings** to configure auto-drafting and how your drafts sound. See [Assistant Settings](/essentials/assistant-settings) for details.
## What to do next
Search mail and take actions using natural language.
Organize new mail and draft responses automatically.
Use availability, booking links, and meeting workflows.
Deliver notifications and drafts to the apps where you work.
# Inbox Zero Tabs Extension
Source: https://docs.getinboxzero.com/essentials/inbox-zero-tabs-extension
Add custom tabs to Gmail for email organization
Inbox Zero Tabs is a free browser extension that adds custom tabs to Gmail. It helps you organize your inbox by creating tabs for different types of emails - similar to Superhuman's split inbox feature.
The extension is 100% private - all data stays in your browser with no tracking or data collection. It currently works with Gmail only.
When used with [Inbox Zero's AI Assistant](/essentials/email-ai-personal-assistant), the extension becomes extra powerful. The AI can automatically categorize and label your emails, which then appear in the appropriate tabs without any manual setup.
## Installation
Install the extension for your browser:
### Chrome & Chromium Browsers
[Get Inbox Zero Tabs Extension](https://go.getinboxzero.com/extension)
Works with Chrome, Brave, Arc, Edge, Opera, and other Chromium-based browsers.
### Firefox
[Get Inbox Zero Tabs for Firefox](https://go.getinboxzero.com/firefox)
Works with Firefox and Firefox-based browsers.
After installation, refresh your Gmail tab to see the new tab system.
## Features
The extension adds custom tabs to Gmail that work with any Gmail search query. You get pre-configured tabs for common needs like "To Reply", "Newsletters", and "Receipts", or you can create your own based on any search criteria.
It supports multiple Gmail accounts with separate settings for each, automatically detecting which account you're using. The design matches Gmail's interface perfectly, supporting both dark and light themes.
### Key Difference from Gmail Labels
Unlike Gmail labels which show all emails (including archived ones), tabs focus on what's currently in your inbox. This is why most tab queries include `in:inbox` - to show only active emails, not everything you've ever received. You can also add `is:unread` to focus only on unread messages.
## Getting Started
After installing the extension and refreshing Gmail, click the extension icon to add your first tab. You can choose from pre-configured tabs or create custom ones using any Gmail search query.
### Example Tabs
Common tabs include:
* **To Reply**: `in:inbox is:sent -in:chats -label:replied`
* **Newsletters**: `in:inbox label:newsletter OR from:substack.com`
* **Receipts**: `in:inbox subject:(receipt OR invoice OR order)`
* **Team**: `in:inbox from:@yourcompany.com`
* **Important & Unread**: `in:inbox is:important is:unread`
## Configuration
To add a new tab, click the extension icon and select "Add Tab". Give it a name and define the Gmail search query you want to use. You can optionally enable "Unread Only" to filter out read emails.
Existing tabs can be edited by clicking on their names. You can modify the search query, rename tabs, or delete ones you no longer need. To reorder tabs, click the settings icon and then drag tabs to arrange them in your preferred order.
Use Gmail's search operators like `from:`, `label:`, `has:attachment`, `is:unread`, and `newer_than:` to create powerful filters. Combine them with `OR` and `AND` for complex queries.
## Privacy
The extension runs entirely in your browser. No data is collected, no account is required, and your email data never leaves your device.
## Troubleshooting
### Extension Not Showing
1. Refresh your Gmail tab after installation
2. Check that the extension is enabled in your browser's extension settings
### Tabs Not Filtering Correctly
1. Verify your search query syntax
2. Test the query in Gmail's search bar first
3. Check for typos in label names
4. Ensure labels exist in your Gmail account
## Support
Need help? Contact us at [support@getinboxzero.com](mailto:support@getinboxzero.com) or visit our [support page](https://getinboxzero.com).
# Meeting Briefs
Source: https://docs.getinboxzero.com/essentials/meeting-briefs
Get AI-generated context before meetings with external guests.
Meeting Briefs means you walk into every external meeting prepared. Before a calendar event with external guests, Inbox Zero sends you a briefing that combines attendee details with your email and meeting history, plus web research.
Meetings with only internal attendees are skipped; people on your email domain count as internal.
## Set Up Meeting Briefs
### Connect a Calendar
Open **Meeting Briefs** in the left sidebar. If no calendar is connected, follow the prompt to connect Google Calendar or Microsoft Outlook Calendar. You can also manage calendar connections from **Calendars**.
### Enable the Feature
Turn on **Enable Meeting Briefs**.
### Choose the Timing
Set how long before each meeting the briefing should be generated. The default is four hours.
### Choose Delivery Channels
Email delivery is enabled by default. You can also deliver briefs to any supported account connected on the **Channels** page:
* Slack
* Microsoft Teams
* Telegram
Slack can deliver to a direct message or an allowed private channel. You can enable more than one delivery channel at the same time.
## Briefing Content
A briefing can include:
* Attendee names, email addresses, and relevant background
* Recent email history with each external guest
* Past and upcoming meetings involving the same people
* Web research and professional context
* Internal team members who are also attending
* Meeting time, location, and joining details
The **Integrations** setting on the Meeting Briefs page can connect additional tools to enrich the briefing.
## Upcoming Meetings and Tests
The **Upcoming Meetings** section lists calendar events that Inbox Zero can see. Choose **Send test brief** to generate a sample immediately for a selected event.
Use **View send history** to inspect recent attempts.
# Meeting Recorder
Source: https://docs.getinboxzero.com/essentials/meeting-recorder
Record calls with a visible notetaker and receive transcripts, notes, action items, and follow-up drafts.
Meeting Recorder is in Early Access.
Meeting Recorder adds **Inbox Zero Notetaker** to your video calls as a visible participant. After the call, Inbox Zero produces a transcript and summary with decisions, action items, and next steps. It can also email the notes to you and prepare a follow-up in your Drafts folder.
The notetaker records and transcribes a meeting. Make sure participants know it is present and follow the consent and recording laws that apply to you and your attendees.
## Requirements
* Early Access must be enabled for your account.
* Meeting recording requires the **Plus plan or higher**.
* Connect a Google or Microsoft calendar to Inbox Zero.
* The calendar event must contain a Google Meet, Zoom, or Microsoft Teams meeting link.
## Set up Meeting Recorder
1. Open **Meetings** in the left sidebar.
2. If the feature is not enabled for your account, select **Join Early Access**.
3. Connect a calendar if prompted.
4. Select which meetings the notetaker should join:
* **Only calls with people outside my company**: the recommended default.
* **Every call with a video link**.
* **Only calls I organize**.
* **Only the ones I turn on myself**: nothing is scheduled automatically.
5. Select **Start recording my meetings**.
The **Up next** list shows your upcoming calls in the next 48 hours. Use the toggle beside a meeting to override the default for that individual call.
## Configure notes and follow-ups
Open **Meetings > Settings** to change the automatic join rule and these options:
* **Email me the notes** sends the completed recap to your email.
* **Draft a follow-up email** creates a draft addressed to the other attendees.
The follow-up is never sent automatically. Review its recipients and content in Drafts before sending it.
Selecting **Turn off** cancels every call the notetaker is currently booked to join.
## Review a recorded meeting
Completed and processing calls appear under **Recorded** on the Meetings page. Open a meeting to see:
* An overview and key decisions.
* Action items and their detected owners.
* Open questions and next steps.
* A speaker-attributed transcript with timestamps.
* A link to the generated follow-up draft, when enabled.
AI-generated notes can be incomplete or inaccurate. Compare important decisions, commitments, names, and dates with the transcript or the other attendees before relying on them.
## Troubleshooting
### A call does not appear under Up next
Confirm that the calendar connection is active, the event is within the next 48 hours, and the event contains a video-conference link. Then check whether your automatic join rule excludes the event.
### The notetaker did not join
Open the meeting in **Up next** or **Recorded** and check its status. Common causes include a removed or changed meeting link, an event that was changed too close to its start time, host admission controls, or the meeting provider rejecting the bot.
### Notes are still processing
Transcription and summarization continue after the call ends and may take time. Refresh the meeting later.
### No summary was created
Open the meeting detail to see whether recording or summarization failed. A failed recording cannot be recovered after the call.
# Mobile Apps
Source: https://docs.getinboxzero.com/essentials/mobile-apps
Use Inbox Zero on iOS or Android to triage email and manage your assistant on the go.
Inbox Zero is available for iOS and Android. The mobile apps work with the same Inbox Zero account and connected Gmail or Outlook accounts you use on the web.
## Install and sign in
1. Open [getinboxzero.com/app](https://www.getinboxzero.com/app).
2. Select **App Store** or **Google Play**.
3. Install Inbox Zero and sign in with your existing account. If you are new, create an account and connect Gmail or Outlook during setup.
The apps are free to download. Features that require a paid Inbox Zero plan on the web keep the same plan requirement on mobile.
## What you can do
The current mobile experience supports core inbox and assistant workflows, including:
* Chat with the AI assistant to ask about email, get summaries, and prepare replies.
* Read conversations and send new messages or replies.
* Review messages needing a reply and common categories such as Newsletters, Promotions, and Notifications.
* Work across your connected inboxes from the combined inbox view.
* Archive, restore, move to trash, or undo those actions for individual or selected threads.
* Create a rule from a plain-language prompt or configure it manually, then edit, enable, disable, or delete rules.
Some account administration and advanced configuration remain easier or available only in the web app. If a setting is not present on mobile, open Inbox Zero in a desktop browser.
## Multiple inboxes
The combined inbox shows mail from every connected email account.
## Troubleshooting
### Sign-in returns to the browser instead of the app
Update the app and retry from its sign-in screen. If the callback still does not return, close the browser tab, reopen the app, and start a fresh sign-in.
### One connected account is empty
Open the account on the web and confirm that its Gmail or Outlook connection is active. Then refresh the mobile view.
### A web feature is missing on mobile
Use the web app for the complete settings and administration surface. Mobile and web share the same account, so changes saved on the web apply on mobile.
# Organizations
Source: https://docs.getinboxzero.com/essentials/organizations
Invite teammates, manage roles, share assistant rules, and view consented team analytics.
Organizations let a team manage membership, distribute shared assistant rules, and review aggregate usage. Each email account can belong to only one organization at a time.
## Create an organization
1. Open the account menu.
2. Select **Create organization**.
3. Enter the organization name and a unique URL slug.
4. Select **Create Organization**.
The creator becomes the organization **Owner**.
## Roles and permissions
| Role | Access |
| ---------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Owner** | All admin abilities, plus transferring ownership. |
| **Admin** | Invite and remove members, change non-owner roles, manage organization rules, and view analytics that members have shared. |
| **Member** | View the member list and use organization-managed rules in their own account. |
After a transfer, the previous owner becomes an admin.
## Invite and manage members
1. Open **My Organization** from the account menu.
2. On **Members**, select **Invite members**.
3. Enter up to 10 email addresses at a time and assign a role.
4. Send the invitations.
Invitations are delivered by email and expire after 14 days. The recipient must accept while signed in with the exact invited email address. An admin can cancel a pending invitation from the Members page.
Use the menu beside a member to change their role or remove them. The owner also sees **Transfer ownership**. If the organization provides premium seats, accepting an invitation can claim an available seat; removing a member releases their organization seat.
## Create organization rules
Owners and admins can open **Rules** and create assistant rules that are copied to every member account.
* New members receive the current organization rules when they join.
* Editing an organization rule updates its member copies.
* Members see a **Managed by organization** rule and cannot edit its definition.
* A member may turn a managed rule on or off for their own account.
* The rule only runs for a member when both the organization-level rule and that member's copy are enabled.
* Deleting an organization rule removes it for all members.
Messaging-channel actions are not supported in organization rules; configure those actions in each member's own rules instead.
Because organization rules act on every member's inbox, test a rule's conditions before rolling it out organization-wide.
## Analytics and privacy
The **Analytics** tab is available to owners and admins. It shows emails received, rules executed, and active members over a selected date range.
Member analytics are private by default. Each member sees a prompt to allow organization-admin analytics. Admins can open a member's Analytics and Usage pages only after that member grants access. A hidden-activity badge means the member has not shared analytics.
Granting analytics access does not give an admin the ability to read the member's email content through the organization page.
## Troubleshooting
### An invitation cannot be accepted
Confirm that it has not expired and that the signed-in account exactly matches the invited email. The recipient must leave any other organization before joining.
### Rules or Analytics tabs are missing
Those tabs are limited to owners and admins. Ask an owner or admin to update your role if appropriate.
### A member cannot edit a rule
Rules labeled **Managed by organization** can only be edited by an owner or admin from the organization's Rules tab. The member can still enable or disable their own copy.
### A member's analytics are unavailable
The member must select **Allow Access** on the organization page. Analytics can also remain empty until Inbox Zero has processed enough account activity for the selected date range.
# Using Outlook
Source: https://docs.getinboxzero.com/essentials/outlook-guide
Terminology, tips, and troubleshooting for Outlook and Microsoft 365 accounts.
Inbox Zero fully supports Outlook, including Microsoft 365 work or school accounts and personal Outlook accounts. Connecting works the same way as Gmail: follow the [Getting Started guide](/essentials/getting-started), choose Outlook when connecting, and approve the requested Microsoft permissions.
Everything in the main documentation applies to both providers. This page covers the small number of things that are specific to Outlook.
On a managed Microsoft 365 tenant, an organization administrator may need to approve the app before your account can connect. If access is later revoked in Microsoft, reconnect the mailbox from Inbox Zero.
## Gmail terms in Outlook
Some Inbox Zero videos and screenshots were recorded with Gmail. The steps are the same in Outlook; only the mail concepts differ:
| Gmail term | Outlook equivalent |
| --------------- | ---------------------- |
| Label | Category |
| Move to label | Move to folder |
| Archive | Archive folder |
| Trash | Deleted Items |
| Spam | Junk Email |
| Google Calendar | Outlook Calendar |
| Google Drive | OneDrive or SharePoint |
## The Tabs extension
The [Inbox Zero Tabs](/essentials/inbox-zero-tabs-extension) browser extension is the one feature that only applies to Gmail. Outlook includes similar inbox-organization tools natively, such as folders, categories, and Focused Inbox, so the extension targets Gmail specifically.
Some [Early Access](/essentials/deep-clean) experiments may also launch on one provider before the other.
## Outlook troubleshooting
### Microsoft will not authorize the connection
Retry with the intended Microsoft account. For a managed Microsoft 365 tenant, ask an administrator whether user consent is restricted or whether the Inbox Zero app requires approval.
### A rule uses the wrong category or folder
Confirm that the category or folder still exists in the connected Outlook mailbox, then edit and retest the rule. Settings and rules are not shared automatically between connected mailboxes.
### Inbox Zero stopped receiving Outlook mail
Open **Settings → Email Accounts** and reconnect the Outlook account if it shows a permissions or subscription error. You can also review or revoke Inbox Zero from the [Microsoft App permissions page](https://account.microsoft.com/privacy/app-access).
# Reply Zero
Source: https://docs.getinboxzero.com/essentials/reply-zero
Track conversations that need a reply or a follow-up.
Reply Zero is in Early Access and is not yet available on all accounts.
Reply Zero keeps every conversation that needs your reply, and every reply you're waiting on, in one place, so nothing slips through the cracks. Conversations are labeled `To Reply` when you owe a response and `Awaiting Reply` when you're waiting on someone else, and the labels are visible in your regular email client too.
## Open Reply Zero
Open the account menu at the bottom of the sidebar and choose **Reply Zero**. On first use, follow the onboarding steps to enable the reply-tracking rules.
## Lists
### To Reply
Incoming conversations that appear to need your response are labeled `To Reply`. The Reply Zero view shows them on the **To Reply** tab and provides a **Reply** shortcut.
### Waiting
Sent conversations that appear to require a response are labeled `Awaiting Reply` and shown on the **Waiting** tab. Use **Nudge** to open the thread and prepare a follow-up.
### Done
Choose **Mark Done** when a conversation no longer needs attention. It moves to the **Done** tab. You can restore it with **Not Done** if necessary.
Use the time-range filter to focus on newer or older conversations.
## Follow-Up Reminders
Open **Assistant** > **Settings** and configure **Follow-up reminders** to choose how many days to wait and whether Inbox Zero should automatically draft a nudge when you are waiting. Saturday and Sunday do not count toward these thresholds. Use **Find follow-ups** to scan existing mail immediately. Matching conversations receive a `Follow-up` label or category.
To receive reminders in Slack, Microsoft Teams, or Telegram, enable follow-up delivery for the connected account on the **Channels** page.
The Reply Zero view is currently available for Gmail accounts. On Outlook, use the `To Reply`, `Awaiting Reply`, and `Follow-up` categories directly in Outlook instead.
# Security, Permissions, and AI
Source: https://docs.getinboxzero.com/essentials/security-and-data
Understand account access, confirmations, sensitive-data controls, and recovery.
Inbox Zero needs access to your mailbox to search messages and run the workflows you enable. Optional features request additional access only when you connect them, such as calendar or drive permissions.
## Account permissions
* Email permissions allow Inbox Zero to read and organize messages and create drafts.
* Calendar permissions support availability, booking links, and meeting features.
* Drive permissions support filing attachments and attaching approved files to drafts.
* Slack, Teams, and Telegram connections let the assistant respond and deliver configured notifications.
You can revoke a connection from Inbox Zero or from the provider's security settings. Revoking provider access stops the affected feature until you reconnect it.
## Confirming high-impact actions
Chat and messaging-channel workflows ask for confirmation before high-impact actions such as sending messages or creating automation that can communicate externally. Always review generated recipients, content, links, and attachments before approving.
Rules run automatically after they are enabled. Test new rules with recent messages and review **Assistant → History** before relying on outbound actions.
## Sensitive-data protection
Assistant settings include a sensitive-data policy that can allow, redact, or block detected credentials and payment-card numbers before content is sent to an AI provider.
This control reduces accidental exposure; it is not a substitute for removing secrets from email or reviewing generated content.
## AI limitations
AI output can be incomplete or incorrect. In particular:
* A rule may match an unexpected message.
* A draft may omit context or make an unsupported assumption.
* A summary may miss a detail from a long thread or attachment.
* Availability and external-tool results depend on connected services being current.
Use rule tests, draft confidence, confirmation prompts, and the **Fix** workflow to reduce these risks.
## Safer cleanup and recovery
Prefer labels, folders, archiving, or marking mail as read while testing a workflow. Deletion is more difficult to recover and may depend on the retention behavior of Gmail or Outlook.
If a rule behaves incorrectly, disable it, inspect its History entry, and use **Fix**. You can also disable all rules for one mailbox from **Settings → Email Accounts** while investigating.
## Account deletion
Deleting your Inbox Zero account is separate from revoking Google or Microsoft access. See the [FAQ](/essentials/faq) for both processes and review the [Privacy Policy](https://www.getinboxzero.com/privacy) for the hosted service's current data terms.
# Slack Integration
Source: https://docs.getinboxzero.com/essentials/slack-integration
Chat with your assistant and deliver rules, drafts, and updates to Slack.
Connect Slack from the unified **Channels** page. A connected workspace can chat with the assistant and receive rule notifications, draft replies for review, meeting briefs, follow-up reminders, digests, and document-filing alerts.
## Connect Slack
1. Connect a Gmail or Outlook account to Inbox Zero.
2. Open **Channels** in the left sidebar.
3. Find Slack and click **Connect**.
4. Approve the requested permissions in Slack.
5. After returning to Inbox Zero, configure the rules and feature destinations you want.
The connected workspace appears on the Channels page with a **Connected** badge.
## Choose a Destination
Each Slack feature can use a direct message or an allowed private channel. Configured channel delivery has these restrictions:
* Public channels cannot be selected.
* You must be a member of the private channel.
* Inbox Zero does not automatically join the selected channel.
* If a private channel is missing from the selector, use the `/invite @` command shown in the destination menu to invite the Inbox Zero bot, then refresh the list.
You can choose separate destinations for rule notifications, meeting briefs, follow-up reminders, digests, document-filing alerts, and scheduled check-ins.
## Rule Notifications and Draft Review
The **Rule notifications** section lists your assistant rules. Enable a rule for Slack, then use its menu to choose:
* **Notify only**: Post a notification when the rule matches.
* **Draft reply in chat**: Deliver the generated reply to Slack for review.
## Chat with the Assistant
* Send the Inbox Zero bot a direct message.
* Mention the bot in a Slack conversation where it has been added.
* Continue related conversations in Slack threads.
The assistant can search and manage email, draft messages, and update supported rules and settings. Use `/help` to see shortcuts such as `/summary`, `/draftreply`, `/followups`, and `/cleanup`.
## Other Slack Deliveries
Enable these from the connected Slack section of **Channels** or from the feature's own settings:
* [Meeting Briefs](/essentials/meeting-briefs)
* Follow-up reminders and scheduled check-ins
* [Email Digest](/essentials/email-digest)
* [Auto-File Attachments](/essentials/auto-file-attachments) alerts
## Disconnect Slack
Open **Channels**, use the menu next to the connected Slack workspace, and choose `Disconnect Slack`. This stops chat access and all Slack deliveries for that connection.
# Telegram Integration
Source: https://docs.getinboxzero.com/essentials/telegram-integration
Chat with your assistant and receive Inbox Zero updates in Telegram.
Connect Telegram from the unified **Channels** page. The integration uses a direct message with the Inbox Zero bot for chat and feature delivery.
## Connect Telegram
1. Open **Channels** in the left sidebar.
2. Find Telegram and click **Connect**.
3. Inbox Zero generates a one-time `/connect` command.
4. Open the Inbox Zero bot using the link in the dialog.
5. Send the complete command in a direct message to link your account.
Once connected, Telegram appears on the Channels page with a **Connected** badge.
## Chat with the Assistant
The Telegram bot provides the same core [AI Chat](/essentials/ai-chat) workflow. You can:
* Search and summarize email.
* Manage inbox messages.
* Draft messages and replies for review.
* Create and update automation rules.
* Ask what needs your attention.
If more than one email account is linked, use `/switch` to list them and `/switch ` to change the active account.
## Commands
* `/connect `: Link an Inbox Zero email account.
* `/switch`: List linked accounts.
* `/summary`: Summarize what needs attention today.
* `/draftreply`: Draft a response to your most urgent unread email.
* `/followups`: Show emails that may need a follow-up this week.
* `/cleanup`: Start an inbox cleanup conversation.
* `/help`: Show available commands.
## Feature Delivery
From the connected Telegram section on **Channels**, you can configure:
* Rule notifications or draft replies for review
* Meeting briefs
* Follow-up reminders and scheduled check-ins
* Digests
* Document-filing alerts
Telegram delivery goes to the linked direct-message destination; there is no separate channel picker.
## Disconnect Telegram
Open **Channels**, use the menu next to Telegram, and choose **Disconnect Telegram**. This stops Telegram chat access and all configured deliveries.
# Troubleshooting
Source: https://docs.getinboxzero.com/essentials/troubleshooting
Resolve common mailbox, rule, draft, calendar, and channel problems.
## Mail is not being processed
1. Confirm the correct mailbox is selected in the account switcher.
2. Open **Settings → Email Accounts** and make sure rules are not globally disabled.
3. Check whether Gmail or Outlook access was revoked or requires new permissions.
4. Open **Assistant → History** to see whether the message was evaluated.
5. Reconnect the mailbox if the app reports a permission or subscription error.
## A rule matched the wrong message
Open **Assistant → History**, find the message, and select **Fix**. Explain what should have happened. You can also open the rule directly to adjust its static conditions, AI instructions, actions, or learned patterns.
Use the **Test** tab before re-enabling a rule that sends, replies, forwards, deletes, or calls a webhook.
## A rule did not match
* Check whether the rule is enabled.
* Check **Apply to threads** if the message was a reply in an existing conversation.
* Review overlapping rules and the multi-rule setting.
* Confirm that referenced labels, folders, channels, files, or calendars still exist.
* Test the rule against the message text and inspect the explanation.
## A draft was not created
Check that auto-drafting is enabled and that the message meets your configured draft-confidence threshold. A message may also be excluded because it does not need a reply, the relevant rule is disabled, or the provider no longer has permission to create drafts.
## Calendar or availability is wrong
* Verify the correct calendars are connected and enabled.
* Confirm your timezone and weekly availability.
* Check that the destination calendar for a booking link still exists.
* Reconnect the calendar if events are not updating.
## Channel notifications are missing
Open **Channels** and check that the provider is connected and the relevant delivery type is enabled.
For Slack notifications, choose a private channel you belong to and manually invite the Inbox Zero bot to that channel. Teams and Telegram delivery uses the linked direct-message conversation.
## Attachment filing failed
Confirm that the drive connection is active and that the destination is within the folders you approved. If the AI requested clarification, reply through the configured channel or correct the filing from the Attachments page.
## A bulk action is taking longer than expected
Large inbox operations can take time. Keep the page open while it reports progress, avoid starting the same operation again, and review the resulting history or sender state before applying another bulk action.
## Still stuck?
Contact [support@getinboxzero.com](mailto:support@getinboxzero.com) with the affected feature, email provider, approximate time of the problem, and any visible error message. Do not send passwords, API keys, OAuth tokens, or full sensitive email content.
# AWS Deployment
Source: https://docs.getinboxzero.com/hosting/aws
Choose the right AWS deployment method for Inbox Zero
There are three ways to deploy Inbox Zero on AWS. Choose the one that fits your team and infrastructure.
| Approach | Best for | Infrastructure |
| --------------------------------------- | ---------------------------- | ---------------------------------------- |
| [EC2 + Docker](/hosting/ec2-deployment) | Simple VPS-style deployment | Single EC2 instance with ALB |
| [Terraform](/hosting/terraform) | Infrastructure-as-code teams | ECS Fargate + RDS + optional ElastiCache |
| [AWS Copilot](/hosting/aws-copilot) | AWS-native teams | ECS Fargate (managed by Copilot) |
## EC2 + Docker
The most straightforward approach. Launch an EC2 instance, install Docker, and use the same Docker Compose setup from the [Docker/VPS Deployment Guide](/hosting/self-hosting). Add an ALB for HTTPS.
Best if you want full control over a single server and are comfortable with SSH.
Step-by-step EC2 setup with ALB and SSL.
## Terraform
Generate a complete Terraform configuration with one command. Provisions ECS Fargate, RDS PostgreSQL, optional ElastiCache Redis, and manages secrets via SSM Parameter Store.
Best if your team uses infrastructure-as-code and wants repeatable deployments.
Deploy with `terraform init && terraform apply`.
## AWS Copilot
AWS Copilot handles the infrastructure for you. It creates ECS services, load balancers, and networking with simple CLI commands.
Best if you prefer AWS-managed tooling and want to avoid writing infrastructure code.
Deploy with `copilot init` and `copilot svc deploy`.
# Copilot Deployment
Source: https://docs.getinboxzero.com/hosting/aws-copilot
Deploy Inbox Zero to AWS using AWS Copilot and ECS Fargate
Deploy Inbox Zero to AWS using AWS Copilot. The deployment uses Amazon ECS on Fargate.
If you prefer Terraform, see [Terraform Deployment Guide](/hosting/terraform).
## Prerequisites
* AWS CLI installed and configured with appropriate credentials
* AWS Copilot CLI installed ([installation guide](https://aws.github.io/copilot-cli/docs/getting-started/install/))
* Docker installed and running
* An AWS account with appropriate permissions
* Inbox Zero repository cloned locally (run all commands from the repo root)
## CLI Setup
The CLI automates Copilot setup, addons (RDS + ElastiCache), secrets, and deployment. Run from the cloned repo root:
```bash theme={null}
pnpm setup-aws
```
Non-interactive mode:
```bash theme={null}
pnpm setup-aws -- --yes
```
> The CLI will update `copilot/environments/addons/addons.parameters.yml`, configure SSM secrets,
> deploy the environment, and then deploy the service. It also handles the webhook gateway if enabled.
> Note: The CLI now writes `DATABASE_URL`, `DIRECT_URL`, and `REDIS_URL` after the environment deploy,
> because creating those SSM parameters inside addon templates can trigger EarlyValidation failures.
If you use the CLI, you can skip the manual steps below.
## Manual Copilot Setup
Use this section if you prefer to drive Copilot directly.
### 1. Initialize the Copilot Application
First, initialize a new Copilot application with your domain:
```bash theme={null}
copilot app init inbox-zero-app --domain
```
Replace `` with your actual domain (without the `http://` or `https://` prefix), for example: `example.com`.
This creates the Copilot application structure and sets up your domain.
> **Note:** The `--domain` flag only works if your domain is hosted on AWS Route53. If your domain is managed elsewhere, omit the `--domain` flag and remove the `http` section from `copilot/inbox-zero-ecs/manifest.yml` (the `alias` and `hosted_zone` fields). You'll need to configure your domain's DNS separately to point to the load balancer.
### 2. Configure the Service Manifest
Before initializing the service, configure the environment variables in the manifest file. The service manifest (`copilot/inbox-zero-ecs/manifest.yml`) is already included in the repository.
Edit `copilot/inbox-zero-ecs/manifest.yml` to add your environment variables in the `variables` section.
Required environment variables include:
* `DATABASE_URL` - Your PostgreSQL connection string
* `DIRECT_URL` - Direct database connection (for migrations)
* `AUTH_SECRET` - Authentication secret
* `GOOGLE_CLIENT_ID` - Google OAuth client ID
* `GOOGLE_CLIENT_SECRET` - Google OAuth client secret
* `NEXT_PUBLIC_BASE_URL` - Your application URL
* And other required variables (see `apps/web/env.ts`)
For sensitive values, consider using the `secrets` section instead of `variables` (see [Managing Secrets](#managing-secrets) below).
### 3. Initialize the Production Environment
Create a production environment:
```bash theme={null}
copilot env init --name production
```
This will prompt you for:
* AWS profile/region (if not already configured)
* Other infrastructure options
### 4. Initialize the Service
Initialize the Load Balanced Web Service:
```bash theme={null}
copilot init --app inbox-zero-app --name inbox-zero-ecs --type "Load Balanced Web Service" --deploy no
```
**Note:** The service manifest is already included in the repository. Copilot will detect the existing manifest and configure infrastructure accordingly.
### 5. Deploy the Environment
Deploy the production environment infrastructure:
```bash theme={null}
copilot env deploy --force
```
This creates the necessary AWS resources (VPC, load balancer, etc.) for your environment.
### 6. Deploy the Service
Deploy your application service:
```bash theme={null}
copilot svc deploy
```
This will:
* Use the pre-built Docker image from GitHub Container Registry (`ghcr.io/elie222/inbox-zero:latest`), or
* Build your Docker image using `docker/Dockerfile.prod` if you prefer to build from source
* Push the image to Amazon ECR (if building)
* Deploy the service to ECS/Fargate
* Set up the load balancer and domain
**Note:** The manifest is configured to use the pre-built public image by default. If you want to build from source instead, you can remove or comment out the `image.location` line in `copilot/inbox-zero-ecs/manifest.yml` and Copilot will build using the `image.build` configuration.
***
## Post-Deployment
The following sections apply whether you used the CLI or manual setup.
### Updating Your Deployment
To update your application after making changes:
```bash theme={null}
copilot svc deploy
```
This will:
* Pull the latest pre-built image from GitHub Container Registry (if using the default configuration), or
* Rebuild and redeploy your service with the latest changes (if building from source)
### ElastiCache Redis (Optional)
Redis is deployed as an environment addon. You can enable or change its size by
editing `copilot/environments/addons/addons.parameters.yml`:
```yaml theme={null}
EnableRedis: 'true'
RedisInstanceClass: 'cache.t4g.micro'
```
Then deploy the environment:
```bash theme={null}
copilot env deploy --name production
```
### Managing Secrets
For sensitive values, use AWS Systems Manager Parameter Store:
1. Store secrets in Parameter Store:
```bash theme={null}
aws ssm put-parameter --name /copilot/inbox-zero-app/production/inbox-zero-ecs/AUTH_SECRET --value "your-secret" --type SecureString
```
2. Reference them in `manifest.yml`:
```yaml theme={null}
secrets:
AUTH_SECRET: AUTH_SECRET # The key is the env var name, value is the SSM parameter name
```
### Viewing Logs
View your application logs:
```bash theme={null}
copilot svc logs
```
Or follow logs in real-time:
```bash theme={null}
copilot svc logs --follow
```
### Checking Service Status
Check the status of your service:
```bash theme={null}
copilot svc status
```
### Database Migrations
Database migrations run automatically on container startup via the `docker/scripts/start.sh` script. The script uses `prisma migrate deploy` to apply any pending migrations.
**Important:** The service manifest includes a `grace_period` of 320 seconds in the healthcheck configuration to ensure the container is not killed before migrations complete. This is especially important for the initial deployment when all migrations need to be applied. If you have a large number of migrations, you may need to increase this value in `copilot/inbox-zero-ecs/manifest.yml`.
If you need to manually run migrations:
```bash theme={null}
copilot svc exec
# Then inside the container:
prisma migrate deploy --schema=./apps/web/prisma/schema.prisma
```
## Troubleshooting
### Service Won't Start
1. Check logs: `copilot svc logs`
2. Verify environment variables are set correctly
3. Ensure database is accessible from the ECS task
4. Check that the Docker image builds successfully
### Migration Issues
If migrations fail:
1. Check database connectivity
2. Verify `DATABASE_URL` and `DIRECT_URL` are correct
3. Check the container logs for specific error messages
4. You may need to manually resolve failed migrations using `prisma migrate resolve`
### Addons Change Set EarlyValidation
If `copilot env deploy` fails with `AWS::EarlyValidation::PropertyValidation`, make sure addon
templates do not create SSM parameters that include dynamic Secrets Manager references. The CLI
setup flow creates `DATABASE_URL`, `DIRECT_URL`, and `REDIS_URL` after the environment deploy.
### Domain Not Working
1. Verify DNS settings for your domain
2. Check that the load balancer is properly configured
3. Ensure SSL certificate is provisioned (Copilot handles this automatically)
## Firewalled Deployments (Webhook Gateway)
For deployments where the main application is behind a firewall or private network (e.g., only accessible to employees via VPN), you need a way for Google Pub/Sub to deliver Gmail webhook notifications. The webhook gateway addon solves this by creating a public API Gateway endpoint that validates Google's OIDC tokens before forwarding to your private infrastructure.
### Prerequisites
* **IAM User (not root)**: AWS Copilot requires IAM role assumption, which doesn't work with root account credentials. Create an IAM user with `AdministratorAccess` policy.
* **AWS CLI Profile**: Configure an AWS CLI profile for your deployment:
```bash theme={null}
aws configure --profile inbox-zero
# Enter your IAM user's access key and secret
# Set region (e.g., us-east-1)
```
* **Set environment variables** before running Copilot commands:
```bash theme={null}
export AWS_PROFILE=inbox-zero
export AWS_REGION=us-east-1
```
### Architecture
```
Google Pub/Sub → API Gateway (public) → VPC Link → Internal ALB → ECS
↑
JWT validation
(Google OIDC)
```
* **API Gateway**: Public endpoint that Google Pub/Sub can reach
* **JWT Authorizer**: Validates Google's OIDC tokens cryptographically
* **VPC Link**: Connects API Gateway to your private VPC
* **Internal ALB**: Your Copilot-managed load balancer
### How It Works
1. Google Pub/Sub sends webhook requests with a signed JWT in the `Authorization` header
2. API Gateway validates the JWT:
* Verifies signature using Google's public keys
* Checks issuer is `https://accounts.google.com`
* Validates audience matches your configured endpoint
* Ensures token is not expired
3. Valid requests are forwarded to your internal ALB via VPC Link
4. Invalid requests are rejected with 401 (never reach your app)
### Deployment
The webhook gateway is an **environment addon**. However, it requires the ALB's HTTPS listener which is only created when a Load Balanced Web Service is deployed. Follow this specific order:
> **Important**: The addon references `HTTPSListenerArn` which only exists after a service is deployed. If you try to deploy the environment addon before the service, it will fail.
#### First-time Setup (New Deployment)
Keep the webhook gateway template in `copilot/templates/` until the service is deployed.
1. **Deploy the environment** (without the addon):
```bash theme={null}
copilot env deploy --name production
```
2. **Deploy the service** (this creates the ALB and HTTPS listener):
```bash theme={null}
copilot svc deploy --name inbox-zero-ecs --env production
```
3. **Add and deploy the addon**:
```bash theme={null}
cp copilot/templates/webhook-gateway.yml copilot/environments/addons/
copilot env deploy --name production
```
#### Existing Deployment (Service Already Running)
If you already have a deployed service with an ALB, add the addon then deploy the environment:
```bash theme={null}
cp copilot/templates/webhook-gateway.yml copilot/environments/addons/
copilot env deploy --name production
```
#### Get the Webhook Endpoint URL
After the addon is deployed, get the webhook URL from the addon stack outputs:
```bash theme={null}
# Find the addon stack
ADDON_STACK=$(aws cloudformation list-stack-resources \
--stack-name inbox-zero-app-production \
--query "StackResourceSummaries[?contains(LogicalResourceId,'AddonsStack')].PhysicalResourceId" \
--output text)
# Get the webhook URL
aws cloudformation describe-stacks \
--stack-name "$ADDON_STACK" \
--query "Stacks[0].Outputs[?OutputKey=='WebhookEndpointUrl'].OutputValue" \
--output text
```
The URL will look like: `https://abc123xyz.execute-api.us-east-1.amazonaws.com/api/google/webhook`
### Google Cloud Configuration
Configure your Google Cloud Pub/Sub push subscription to use OIDC authentication:
1. **Create or update the push subscription**:
```bash theme={null}
# Get the webhook URL from the previous step
WEBHOOK_URL="https://abc123xyz.execute-api.us-east-1.amazonaws.com/api/google/webhook"
gcloud pubsub subscriptions create gmail-push-subscription \
--topic=projects/YOUR_PROJECT/topics/gmail-notifications \
--push-endpoint="${WEBHOOK_URL}" \
--push-auth-service-account=YOUR_SERVICE_ACCOUNT@YOUR_PROJECT.iam.gserviceaccount.com \
--push-auth-token-audience="${WEBHOOK_URL}"
```
Or update an existing subscription:
```bash theme={null}
gcloud pubsub subscriptions modify-push-config gmail-push-subscription \
--push-endpoint="${WEBHOOK_URL}" \
--push-auth-service-account=YOUR_SERVICE_ACCOUNT@YOUR_PROJECT.iam.gserviceaccount.com \
--push-auth-token-audience="${WEBHOOK_URL}"
```
2. **Grant token creation permissions**:
```bash theme={null}
PROJECT_NUMBER=$(gcloud projects describe YOUR_PROJECT --format='value(projectNumber)')
gcloud projects add-iam-policy-binding YOUR_PROJECT \
--member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountTokenCreator"
```
### Custom Domain (Optional)
If you want to use a custom domain for the webhook endpoint:
1. Edit `copilot/environments/addons/addons.parameters.yml`:
```yaml theme={null}
Parameters:
WebhookAudience: 'https://webhook.yourdomain.com/api/google/webhook'
```
2. Set up a custom domain in API Gateway (via AWS Console or additional CloudFormation)
3. Update the Google Pub/Sub subscription with the custom domain URL
### Verification
Test that the endpoint correctly rejects unauthenticated requests:
```bash theme={null}
# This should return 401 Unauthorized
curl -X POST https://abc123xyz.execute-api.us-east-1.amazonaws.com/api/google/webhook
```
### Security Notes
| Aspect | Details |
| ------------------ | --------------------------------------------------------- |
| **Authentication** | Cryptographic JWT validation using Google's public keys |
| **Issuer** | Fixed to `https://accounts.google.com` |
| **Audience** | Must match exactly between AWS and Google configurations |
| **Token lifetime** | Google tokens are valid for up to 1 hour |
| **Throttling** | API Gateway applies rate limiting (50 req/sec, 100 burst) |
### Troubleshooting
**401 Unauthorized from API Gateway:**
* Verify the audience in Google Pub/Sub matches the AWS configuration exactly
* Check that the service account has `iam.serviceAccountTokenCreator` permissions
* Ensure the push subscription has OIDC authentication enabled
**502 Bad Gateway:**
* The VPC Link may not have connectivity to the ALB
* Check security group rules allow traffic from API Gateway to ALB
* Verify the ALB listener is healthy
**Logs:**
```bash theme={null}
# View API Gateway logs
aws logs tail /aws/apigateway/inbox-zero-app-production-webhook-api --follow
```
## Additional Resources
* [AWS Copilot Documentation](https://aws.github.io/copilot-cli/docs/)
* [Copilot Manifest Reference](https://aws.github.io/copilot-cli/docs/manifest/overview/)
* [Docker/VPS Deployment Guide](/hosting/self-hosting) - For local Docker setup
* [Google Pub/Sub Push Authentication](https://cloud.google.com/pubsub/docs/authenticate-push-subscriptions)
# EC2 Deployment
Source: https://docs.getinboxzero.com/hosting/ec2-deployment
Deploy Inbox Zero on AWS EC2 with ALB
This guide covers setting up Inbox Zero on AWS EC2 with an Application Load Balancer.
**Note:** This is a reference implementation. There are many ways to deploy on AWS (ECS, EKS, Elastic Beanstalk, etc.). Use what works best for your infrastructure and expertise.
## 1. Launch Instance
1. **Go to EC2 Console** and click **Launch Instances**.
2. **Name:** `inbox-zero` (or whatever you like)
3. **OS / AMI:**
* Select **Amazon Linux 2023** (Kernel 6.1 LTS).
4. **Instance Type:**
* **Test:** `t2.micro` or `t3.micro` (Free Tier, 1GB RAM).
* *Warning:* You **must** set up swap memory (see below) or the app will crash.
* **Production:** `t3.medium` (4GB RAM) or larger is recommended to avoid OOM kills.
5. **Key Pair:**
* Create a new key pair if you don't have one.
* **Name:** e.g., `inbox-zero`.
* **Type:** RSA, `.pem` format.
* **Permissions:** Run `chmod 400 ~/.ssh/your-key.pem` immediately after downloading.
6. **Network Settings:**
* Allow SSH traffic from **Anywhere** (or **My IP** if you have a static IP).
* *Note:* Using "Anywhere" is acceptable for test servers since you're using key-based authentication. For production, consider restricting to your office IP or VPN.
* Allow HTTP/HTTPS traffic from the internet.
7. **Storage:** Default (8GB) is usually fine for testing, but 20GB is safer for Docker images + logs.
## 2. Post-Launch Setup
### Elastic IP (Recommended)
EC2 public IPs change if you stop/start the instance. For a stable address:
1. Go to **Network & Security** -> **Elastic IPs**.
2. Click **Allocate Elastic IP address**.
3. Select the IP -> **Actions** -> **Associate Elastic IP address**.
4. Select your instance and associate.
### SSH Config
Add the server to your local `~/.ssh/config` to avoid typing long IPs.
```text theme={null}
Host inbox-zero-test
HostName
User ec2-user
IdentityFile ~/.ssh/inbox-zero.pem
```
Connect with: `ssh inbox-zero-test`
### Essential Server Setup (Amazon Linux 2023)
Once logged in, run these commands to prepare the server.
#### 1. Update & Install Required Tools
```bash theme={null}
sudo dnf update -y
sudo dnf install docker git -y
sudo service docker start
sudo usermod -a -G docker ec2-user
# You must log out and log back in for group changes to take effect
exit
```
#### 2. Install Node.js (Required if using setup CLI)
After logging back in, install Node.js:
**Note:** this is only needed if you want to run the setup CLI:
```bash theme={null}
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
sudo dnf install -y nodejs
```
#### 3. Install Docker Compose
```bash theme={null}
mkdir -p ~/.docker/cli-plugins
curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
# Verify it works
docker compose version
```
#### 4. Setup Swap Memory (CRITICAL for Micro Instances)
If you are using a `t2.micro` or `t3.micro` (1GB RAM), you MUST add swap or the build/runtime will crash.
```bash theme={null}
# Create a 4GB swap file
sudo dd if=/dev/zero of=/swapfile bs=128M count=32
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
```
## 3. SSL/HTTPS Setup
### Application Load Balancer (ALB)
You can also use nginx or any approach of your choice.
1. **Request SSL Certificate (AWS Certificate Manager):**
* Go to **AWS Certificate Manager** console
* Click **Request certificate** → **Request a public certificate**
* Enter your domain name (e.g., `app.yourdomain.com`)
* Choose **DNS validation** (easier) or **Email validation**
* Follow validation steps: AWS will provide a CNAME record to add to your DNS. Once added, the certificate will be issued in 5-10 minutes.
* Wait for certificate status to show **Issued**
2. **Create Target Group:**
* Go to **EC2 Console** → **Target Groups** → **Create target group**
* Name: e.g., `inbox-zero-web`
* Target type: **Instances**
* Protocol: **HTTP**, Port: **3000**
* Health check path: `/api/health`
* Click **Next**, select your EC2 instance, click **Include as pending below**, then **Next**, then **Create target group**
3. **Create Application Load Balancer:**
* Go to **EC2 Console** → **Load Balancers** → **Create load balancer**
* Choose **Application Load Balancer**
* Name: `inbox-zero-alb`
* Scheme: **Internet-facing**
* IP address type: **IPv4**
* Network mapping: Select at least 2 availability zones
* Security groups: Create/select one that allows HTTP (80) and HTTPS (443) from anywhere
* **Listeners:**
* Add listener: **HTTPS (443)** → Forward to your target group
* (Optional) Add listener: **HTTP (80)** → Redirect to HTTPS
* **Secure listener settings**: Select your ACM certificate
* Click **Create load balancer**
4. **Update DNS:**
* Wait for the ALB to finish provisioning (status: **Active**, takes 2-5 minutes)
* Find the ALB DNS name in **EC2 Console** → **Load Balancers** → click your ALB → copy the **DNS name**
* In your DNS provider, create a CNAME record:
* **Name:** Your domain/subdomain (e.g., `test` for `test.yourdomain.com` or `@` for root domain)
* **Target:** `` (e.g., `inbox-zero-alb-123456789.us-east-1.elb.amazonaws.com`)
* **Proxy status:** DNS only (if using Cloudflare DNS)
5. **Update Security Group:**
* Your EC2 instance security group should allow traffic from the ALB security group on port 3000
* Add a new port 3000 rule with source set to the ALB's security group (find it in ALB → Security tab)
* This allows only the ALB to access your app on port 3000, not the public internet
## 4. Deployment
Once your EC2 instance is set up with Docker, swap memory, and HTTPS, follow the deployment steps in the [Docker/VPS Deployment Guide](/hosting/self-hosting).
# Environment Variables
Source: https://docs.getinboxzero.com/hosting/environment-variables
Reference for self-hosting environment variables used in Inbox Zero
Reference for environment variables relevant to self-hosting Inbox Zero. Hosted-only billing, analytics, and internal operations variables are intentionally omitted unless they affect common self-hosted deployments.
## Self-Hosting Environment Variables
| Variable | Required | Description | Default |
| ------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| **Core** | | | |
| `DATABASE_URL` | Yes | PostgreSQL connection string | — |
| `DIRECT_URL` | No\* | Direct PostgreSQL connection used by Prisma migrations. Set this when your pooled `DATABASE_URL` cannot run migrations. Docker Compose sets it automatically. | `DATABASE_URL` |
| `DATABASE_URL_UNPOOLED` | No | Alternative unpooled PostgreSQL URL used by the app runtime in preview-style environments | — |
| `NEXT_PUBLIC_BASE_URL` | Yes | Public URL where app is hosted (e.g., `https://yourdomain.com`) | — |
| `INTERNAL_API_KEY` | Yes | Secret key for internal API calls. Generate with `openssl rand -hex 32` | — |
| `AUTH_SECRET` | Yes | better-auth secret. Generate with `openssl rand -hex 32` | — |
| `NODE_ENV` | No | Environment mode | `development` |
| **Encryption** | | | |
| `EMAIL_ENCRYPT_SECRET` | Yes | Secret for encrypting OAuth tokens. Generate with `openssl rand -hex 32` | — |
| `EMAIL_ENCRYPT_SALT` | Yes | Salt for encrypting OAuth tokens. Generate with `openssl rand -hex 16` | — |
| **Google OAuth** | | | |
| `GOOGLE_CLIENT_ID` | Yes | OAuth client ID from Google Cloud Console | — |
| `GOOGLE_CLIENT_SECRET` | Yes | OAuth client secret from Google Cloud Console | — |
| **Microsoft OAuth** | | | |
| `MICROSOFT_CLIENT_ID` | No | OAuth client ID from Azure Portal | — |
| `MICROSOFT_CLIENT_SECRET` | No | OAuth client secret from Azure Portal | — |
| `MICROSOFT_TENANT_ID` | No | Microsoft tenant used for OAuth (`common` for multi-tenant/personal-account support, or your tenant ID for single tenant) | `common` |
| `MICROSOFT_WEBHOOK_CLIENT_STATE` | No | Secret for Microsoft webhook verification. Generate with `openssl rand -hex 32` | — |
| **Slack** | | | |
| `SLACK_CLIENT_ID` | No | Slack OAuth client ID | — |
| `SLACK_CLIENT_SECRET` | No | Slack OAuth client secret | — |
| `SLACK_SIGNING_SECRET` | No | Slack signing secret used to verify requests | — |
| `NEXT_PUBLIC_SLACK_BOT_NAME` | No | Bot display name shown in the app | `Inbox Zero` |
| **Messaging Adapters** | | | |
| `TEAMS_BOT_APP_ID` | No | Microsoft Teams bot app ID | — |
| `TEAMS_BOT_APP_PASSWORD` | No | Microsoft Teams bot app password/secret | — |
| `TEAMS_BOT_APP_TENANT_ID` | No | Tenant ID, required when Microsoft Teams integration is enabled | — |
| `TELEGRAM_BOT_TOKEN` | No | Telegram bot token from BotFather | — |
| `TELEGRAM_BOT_SECRET_TOKEN` | No\* | Telegram webhook secret token sent in `x-telegram-bot-api-secret-token`. Required when `TELEGRAM_BOT_TOKEN` is set. | — |
| **Google PubSub** | | | |
| `GOOGLE_PUBSUB_TOPIC_NAME` | Yes | Full topic name (e.g., `projects/my-project/topics/gmail`) | — |
| `GOOGLE_PUBSUB_VERIFICATION_TOKEN` | Yes\* | Token for webhook verification | — |
| **Redis** | | | |
| `UPSTASH_REDIS_URL` | No\* | Upstash Redis URL or any Upstash-compatible HTTP Redis endpoint (\*required if not using Docker Compose with local Redis) | — |
| `UPSTASH_REDIS_TOKEN` | No\* | Upstash Redis token or serverless-redis-http token (\*required if not using Docker Compose) | — |
| `REDIS_URL` | No | Redis URL for subscriptions and the optional BullMQ worker | — |
| **Image Proxy (Optional)** | | | |
| `NEXT_PUBLIC_IMAGE_PROXY_BASE_URL` | No | Base URL for the optional remote-image proxy. Example: `https://img.example.com/proxy` | — |
| `NEXT_PUBLIC_IMAGE_PROXY_USE_APP_ROUTE` | No | Set to `true` to proxy remote images through the app's own Next.js route at `/api/image-proxy` instead of a separate proxy service | `false` |
| `IMAGE_PROXY_SIGNING_SECRET` | No | Shared HMAC secret used to sign proxy URLs for the bundled Cloudflare Worker or a compatible proxy. Proxy validators may use a comma-separated list, but each signer should still be configured with a single secret. | — |
| **LLM Provider Selection** | | | |
| `DEFAULT_LLMS` | Yes | Ordered default model list in `provider:model,provider:model` format. First valid entry is primary; later entries are fallbacks. | — |
| `ECONOMY_LLMS` | No | Ordered model list for cheaper operations | Falls back to `DEFAULT_LLMS` |
| `CHAT_LLMS` | No | Ordered model list for chat operations | Falls back to `DEFAULT_LLMS` |
| `NANO_LLMS` | No | Ordered model list for lightweight classification/extraction tasks | Falls back to economy/default |
| `DRAFT_LLMS` | No | Ordered model list for drafting replies | Falls back to `DEFAULT_LLMS` |
| `DEFAULT_OPENROUTER_PROVIDERS` | No | Comma-separated list of OpenRouter providers | — |
| `ECONOMY_OPENROUTER_PROVIDERS` | No | OpenRouter providers for economy model | — |
| `CHAT_OPENROUTER_PROVIDERS` | No | OpenRouter providers for chat | — |
| `DEFAULT_LLM_PROVIDER` | Deprecated | Legacy primary LLM provider. Converted into `DEFAULT_LLMS` at startup. | — |
| `DEFAULT_LLM_MODEL` | Deprecated | Legacy default model. Converted into `DEFAULT_LLMS` at startup. | Provider default |
| `DEFAULT_LLM_FALLBACKS` | Deprecated | Legacy default fallback chain. Converted into `DEFAULT_LLMS` at startup. | — |
| `ECONOMY_LLM_PROVIDER` | Deprecated | Legacy economy provider. Converted into `ECONOMY_LLMS` at startup. | — |
| `ECONOMY_LLM_MODEL` | Deprecated | Legacy economy model. Converted into `ECONOMY_LLMS` at startup. | — |
| `ECONOMY_LLM_FALLBACKS` | Deprecated | Legacy economy fallback chain. Converted into `ECONOMY_LLMS` at startup. | — |
| `CHAT_LLM_PROVIDER` | Deprecated | Legacy chat provider. Converted into `CHAT_LLMS` at startup. | — |
| `CHAT_LLM_MODEL` | Deprecated | Legacy chat model. Converted into `CHAT_LLMS` at startup. | — |
| `CHAT_LLM_FALLBACKS` | Deprecated | Legacy chat fallback chain. Converted into `CHAT_LLMS` at startup. | — |
| `NANO_LLM_PROVIDER` | Deprecated | Legacy nano provider. Converted into `NANO_LLMS` at startup. | — |
| `NANO_LLM_MODEL` | Deprecated | Legacy nano model. Converted into `NANO_LLMS` at startup. | — |
| `DRAFT_LLM_PROVIDER` | Deprecated | Legacy draft provider. Converted into `DRAFT_LLMS` at startup. | — |
| `DRAFT_LLM_MODEL` | Deprecated | Legacy draft model. Converted into `DRAFT_LLMS` at startup. | — |
| **LLM Provider Credentials** | | | |
| `LLM_API_KEY` | No | Shared fallback API key for simple single-provider setups; use provider-specific keys when mixing providers. | — |
| `ANTHROPIC_API_KEY` | No | Anthropic API key | — |
| `OPENAI_API_KEY` | No | OpenAI API key | — |
| `OPENAI_ZERO_DATA_RETENTION` | No | Pass OpenAI zero-data-retention provider options when your OpenAI account is approved for it | `false` |
| `GOOGLE_API_KEY` | No | Google Gemini API key | — |
| `GOOGLE_THINKING_BUDGET` | No | Override the thinking budget for Gemini 2.x/2.5 models used through Google, Vertex, or AI Gateway. Set to `0` to omit the budget. Gemini 3 models still use minimal thinking. | `128` |
| `GROQ_API_KEY` | No | Groq API key | — |
| `OPENROUTER_API_KEY` | No | OpenRouter API key | — |
| `AI_GATEWAY_API_KEY` | No | AI Gateway API key | — |
| `PERPLEXITY_API_KEY` | No | Perplexity API key for guest research for meeting briefs | — |
| **Azure OpenAI** | | | |
| `AZURE_API_KEY` | No | Azure OpenAI API key (required when `azure` is used and `LLM_API_KEY` is not set) | — |
| `AZURE_RESOURCE_NAME` | No | Azure OpenAI resource name (required when `azure` is used as a default or fallback provider) | — |
| `AZURE_API_VERSION` | No | Azure OpenAI API version override | — |
| **Azure AI Foundry** | | | |
| `AZURE_FOUNDRY_API_KEY` | No | Azure AI Foundry API key required when `azure-foundry` is used | — |
| `AZURE_FOUNDRY_BASE_URL` | No | Azure AI Foundry OpenAI-compatible base URL, such as `https://your-resource.services.ai.azure.com/openai/v1` | — |
| **Google Vertex** | | | |
| `GOOGLE_VERTEX_PROJECT` | No | Google Cloud project ID for Vertex AI (required when `vertex` is used as a default or fallback provider) | — |
| `GOOGLE_VERTEX_LOCATION` | No | Vertex AI location | `us-central1` |
| `GOOGLE_VERTEX_CLIENT_EMAIL` | No | Service account client email for Vertex auth (when not using ADC file) | — |
| `GOOGLE_VERTEX_PRIVATE_KEY` | No | Service account private key for Vertex auth (supports `\n` escaped newlines) | — |
| `GOOGLE_APPLICATION_CREDENTIALS` | No | Path to a Google service account JSON file for ADC/Vertex auth | — |
| **AWS Bedrock** | | | |
| `BEDROCK_ACCESS_KEY` | No | AWS access key for Bedrock. See [AI SDK Bedrock documentation](https://ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock). | — |
| `BEDROCK_SECRET_KEY` | No | AWS secret key for Bedrock | — |
| `BEDROCK_REGION` | No | AWS region for Bedrock | `us-west-2` |
| **Ollama (Local LLM)** | | | |
| `OLLAMA_BASE_URL` | No | Ollama API endpoint (e.g., `http://localhost:11434/api`) | — |
| `OLLAMA_MODEL` | No | Ollama model name when configured separately from the selected LLM tier model | — |
| **OpenAI-Compatible (Local LLM)** | | | |
| `OPENAI_COMPATIBLE_BASE_URL` | No | Base URL for an OpenAI-compatible server (e.g. LM Studio: `http://localhost:1234/v1`) | `http://localhost:1234/v1` |
| `OPENAI_COMPATIBLE_MODEL` | No | OpenAI-compatible model name when configured separately from the selected LLM tier model | — |
| `OPENAI_COMPATIBLE_AUTH_HEADER` | No | Header style for the OpenAI-compatible API key: `authorization` or `api-key` | `authorization` |
| **CLI LLM Providers (Experimental)** | | | |
| `CLI_LLM_ENABLED` | No | Enables community CLI-backed LLM providers (`codex-cli`, `claude-code`). Self-host only; requires installing optional provider packages. | `false` |
| `CODEX_CLI_ALLOW_NPX` | No | Allows the Codex community provider to fall back to `npx @openai/codex` if `codex` is not on PATH. Leave disabled unless you trust that install path. | `false` |
| `CODEX_CLI_PATH` | No | Optional path to the `codex` binary when using `codex-cli`. | — |
| **AI Content Controls** | | | |
| `SENSITIVE_DATA_POLICY_DEFAULT` | No | Default policy for handling sensitive data matches in LLM requests (`ALLOW`, `REDACT`, or `BLOCK`) | `ALLOW` |
| `NEXT_PUBLIC_SENSITIVE_DATA_POLICY_LOCKED` | No | Set to `true` to enforce the default policy for all accounts, disable account-level edits, and hide the setting in the UI | `false` |
| **Reasoning Retention** | | | |
| `REASONING_RETENTION_DAYS` | No | Number of days to keep stale AI reasoning fields before the daily reasoning-retention cron redacts them. Covers only `ExecutedRule.reason` and `DocumentFiling.reasoning`; group learnings and other stored content are not redacted. Leave unset to disable reasoning cleanup. | Disabled |
| `DRAFT_SENT_TEXT_RETENTION_DAYS` | No | Number of days to keep captured sent draft text before the daily reasoning-retention cron redacts it. | `14` |
| **Background Jobs (QStash, optional)** | | | |
| `QSTASH_TOKEN` | No | QStash API token (optional; fallback runs jobs via internal API + cron) | — |
| `QSTASH_CURRENT_SIGNING_KEY` | No | Current signing key for webhooks | — |
| `QSTASH_NEXT_SIGNING_KEY` | No | Next signing key for key rotation | — |
| `QUEUE_BACKEND` | No | Background job transport: `qstash`, `bullmq`, or `internal` | Auto-detect (`qstash` when configured, else `internal`) |
| **Sentry** | | | |
| `SENTRY_AUTH_TOKEN` | No | Auth token for source maps | — |
| `SENTRY_ORGANIZATION` | No | Organization slug | — |
| `SENTRY_PROJECT` | No | Project slug | — |
| `NEXT_PUBLIC_SENTRY_DSN` | No | Client-side DSN | — |
| **Resend** | | | |
| `RESEND_API_KEY` | No | API key for transactional emails | — |
| `RESEND_AUDIENCE_ID` | No | Audience ID for contacts | — |
| `RESEND_FROM_EMAIL` | No | From email address | `Inbox Zero ` |
| `NEXT_PUBLIC_IS_RESEND_CONFIGURED` | No | Client-side flag indicating if Resend is configured | — |
| **Meeting Recorder (Recall.ai, Optional)** | | | |
| `RECALL_API_KEY` | No\* | Recall.ai API key. Required with `RECALL_WEBHOOK_SECRET` when Meeting Recorder is enabled. | — |
| `RECALL_WEBHOOK_SECRET` | No\* | Signing secret for the Recall webhook at `/api/recall/webhook`. Required with `RECALL_API_KEY` when Meeting Recorder is enabled. | — |
| `RECALL_REGION` | No | Recall workspace region | `us-west-2` |
| `RECALL_BASE_URL` | No | Recall-compatible API base URL. Intended for local emulation; normal deployments should leave this unset. | Recall.ai regional API |
| **Other** | | | |
| `API_KEY_SALT` | No\* | Salt used to hash external API keys. Generate with `openssl rand -hex 32`. Required when `NEXT_PUBLIC_EXTERNAL_API_ENABLED=true`. | — |
| `CRON_SECRET` | No | Shared secret that authenticates calls to the scheduled-task endpoints (`/api/cron/*`, `/api/watch/all`, `/api/meeting-briefs`, `/api/meeting-recorder/schedule`, `/api/follow-up-reminders`, `/api/resend/digest/all`). Required if you trigger these endpoints yourself instead of using the bundled Docker Compose `cron` container. Generate with `openssl rand -hex 32`. See [Scheduled Tasks](/hosting/self-hosting#scheduled-tasks). | — |
| `HEALTH_API_KEY` | No | API key for health checks | — |
| `WEBHOOK_URL` | No | External webhook URL | — |
| `WEBHOOK_ALLOW_PRIVATE_IPS` | No | Allow rule webhooks to target private, loopback, link-local, or Tailscale addresses. This disables SSRF protection for webhook delivery; enable it only on a trusted single-tenant deployment. | `false` |
| `INTERNAL_API_URL` | No | Preferred callback base URL for QStash and server-side internal callbacks | `NEXT_PUBLIC_BASE_URL` |
| `OAUTH_PROXY_URL` | No | OAuth proxy deployment URL used when callbacks should route through a separate proxy server | — |
| `IS_OAUTH_PROXY_SERVER` | No | Marks this deployment as the OAuth proxy server | `false` |
| `ADDITIONAL_TRUSTED_ORIGINS` | No | Comma-separated additional trusted origins for auth/CORS, including wildcard origins such as `https://*.vercel.app` | — |
| **Digest Controls** | | | |
| `DIGEST_MAX_SUMMARIES_PER_24H` | No | Maximum digest summaries per email account in a rolling 24-hour window. Set to `0` to disable the cap. | `50` |
| **Admin & Access Control** | | | |
| `ADMINS` | No | Comma-separated list of admin emails | — |
| `AUTH_ALLOWED_EMAILS` | No | Comma-separated list of exact email addresses allowed to create new auth users. Useful for self-hosted or enterprise deployments that want to restrict sign-up. | Open sign-up |
| `AUTH_ALLOWED_EMAIL_DOMAINS` | No | Comma-separated list of email domains allowed to create new auth users (for example `company.com,subsidiary.org`). | Open sign-up |
| `AUTO_JOIN_ORGANIZATION_ENABLED` | No | Automatically add new users to the single organization on sign-up. Only enable this if your deployment explicitly wants automatic org membership. | `false` |
| `AUTO_ENABLE_ORG_ANALYTICS` | No | Default new organization memberships to analytics enabled | `false` |
| `SSO_LOGIN_ENABLED` | No | Show and allow SSO login. Configuring an SSO provider is a separate admin setup step. | `false` |
| `NEXT_PUBLIC_SELF_HOSTED_LOGIN_FOOTER_TEXT` | No | Self-hosted login footer notice. When unset, the default login footer notice is shown. Set to `none` to hide the notice. | Default notice |
| **Feature Flags** | | | |
| `NEXT_PUBLIC_CONTACTS_ENABLED` | No | Enable contacts feature | `false` |
| `NEXT_PUBLIC_EMAIL_SEND_ENABLED` | No | Enable email sending | `true` |
| `NEXT_PUBLIC_EXTERNAL_API_ENABLED` | No | Enable external API endpoints, API keys, and API key UI. Also set `API_KEY_SALT`. | `false` |
| `NEXT_PUBLIC_WEBHOOK_ACTION_ENABLED` | No | Enable outgoing webhook rule actions and the webhook-secret UI | `true` |
| `NEXT_PUBLIC_AI_MODEL_SETTINGS_DISABLED` | No | Hide user AI model settings and reject account-level changes. | `false` |
| `NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS` | No | Bypass premium checks (recommended for self-hosting) | `true` |
| `NEXT_PUBLIC_DIGEST_ENABLED` | No | Enable email digest feature, which sends periodic summaries of emails. Works without QStash (no retries). | `false` |
| `NEXT_PUBLIC_MEETING_BRIEFS_ENABLED` | No | Enable meeting briefs, which automatically sends pre-meeting briefings to users. Requires the meeting briefs cron job to be running. | `false` |
| `NEXT_PUBLIC_MEETING_RECORDER_ENABLED` | No | Enable the Early Access Meeting Recorder. Requires Recall.ai credentials, its signed webhook, and the meeting-recorder scheduling job. | `false` |
| `NEXT_PUBLIC_FOLLOW_UP_REMINDERS_ENABLED` | No | Enable follow-up reminders, which allows users to add labels to emails for automatic follow-up tracking. Requires the follow-up reminders cron job to be running. | `false` |
| `NEXT_PUBLIC_INTEGRATIONS_ENABLED` | No | Enable the integrations feature, allowing users to connect external services. | `false` |
| `NEXT_PUBLIC_SMART_FILING_ENABLED` | No | Enable the Smart Filing feature for automatic document organization from email attachments. | `false` |
| `NEXT_PUBLIC_CLEANER_ENABLED` | No | Enable the newer cleaner/bulk cleanup experience | `false` |
| `NEXT_PUBLIC_DELETE_EMAIL_ACTION_ENABLED` | No | Enable delete/trash actions for automation rules, including rules created through the external API. | `false` |
| `NEXT_PUBLIC_BOOKING_LINKS_ENABLED` | No | Enable first-party booking links and availability pages. | `false` |
| `NEXT_PUBLIC_AUTO_DRAFT_DISABLED` | No | Disable the auto-drafting feature, which automatically drafts replies based on assistant rules. | `false` |
| `NEXT_PUBLIC_TABS_EXTENSION_ID` | No | Chrome extension ID used for Inbox Zero Tabs sync | Built-in extension ID |
| **White Labeling (Optional)** | | | |
| `NEXT_PUBLIC_BRAND_NAME` | No | Brand name used in UI text and metadata | `Inbox Zero` |
| `NEXT_PUBLIC_BRAND_LOGO_URL` | No | Custom logo URL or public asset path (for example `/images/brand-logo.svg`) | Built-in Inbox Zero logo |
| `NEXT_PUBLIC_BRAND_ICON_URL` | No | Custom app icon URL or public asset path | `/icon.png` |
| `NEXT_PUBLIC_SUPPORT_EMAIL` | No | Contact email shown in support links and error messages | `support@getinboxzero.com` |
| **Debugging** | | | |
| `DISABLE_LOG_ZOD_ERRORS` | No | Disable logging Zod validation errors | — |
| `ENABLE_DEBUG_LOGS` | No | Enable debug logging | `false` |
| `NEXT_PUBLIC_LOG_SCOPES` | No | Comma-separated log scopes | — |
\* Conditional requirements:
* `DIRECT_URL` is required only when Prisma migrations need a direct/unpooled database URL that differs from `DATABASE_URL`.
* `API_KEY_SALT` is required only when external API keys are enabled with `NEXT_PUBLIC_EXTERNAL_API_ENABLED=true`.
* `TELEGRAM_BOT_SECRET_TOKEN` is required only when `TELEGRAM_BOT_TOKEN` is set.
* `RECALL_API_KEY` and `RECALL_WEBHOOK_SECRET` are both required when Meeting Recorder is enabled.
* `GOOGLE_PUBSUB_VERIFICATION_TOKEN` is required when Gmail Pub/Sub push is enabled. If your deployment authenticates `/api/google/webhook` upstream, you can set it to an empty string to intentionally disable query-parameter verification.
## Setup Guides
For detailed setup instructions, see the [Setup Guides](/hosting/setup-guides):
* [Google OAuth](/hosting/google-oauth)
* [Microsoft OAuth](/hosting/microsoft-oauth)
* [Enterprise SSO and SCIM](/hosting/sso)
* [Google PubSub](/hosting/google-pubsub)
* [LLM](/hosting/llm-setup)
## Notes
* If running the app in Docker and Ollama locally, use `http://host.docker.internal:11434/api` as the `OLLAMA_BASE_URL`.
* If running the app in Docker and an OpenAI-compatible server locally, replace `localhost` with `host.docker.internal` in `OPENAI_COMPATIBLE_BASE_URL`.
* CLI LLM providers are experimental and depend on third-party community AI SDK provider packages that spawn local CLI tools. Review their source, pin exact versions, and only enable them on trusted self-hosted deployments.
* When using Docker Compose with `--profile all`, database and Redis URLs are auto-configured. See the [Docker/VPS Deployment Guide](/hosting/self-hosting) for details.
* For image privacy, you can deploy the optional proxy separately and point `NEXT_PUBLIC_IMAGE_PROXY_BASE_URL` at it. See the [Image Proxy guide](/hosting/image-proxy).
* For Azure OpenAI, set `AZURE_RESOURCE_NAME` and either `AZURE_API_KEY` or `LLM_API_KEY` when using `azure` as a default or fallback provider.
* For Google Vertex, set `GOOGLE_VERTEX_PROJECT` when using `vertex` as a provider. For auth, use either `GOOGLE_APPLICATION_CREDENTIALS` (recommended for Node.js) or both `GOOGLE_VERTEX_CLIENT_EMAIL` and `GOOGLE_VERTEX_PRIVATE_KEY`. You do not need to set all three auth variables. See [AI SDK Google Vertex documentation](https://ai-sdk.dev/providers/ai-sdk-providers/google-vertex).
* `AUTH_ALLOWED_EMAILS` and `AUTH_ALLOWED_EMAIL_DOMAINS` only restrict creation of new auth users. They do not retroactively block existing users, and they do not replace invitation-based organization access control.
* If both auth allowlist variables are unset, sign-up remains open.
* You can combine exact email allowlisting with domain allowlisting. For example, allow `company.com` broadly while also permitting a few personal addresses such as founders or contractors.
# GCP + Cloudflare Tunnel
Source: https://docs.getinboxzero.com/hosting/gcp-cloudflare-tunnel
Deploy Inbox Zero on Google Cloud Compute Engine with Cloudflare Tunnel for HTTPS — no reverse proxy or SSL certificates required
This guide covers deploying Inbox Zero on a GCP Compute Engine VM using Cloudflare Tunnel for secure HTTPS access. Cloudflare Tunnel eliminates the need for a reverse proxy (Nginx/Caddy) and SSL certificate management — the tunnel connects outbound from your VM to Cloudflare's edge, so no inbound firewall ports need to be opened.
**Why Cloudflare Tunnel?**
* HTTPS with no Nginx, Caddy, or Let's Encrypt setup
* No public inbound ports required — the VM only makes outbound connections
* Free on Cloudflare's free plan
* Pairs naturally with GCP VMs running Gmail-integrated apps (same Google Cloud project)
## Prerequisites
* A [Google Cloud](https://console.cloud.google.com) account with billing enabled
* A [Cloudflare](https://cloudflare.com) account (free tier) with a domain managed by Cloudflare DNS
* SSH access to GCP (via `gcloud` CLI or browser-based SSH)
## 1. Create the Compute Engine VM
1. Go to **Compute Engine → VM instances → Create instance**
2. **Name:** `inbox-zero` (or your choice)
3. **Region/Zone:** choose one close to your users
4. **Machine configuration:**
* Minimum: `e2-medium` (2 vCPU, 4 GB RAM) — add swap if using this size
* Recommended: `e2-standard-2` (2 vCPU, 8 GB RAM)
5. **Boot disk:**
* OS: **Debian 12** or **Ubuntu 24.04 LTS**
* Size: **20 GB** minimum (Docker images + logs)
6. **Firewall:** leave HTTP and HTTPS checkboxes **unchecked** — Cloudflare Tunnel handles all ingress
7. Click **Create**
### Optional: Reserve a static external IP
GCP external IPs change if the VM is stopped. If you need SSH access from a fixed address, reserve a static IP under **VPC network → IP addresses** and attach it to the VM. Cloudflare Tunnel does not require a static IP.
## 2. Install Docker and Docker Compose
SSH into the VM and run:
```bash theme={null}
# Update packages
sudo apt-get update && sudo apt-get upgrade -y
# Install Docker Engine
curl -fsSL https://get.docker.com | sudo sh
# Allow your user to run docker without sudo
sudo usermod -aG docker $USER
newgrp docker
# Verify
docker --version
docker compose version
```
### Add swap (required for e2-medium)
If you're using `e2-medium` (4 GB RAM), add swap to avoid OOM kills:
```bash theme={null}
sudo dd if=/dev/zero of=/swapfile bs=128M count=32
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
```
## 3. Set Up Cloudflare Tunnel
### Create the tunnel
In the **Cloudflare dashboard**:
1. Go to **Zero Trust → Networks → Tunnels → Add a tunnel**
2. Choose **Cloudflared** as the connector type
3. Name the tunnel (e.g. `inbox-zero`)
4. Follow the install instructions for **Debian** — copy the `cloudflared` install command shown in the dashboard and run it on your VM:
```bash theme={null}
# Example — copy the exact command from the Cloudflare dashboard
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
```
5. Run the service install command shown in the dashboard. It looks like:
```bash theme={null}
sudo cloudflared service install
```
This registers `cloudflared` as a `systemd` service that starts automatically on boot.
### Configure the public hostname
Back in the Cloudflare dashboard tunnel settings:
1. Go to the **Public Hostnames** tab
2. Click **Add a public hostname**
3. **Subdomain:** e.g. `inbox` (resulting in `inbox.yourdomain.com`)
4. **Domain:** your Cloudflare-managed domain
5. **Service:** `http://localhost:3000`
6. Save — Cloudflare automatically adds a CNAME DNS record
Your app will be reachable at `https://inbox.yourdomain.com` once the tunnel is running and the app is started.
## 4. Set Up Inbox Zero
### Option A: CLI (recommended)
```bash theme={null}
# Install Node.js (required for the setup CLI)
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
# Run the setup wizard
npx @inbox-zero/cli setup
```
When prompted, enter your full Cloudflare Tunnel URL as the base URL (e.g. `https://inbox.yourdomain.com`).
### Option B: Manual
```bash theme={null}
git clone https://github.com/elie222/inbox-zero.git
cd inbox-zero
cp apps/web/.env.example apps/web/.env
nano apps/web/.env
```
Key variables to set:
```env theme={null}
# Your Cloudflare Tunnel public hostname
NEXT_PUBLIC_BASE_URL=https://inbox.yourdomain.com
# Google OAuth
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
# LLM provider/model
DEFAULT_LLMS=anthropic:claude-sonnet-4-5-20250929
ANTHROPIC_API_KEY=...
```
See the [Environment Variables reference](/hosting/environment-variables) for the full list.
## 5. Start the Application
```bash theme={null}
NEXT_PUBLIC_BASE_URL=https://inbox.yourdomain.com docker compose --profile all up -d
```
Check that all containers are up:
```bash theme={null}
docker ps
docker logs inbox-zero-services-web-1 -f
```
Startup takes 30–60 seconds. Once the web container logs show the Next.js server is ready, visit your Cloudflare URL.
## 6. Update Google OAuth Redirect URIs
In [Google Cloud Console → APIs & Services → Credentials](https://console.cloud.google.com/apis/credentials), open your OAuth client and add:
```
https://inbox.yourdomain.com/api/auth/callback/google
```
to the **Authorized redirect URIs** list.
## Maintenance
### Restart after a VM reboot
Both Docker (with `--restart unless-stopped` / Compose) and `cloudflared` run as systemd services and restart automatically. Verify with:
```bash theme={null}
systemctl status cloudflared
docker ps
```
### Update to the latest image
```bash theme={null}
docker compose pull
NEXT_PUBLIC_BASE_URL=https://inbox.yourdomain.com docker compose --profile all up -d
```
### View logs
```bash theme={null}
docker logs inbox-zero-services-web-1 -f
journalctl -u cloudflared -f
```
## Troubleshooting
**Tunnel shows as "Healthy" but site returns 502:**
* The app container may still be starting up — wait 60 seconds and refresh
* Check `docker logs inbox-zero-services-web-1` for startup errors
**Cloudflare Tunnel disconnected:**
* Check `journalctl -u cloudflared` for errors
* Verify the VM has outbound internet access (should work by default on GCP)
**Google OAuth redirect\_uri\_mismatch:**
* Ensure `NEXT_PUBLIC_BASE_URL` exactly matches the redirect URI registered in Google Cloud Console
* Must match the Cloudflare hostname including `https://`
For other issues, see the [Troubleshooting guide](/hosting/troubleshooting).
# Google OAuth
Source: https://docs.getinboxzero.com/hosting/google-oauth
Configure Google OAuth credentials, scopes, and required APIs
**Quick Setup with CLI:** If you have the `gcloud` CLI installed, run `inbox-zero setup-google` to automate API enabling and Pub/Sub setup. It will guide you through the OAuth steps that require manual console access.
Go to [Google Cloud Console](https://console.cloud.google.com/) and create a new project if necessary.
1. **Configure consent screen:**
Go to [Credentials](https://console.cloud.google.com/apis/credentials). If the banner shows up, click it and then click `Get Started`. Follow the prompts to name your app and set your contact email.
* **Internal** — Google Workspace only. All members of your organization can sign in without additional setup. Personal Gmail accounts cannot use Internal apps.
* **External** — any Google account, including personal Gmail. You'll need to add yourself as a test user (see step 5 below).
If you chose **External**: since your app is unverified (normal for self-hosted), you must add yourself as a test user (see step 5 below) before you can sign in. You'll also see a "This app isn't verified" warning screen when signing in — click "Advanced" then "Go to \[app name]" to proceed.
2. **Create OAuth credentials:**
1. Click `+Create Credentials` > `OAuth Client ID`.
2. Application Type: `Web application`.
3. Authorized JavaScript origins: `http://localhost:3000` (replace with your domain in production)
4. Authorized redirect URIs (replace `localhost:3000` with your domain in production):
* `http://localhost:3000/api/auth/callback/google`
* `http://localhost:3000/api/google/linking/callback`
* `http://localhost:3000/api/google/calendar/callback` (optional, for calendar)
* `http://localhost:3000/api/google/drive/callback` (optional, for Drive)
5. Click `Create` and copy the Client ID and secret.
3. **Update `.env` file:**
* Set `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`.
4. **Update [scopes](https://console.cloud.google.com/auth/scopes):**
1. Go to `Data Access` in the sidebar.
2. Click `Add or remove scopes`.
3. Manually add the core sign-in and Gmail scopes:
```
https://www.googleapis.com/auth/userinfo.profile
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/gmail.modify
https://www.googleapis.com/auth/gmail.settings.basic
```
4. Add only the optional feature scopes your deployment will use:
**Contacts** — only when `NEXT_PUBLIC_CONTACTS_ENABLED=true`:
```
https://www.googleapis.com/auth/contacts
```
**Calendar:**
```
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/calendar.events
https://www.googleapis.com/auth/calendar.freebusy
```
**Google Drive, Standard access** — lets Inbox Zero create folders and access files it created or the user explicitly opened with it:
```
https://www.googleapis.com/auth/drive.file
```
If users will select **Full access** when connecting Drive so they can choose existing folders, also declare:
```
https://www.googleapis.com/auth/drive
```
5. Click `Update`, then `Save`.
5. **Add yourself as a test user (External only):**
1. Go to [Audience](https://console.cloud.google.com/auth/audience).
2. In `Test users`, click `+Add users` and enter your email.
Skip this step if you chose Internal — all org members can sign in automatically.
6. **Enable required APIs:**
* [Gmail API](https://console.cloud.google.com/apis/library/gmail.googleapis.com) (required)
* [Google People API](https://console.cloud.google.com/marketplace/product/google/people.googleapis.com) (optional, for Contacts)
* [Google Calendar API](https://console.cloud.google.com/marketplace/product/google/calendar-json.googleapis.com) (optional)
* [Google Drive API](https://console.cloud.google.com/marketplace/product/google/drive.googleapis.com) (optional)
Next step for real-time notifications: [Google PubSub](/hosting/google-pubsub)
# Google PubSub
Source: https://docs.getinboxzero.com/hosting/google-pubsub
Configure Gmail push notifications with Google PubSub
**Automated Setup:** If you ran `inbox-zero setup-google`, the Pub/Sub topic and subscription were created automatically. Skip to the "For local development" section below.
Complete [Google OAuth](/hosting/google-oauth) first.
PubSub enables real-time email notifications so Inbox Zero is notified immediately when new emails arrive.
### 1. Create a topic
1. Go to the [Pub/Sub Topics page](https://console.cloud.google.com/cloudpubsub/topic/list) in Google Cloud Console.
2. Click **Create Topic**.
3. Enter a topic ID (e.g., `inbox-zero-emails`).
4. Click **Create**.
### 2. Grant Gmail publish access
Gmail needs permission to send notifications to your topic. This is the step that allows Google's servers to push email events into your Pub/Sub topic.
1. Click your topic name to open it.
2. Go to the **Permissions** tab (you may see it labeled "Info Panel" on the right side — look for the "Permissions" section).
3. Click **Add Principal**.
4. In the "New principals" field, enter: `gmail-api-push@system.gserviceaccount.com`
5. In the "Role" dropdown, select **Pub/Sub Publisher**.
6. Click **Save**.
`gmail-api-push@system.gserviceaccount.com` is Google's service account that sends Gmail push notifications. This is not your account — it's a Google-managed service account used by the Gmail API. See the [official docs](https://developers.google.com/gmail/api/guides/push#grant_publish_rights_on_your_topic) for more details.
### 3. Create a push subscription
1. In your topic, go to the **Subscriptions** tab.
2. Click **Create Subscription**.
3. Set the **Delivery type** to **Push**.
4. Set the **Endpoint URL** to: `https://yourdomain.com/api/google/webhook?token=TOKEN`
5. Click **Create**.
### 4. Update your environment variables
Set these in your `.env` file:
* `GOOGLE_PUBSUB_TOPIC_NAME` — the full topic name (e.g., `projects/your-project-id/topics/inbox-zero-emails`)
* `GOOGLE_PUBSUB_VERIFICATION_TOKEN` — the value of `TOKEN` you used in the webhook URL above
If your deployment protects `/api/google/webhook` with upstream authentication, you can set `GOOGLE_PUBSUB_VERIFICATION_TOKEN` to an empty string to intentionally disable query-parameter verification. Leaving it unset is treated as a misconfiguration.
### For local development
Use ngrok to expose your local server:
```bash theme={null}
ngrok http 3000
```
Then update the webhook endpoint in the [Google PubSub subscriptions dashboard](https://console.cloud.google.com/cloudpubsub/subscription/list) to use your ngrok URL (e.g., `https://abc123.ngrok.io/api/google/webhook?token=TOKEN`).
# Image Proxy
Source: https://docs.getinboxzero.com/hosting/image-proxy
Deploy the optional email image proxy for stronger privacy in web and desktop clients
Inbox Zero can proxy remote email images and CSS-loaded assets so senders do not see the end user's IP address when an email is rendered.
This is optional, but recommended if you host Inbox Zero for other people.
## What It Does
When enabled:
* Remote `img`, `srcset`, `background`, `poster`, inline `style`, and `