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.
Connect Gmail or Outlook
Section titled “Connect Gmail or Outlook”-
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. Areturn_urlwhose origin is not listed is rejected with400 invalid_return_url. -
Start the connection. From your backend call
GET /emails/{email_provider}/oauth/startwith thereturn_urland an optionalclient_state(up to 255 characters, returned to you untouched). -
Send the user’s browser to
authorize_url. The user grants access on the provider’s page. -
Receive the user. The browser returns to
return_urlwithresult_tokenand yourclient_stateappended, also when the connection failed. -
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"const { authorize_url } = await client.emails.oauthStart('gmail', { returnUrl: 'https://app.example.com/connected', clientState: sessionId,});// redirect the user's browser to authorize_url ...
const result = await client.emails.oauthResult('gmail', resultToken); // single use$start = $client->emails->oauthStart('gmail', returnUrl: 'https://app.example.com/connected', clientState: $sessionId);// redirect the user's browser to $start['authorize_url'] ...
$result = $client->emails->oauthResult('gmail', $_GET['result_token']); // single useThe result is a successful read even when the connection failed:
{ "success": true, "status": "connected", "email": "user@gmail.com", "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.
Addresses we host
Section titled “Addresses we host”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": "inbox@example.com" }'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.
Manage mailboxes
Section titled “Manage mailboxes”| 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": "user@gmail.com", "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.
Events
Section titled “Events”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.