Skip to content

Connecting mailboxes

Emails arrive in mailboxes connected to a project. There are three kinds:

Kind email_provider Connected by
Gmail gmail The mailbox owner signs in with Google (OAuth)
Outlook outlook The mailbox owner signs in with Microsoft (OAuth)
Cloudflare address cloudflare You add an address on one of our domains (below)

If the mailbox belongs to someone who has no clearance.rest account, send them an authorization link instead.

Connecting a mailbox is free. Each mailbox belongs to one project at a time.

  1. Set allowed return origins. In the console, open the project’s Settings and add the origins of the pages people will return to, such as https://app.example.com. A return_url whose origin is not listed is rejected with 400 invalid_return_url.

  2. Start the connection. From your backend call GET /emails/{email_provider}/oauth/start with the return_url and an optional client_state (up to 255 characters, returned to you untouched).

  3. Send the user’s browser to authorize_url. The user grants access on the provider’s page.

  4. Receive the user. The browser returns to return_url with result_token and your client_state appended, also when the connection failed.

  5. Read the outcome with GET /emails/{email_provider}/oauth/result?token=. A token works once and for 10 minutes.

curl -G https://api.clearance.rest/emails/gmail/oauth/start \
-H "X-API-Key: $CLEARANCE_REST_API_KEY" \
--data-urlencode "return_url=https://app.example.com/connected" \
--data-urlencode "client_state=$SESSION_ID"
curl -G https://api.clearance.rest/emails/gmail/oauth/result \
-H "X-API-Key: $CLEARANCE_REST_API_KEY" \
--data-urlencode "token=$RESULT_TOKEN"

The result is a successful read even when the connection failed:

{ "success": true, "status": "connected", "email": "[email protected]", "email_provider": "gmail", "error": null, "client_state": "abc" }
{ "success": true, "status": "failed", "email": null, "email_provider": "gmail", "error": { "code": "account_in_use", "message": "..." }, "client_state": "abc" }
error.code Meaning
access_denied The user declined or cancelled.
account_in_use The mailbox is already connected to another project.
no_refresh_token The provider did not grant offline access. Ask the user to try again.
profile_unavailable The mailbox address could not be read from the provider.
subscription_failed The mailbox was authorized, but new-mail notifications could not be set up. The mailbox is registered and we retry in the background.
platform_unavailable Connecting this kind of mailbox is not available right now.
provider_error The provider returned another error.

The permission requested depends on the project’s Allow marking emails as read setting; see Marking emails as read.

Instead of connecting an existing mailbox you can add an address on one of our domains. Nothing has to be authorized, and it is ready at once.

curl https://api.clearance.rest/emails/cloudflare/domains -H "X-API-Key: $CLEARANCE_REST_API_KEY"
# { "success": true, "domains": ["example.com"] }
curl -X POST https://api.clearance.rest/emails/cloudflare/accounts \
-H "X-API-Key: $CLEARANCE_REST_API_KEY" -H "content-type: application/json" \
-d '{ "email": "[email protected]" }'

The local part must match [a-z0-9][a-z0-9._+-]{0,63} and the domain must be one returned by GET /emails/cloudflare/domains, otherwise the request fails with 400 invalid_email_address or 400 domain_not_available. An address that is already taken is 409 email_account_exists. Addresses we host cannot mark emails as read.

Request
GET /emails/accounts List mailboxes. Filter by status, email_provider, email and metadata.
GET /emails/accounts/{email} One mailbox.
PATCH /emails/accounts/{email} Update its metadata.
POST /emails/accounts/{email}/disconnect Disconnect it from the project.
{
"id": "0190...",
"email": "[email protected]",
"email_provider": "gmail",
"status": "CONNECTED",
"last_error": null,
"subscription_expires_at": "2026-10-30T10:00:00.000Z",
"mark_as_read_authorized": true,
"project_id": "0190...",
"metadata": { "owner_id": "org_42" },
"metadata_version": 2,
"created_at": "2026-10-20T10:00:00.000Z",
"updated_at": "2026-10-25T10:00:00.000Z"
}
status Meaning
CONNECTED New mail is delivered to us. Addresses we host are always CONNECTED.
RENEWING The notification subscription has lapsed or is not set up yet; it renews automatically.
REAUTH_REQUIRED The last token refresh or sync failed (last_error says why). The owner may need to authorize again.

Tokens never appear in any response. Disconnecting asks the provider to stop notifications and removes the mailbox from the project; the mailbox itself is untouched.

Mailbox changes are announced by email_account.status_changed, email_account.assigned, email_account.unassigned, email_account.connected and email_account.metadata_updated. See Webhook events.