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

# Get Credentials

> Step-by-step instructions for obtaining Zoho Mail OAuth 2.0 credentials.

This guide walks you through obtaining all required credentials for the Zoho Mail plugin.

## Authentication Method

The Zoho Mail plugin uses OAuth 2.0 authentication exclusively.

* **[`oauth_2`](/concepts/oauth)** (default) - OAuth 2.0 authentication

## Pick your region first

Zoho runs region-specific datacenters. The OAuth (`accounts.zoho.*`) and Mail API
(`mail.zoho.*`) hosts share the same top-level domain, and tokens issued in one
region do **not** work in another. Register the plugin with the matching `region`:

| Region        | Domain        | `region` value   |
| ------------- | ------------- | ---------------- |
| United States | `zoho.com`    | `'us'` (default) |
| Europe        | `zoho.eu`     | `'eu'`           |
| India         | `zoho.in`     | `'in'`           |
| Australia     | `zoho.com.au` | `'au'`           |
| Japan         | `zoho.jp`     | `'jp'`           |
| China         | `zoho.com.cn` | `'cn'`           |

```ts corsair.ts theme={null}
zohomail({ region: 'eu' })
```

Create the credentials below in the **same region's** API console (for example
`https://api-console.zoho.eu` for the EU).

## OAuth 2.0 Setup

### Step 1: Create a Server-based Application

1. Go to the [Zoho API Console](https://api-console.zoho.com/) for your region
2. Click **Add Client** → **Server-based Applications**
3. Fill in:
   * **Client Name**: your application name
   * **Homepage URL**: your application URL
   * **Authorized Redirect URIs**: your callback URL (e.g. `https://yourapp.com/auth/zohomail/callback`)
4. Click **Create**
5. Copy the **Client ID** and **Client Secret**

### Step 2: Authorize the required scopes

The plugin requests these scopes during the OAuth flow:

* `ZohoMail.messages.ALL` — read, send, move, delete, and flag emails
* `ZohoMail.folders.ALL` — list, create, update, and delete folders
* `ZohoMail.accounts.READ` — resolve the account ID for the authenticated user

Request `access_type=offline` so Zoho returns a **refresh token** (the plugin
refreshes the access token automatically as it expires).

<Tip>
  For quick local testing you can use the **Self Client** option in the API Console
  to mint an authorization code, then exchange it for access and refresh tokens
  without standing up a redirect endpoint.
</Tip>

### Step 3: Store credentials

The preferred method is to store OAuth credentials in the database using the keys API:

```ts theme={null}
await corsair.withTenant('default').keys.zohomail.setClientId('your-client-id');
await corsair.withTenant('default').keys.zohomail.setClientSecret('your-client-secret');
await corsair.withTenant('default').zohomail.keys.setAccessToken('your-access-token');
await corsair.withTenant('default').zohomail.keys.setRefreshToken('your-refresh-token');
```

Alternatively, you can provide credentials directly in the plugin configuration:

```ts corsair.ts theme={null}
zohomail({
    authType: "oauth_2",
    region: "us",
    credentials: {
        clientId: process.env.ZOHO_CLIENT_ID,
        clientSecret: process.env.ZOHO_CLIENT_SECRET,
        accessToken: process.env.ZOHO_ACCESS_TOKEN,
        refreshToken: process.env.ZOHO_REFRESH_TOKEN,
    },
})
```

## Required Credentials Summary

| Credential    | Required For | Where to Find                                                            |
| ------------- | ------------ | ------------------------------------------------------------------------ |
| Client ID     | OAuth 2.0    | Zoho API Console → your app                                              |
| Client Secret | OAuth 2.0    | Zoho API Console → your app                                              |
| Access Token  | OAuth 2.0    | Obtained automatically after OAuth flow                                  |
| Refresh Token | OAuth 2.0    | Obtained automatically after OAuth flow (requires `access_type=offline`) |

For general information about how Corsair handles authentication, see [Authentication](/concepts/auth).
