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

# ETL: Gmail Source

> Configure the Gmail source component in Integrate.io ETL to read CSV or Excel attachments and email body content from a Gmail inbox into your pipelines.

Use the Google Mail (Gmail) source component to read CSV or Excel file attachments, or the email body itself, from a Gmail inbox and ingest them into your [Integrate.io](http://integrate.io/) ETL pipeline.

## Connection Setup

Integrate.io ETL supports two authentication methods for Gmail: a Google **Service Account** with domain-wide delegation, or **OAuth 2.0**. Use OAuth when you don't have Google Workspace Admin access or want to connect a personal Gmail account.

### Service Account (domain-wide delegation)

#### Step 1: Create a GCP Project

<Steps>
  <Step>
    Access your [Google Cloud Console](https://console.cloud.google.com/).
  </Step>

  <Step>
    Click the project dropdown at the top of the page and select existing project or create a **New Project**.
  </Step>

  <Step>
    If a new project is created, enter a project name (e.g. `my-gmail-connector`) and click **Create**. Make sure the newly created project is selected in the project dropdown before proceeding.

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-1.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=9b2e6f9319aa65b908478e06339dde3b" alt="Creating a new project in Google Cloud Console" width="1200" height="704" data-path="images/connectivity-and-security/google-mail-gmail/image-1.webp" />
    </Frame>
  </Step>
</Steps>

#### Step 2: Enable the Gmail API

<Steps>
  <Step>
    In the left sidebar, navigate to **APIs & Services → Library**.
  </Step>

  <Step>
    Search for **Gmail API**.
  </Step>

  <Step>
    Click the Gmail API result and click **Enable**.

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-2.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=acb1905f710e456b07e55a79a0d6d5dd" alt="Enabling the Gmail API in Google Cloud Console" width="1200" height="603" data-path="images/connectivity-and-security/google-mail-gmail/image-2.webp" />
    </Frame>
  </Step>
</Steps>

#### Step 3: Create a Service Account

<Steps>
  <Step>
    In the left sidebar, navigate to **IAM & Admin → Service Accounts**.

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-3.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=e18e17d8f411d43c24d698e6ef1bd151" alt="Creating a service account in Google Cloud Console" width="1200" height="766" data-path="images/connectivity-and-security/google-mail-gmail/image-3.webp" />
    </Frame>
  </Step>

  <Step>
    Click **+ Create Service Account**.
  </Step>

  <Step>
    Fill in the service account details:

    * **Name**: e.g. `gmail-connector-reader`
    * **Description**: e.g. `Service account for Integrate.io Gmail CSV connector`
  </Step>

  <Step>
    Click **Create and Continue**.
  </Step>

  <Step>
    Skip the optional role grant steps. Gmail access is controlled via domain-wide delegation, not IAM roles.
  </Step>

  <Step>
    Click **Done**.
  </Step>
</Steps>

#### Step 4: Enable Domain-Wide Delegation

<Steps>
  <Step>
    From the **Service Accounts** list, click the service account you just created.
  </Step>

  <Step>
    Go to the **Details** tab.
  </Step>

  <Step>
    Scroll down to **Advanced settings** and find the **Domain-wide Delegation** section.
  </Step>

  <Step>
    Click **Enable Google Workspace Domain-wide Delegation**.
  </Step>

  <Step>
    Enter a product name (e.g. `Integrate.io Gmail Connector`) and click **Save**.
  </Step>

  <Step>
    Note the **Client ID** displayed. This is the long numeric ID (e.g. `118304762983475829341`) you will need in Step 6.

    <Tip>**Finding the Client ID**: The Client ID is also available inside the JSON key file downloaded in Step 5, under the `client_id` field.</Tip>
  </Step>
</Steps>

#### Step 5: Download the JSON Key

<Steps>
  <Step>
    Still on the service account page, go to the **Keys** tab.
  </Step>

  <Step>
    Click **Add Key → Create new key**.
  </Step>

  <Step>
    Select **JSON** and click **Create**.
  </Step>

  <Step>
    A `.json` key file will be automatically downloaded to your machine. Keep this file secure; it contains the private key used to authenticate the service account.
  </Step>
</Steps>

The JSON file will contain a structure similar to:

```
{
  "type": "service_account",
  "project_id": "your-project",
  "private_key_id": "...",
  "private_key": "-----BEGIN RSA PRIVATE KEY-----\\n...",
  "client_email": "gmail-connector-reader@your-project.iam.gserviceaccount.com",
  "client_id": "118304762983475829341",
  ...
}
```

This is the file you will upload to Integrate.io in Step 7.

#### Step 6: Authorize the Scope in Google Workspace Admin

<Warning>This step requires **Google Workspace Admin** access to the organization whose Gmail you want to connect. If you are setting this up for a client, this step must be completed by their Workspace administrator.</Warning>

<Steps>
  <Step>
    Go to [admin.google.com](http://admin.google.com/) and sign in as a Workspace admin.
  </Step>

  <Step>
    Navigate to **Security → Access and data control → API controls**.
  </Step>

  <Step>
    Click **Manage Domain-Wide Delegation**.
  </Step>

  <Step>
    Click **Add new**.
  </Step>

  <Step>
    Enter the following:

    * **Client ID**: The numeric Client ID from Step 4 (e.g. `118304762983475829341`)
    * **OAuth scopes**: `https://www.googleapis.com/auth/gmail.readonly`
  </Step>

  <Step>
    Click **Authorize**.

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-4.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=ecac667cfda21e1b90670e41e163f147" alt="Authorizing API scopes in Google Workspace Admin" width="1200" height="416" data-path="images/connectivity-and-security/google-mail-gmail/image-4.webp" />
    </Frame>
  </Step>
</Steps>

This authorizes the service account to impersonate users in the domain and access their Gmail data on behalf of Integrate.io.

#### Step 7: Create the Gmail Connection in Integrate.io ETL

<Steps>
  <Step>
    Navigate to the **Connections** tab and click **Gmail.**

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-5.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=68807011c2cafebedffd3497196267c5" alt="Selecting Gmail from the connections list" width="1200" height="829" data-path="images/connectivity-and-security/google-mail-gmail/image-5.webp" />
    </Frame>

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-6.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=63baf298f077f7022aa03d3d9d5e38b8" alt="Gmail connection configuration form" width="1200" height="595" data-path="images/connectivity-and-security/google-mail-gmail/image-6.webp" />
    </Frame>
  </Step>

  <Step>
    Fill up the Connection Name
  </Step>

  <Step>
    Upload the JSON key you generated in Step 5.
  </Step>

  <Step>
    Click **Test Connection** and **Create Connection**

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-7.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=d93f7cd0301886f8e0ff65d3d9156a1d" alt="Uploading the JSON key file for Gmail connection" width="1200" height="1035" data-path="images/connectivity-and-security/google-mail-gmail/image-7.webp" />
    </Frame>
  </Step>
</Steps>

### OAuth 2.0

As an alternative to Service Account authentication, Integrate.io ETL also supports connecting to Gmail via OAuth 2.0. This is the recommended method when you don't have Google Workspace Admin access or want to connect a personal Gmail account.

<Steps>
  <Step>
    Navigate to the Connections tab and click + New connection.
  </Step>

  <Step>
    Search for and select **Gmail (OAuth)**.
  </Step>

  <Step>
    Click Authenticate.
  </Step>

  <Step>
    A Google sign-in popup will appear. Select the Google account you want to connect.
  </Step>

  <Step>
    Review the requested permissions.
  </Step>

  <Step>
    Once authentication completes, fill in the Connection Name (e.g. My Gmail OAuth).
  </Step>

  <Step>
    Click Test Connection to verify, then click Create Connection.

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-8.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=45caef05471320605e75e621b3598b40" alt="Gmail OAuth connection setup in Integrate.io" width="1200" height="600" data-path="images/connectivity-and-security/google-mail-gmail/image-8.webp" />
    </Frame>

    <Frame>
      <img src="https://mintcdn.com/integrateio/EbCNa5DlFLu_U6wb/images/connectivity-and-security/google-mail-gmail/image-9.webp?fit=max&auto=format&n=EbCNa5DlFLu_U6wb&q=85&s=b1b94735dbefc0c974403f38a4ba7cae" alt="Gmail OAuth connection completed" width="1200" height="597" data-path="images/connectivity-and-security/google-mail-gmail/image-9.webp" />
    </Frame>
  </Step>
</Steps>

Once created, the OAuth connection is maintained automatically: access tokens refresh every 30 minutes in the background, and a token that expires during a job run is renewed using the stored refresh token. To revoke access, remove Integrate.io from your [Google Account permissions](https://myaccount.google.com/permissions), or delete the connection from the Connections page (which also invalidates the refresh token).

## Source Properties

The source component is configured in Step 02 of the component editor.

<Frame>
  <img src="https://mintcdn.com/integrateio/vPmzup7uAj66abcx/images/creating-packages/using-components-google-mail-gmail-source/image-1.webp?fit=max&auto=format&n=vPmzup7uAj66abcx&q=85&s=70be5362794b8af38a4abfbf2b357383" alt="Gmail source component configuration" width="1200" height="1250" data-path="images/creating-packages/using-components-google-mail-gmail-source/image-1.webp" />
</Frame>

### Gmail Query

Enter a Gmail search query to filter which emails are fetched. This field supports all standard [Gmail search operators](https://support.google.com/mail/answer/7190).

Examples:

* `from:supplier@example.com has:attachment filename:*.csv`: CSV attachments from a specific sender
* `from:@example.com has:attachment filename:*.csv`: CSV attachments from any sender at a domain
* `subject:"monthly report" has:attachment filename:*.csv`: Emails with a specific subject
* `{from:alice@example.com <from:bob@example.com>} has:attachment filename:*.csv`: OR logic across multiple senders

<Tip>A space between operators means AND, so all conditions must match. Use `OR` (uppercase) or `{}` for OR logic between values of the same operator.</Tip>

### Read From

Select what to extract from each matching email:

* **Attachments.** Read CSV or Excel attachments from matching emails. Each row in the file becomes a row in the pipeline, with email metadata appended as extra columns. This is the default.
* **Email body.** Read each matching email as a single row. The body, subject, sender, recipient, date, and message ID are exposed as columns. No attachment is required.

Use **Email body** when the data you need lives in the email text itself (for example, transactional notifications, form submissions, or system alerts that don't carry a file). Use **Attachments** when partners or systems send tabular data as CSV or Excel files.

### File Type

This option appears only when **Read From** is set to **Attachments**. Select the format of the attachment files to ingest:

* **CSV.** Comma-separated values
* **Excel.** `.xlsx` / `.xls` spreadsheet files

### Delimiter, Quote Character, and Header Row

These options appear only when **Read From** is set to **Attachments** and **File Type** is **CSV**.

* **Delimiter.** Character that separates fields in the CSV file.
* **Quote character.** Character used to quote field values.
* **File contains a header row.** Check this box if the first row of the file contains column headers. When enabled, the connector uses the header row to name the schema fields. This is checked by default.

### Load Type

Select how records are loaded on each pipeline run:

* **Full Load.** Fetches all emails matching the Gmail query on every run.
* **Incremental Load.** Fetches only emails received after a reference date. The connector appends an `after:YYYY/MM/DD` operator to your Gmail query at runtime so that only new emails are returned by the Gmail API, keeping API usage low and execution fast.

### Incremental Load Settings

When **Incremental Load** is selected, the following options appear:

**Load records.** Select the filter condition:

* `newer than ( > )`: Fetch emails received after the reference date.

**Reference date.** Choose the source of the date value:

* **Last successful run.** Track emails received since the last successful run of this pipeline. Selecting this option auto-fills `incremental_load_date` with the `$_PACKAGE_LAST_SUCCESSFUL_JOB_SUBMISSION_TIMESTAMP` system variable, so each scheduled run picks up only what arrived since the previous run finished. Recommended for scheduled pipelines.
* **Fixed Date.** Select a specific calendar date using the date picker. Use this for a one-time historical backfill.
* **Variable.** Use a custom package variable as the reference date. Select this when you need to drive the start date from a value other than the last successful run timestamp.

<Warning>**Timezone note**: The Gmail `after:` operator interprets dates in **PST/PDT**, not UTC. If your variable is UTC-based, consider subtracting a 1-day buffer to avoid missing emails near the date boundary.</Warning>

## Schema

After configuring the source properties, the **Schema** section (Step 03) displays the fields available in the pipeline. The columns depend on the **Read From** mode.

### Attachments Mode

Schema fields are derived from the header row of the first matching email attachment. In addition to the columns from the file itself, the connector appends the following metadata columns to every row:

| Column               | Description                                 | Example                                                   |
| -------------------- | ------------------------------------------- | --------------------------------------------------------- |
| email\_message\_id   | Gmail message ID of the source email        | 18d4f2e3a7b1c9d0                                          |
| email\_date          | Date the email was received (ISO 8601, UTC) | 2026-03-10T14:30:00Z                                      |
| attachment\_filename | Original filename of the attachment         | sales\_report\_march.csv                                  |
| email\_from          | Sender email address                        | [supplier@example.com](mailto:supplier@example.com)       |
| email\_to            | Recipient email address                     | [reports@yourcompany.com](mailto:reports@yourcompany.com) |
| email\_subject       | Subject line of the email                   | Monthly Sales Report                                      |
| email\_body          | Plain-text body of the email                | Please find the report attached.                          |

These metadata columns let you trace each row back to its source email and file for deduplication and auditing downstream.

### Email Body Mode

Each matching email produces one row with the following columns:

| Column             | Description                                 | Example                                           |
| ------------------ | ------------------------------------------- | ------------------------------------------------- |
| email\_message\_id | Gmail message ID of the source email        | 18d4f2e3a7b1c9d0                                  |
| email\_date        | Date the email was received (ISO 8601, UTC) | 2026-03-10T14:30:00Z                              |
| email\_from        | Sender email address                        | [alerts@example.com](mailto:alerts@example.com)   |
| email\_to          | Recipient email address                     | [ops@yourcompany.com](mailto:ops@yourcompany.com) |
| email\_subject     | Subject line of the email                   | Order #12345 confirmed                            |
| email\_body        | Plain-text body of the email                | Your order has been confirmed...                  |

Use a downstream **Select** or **Cross Join with Function** component to parse fields out of `email_body` (for example, with regular expressions) when you need structured values from the email text.

### Example: Extract Order IDs from Notification Emails

Configure the source with:

* **Gmail query:** `from:notifications@example.com subject:"Order confirmed"`
* **Read From:** `Email body`
* **Load Type:** `Incremental Load` with `$package_last_successful_job_submission_timestamp` as the reference date

In a downstream **Select** component, extract the order ID from the body using a regular expression:

```text theme={null}
RegexExtract(email_body, 'Order #(\\d+)', 1) AS order_id
```
