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

# Read Data

> Load data from Google Sheets spreadsheets for use in your workflows.

**Read Data** retrieves data from your Google Sheets spreadsheets, making it available for processing in other workflow nodes. Essential for pulling existing data, reference lists, or configuration settings into your automation workflows.

***

## Inputs

| Field                  | Type       | Required | Description                                                        |
| ---------------------- | ---------- | -------- | ------------------------------------------------------------------ |
| **Spreadsheet URL/ID** | Text       | Yes      | Google Sheets document link or ID                                  |
| **Working Sheet**      | Select     | Yes      | Which sheet tab to read from                                       |
| **Load All Data**      | Switch     | Yes      | Read entire sheet or specify range/cell                            |
| **Selection Type**     | Select     | Yes\*    | Choose Range or Cell (\*Required when not loading all data)        |
| **Range**              | Text       | Yes\*    | Cell range to read (e.g., A1:B10) (\*Required for Range selection) |
| **Cell**               | Text       | Yes\*    | Single cell to read (e.g., A1) (\*Required for Cell selection)     |
| **Value Rendering**    | Select     | No       | How to format the retrieved values                                 |
| **Data Filters**       | Conditions | No       | Filter data based on column values and conditions                  |

***

## How It Works

This node connects to your Google Sheets and extracts data based on your specifications. The data becomes available for use in subsequent workflow nodes like text replacement, data analysis, or chart creation.

### Header Recognition

**Important:** When loading data from Google Sheets (either all data or specific ranges), the **first row is always treated as headers/column names**. This is crucial for:

* Column referencing in other nodes
* Proper data organization
* Data filtering functionality

Make sure your first row contains descriptive column names that you can easily reference when setting up filters or using the data in other workflow nodes.

### Data Selection Options

**Load All Data (Recommended):**

* Retrieves everything from the selected sheet
* Automatically includes headers and all rows
* Perfect for complete data processing

**Specific Range:**

* Target exact cell ranges (e.g., A1:C50)
* Useful for structured data sections
* Supports column ranges (A:C) or row ranges
* First row in the range is treated as headers

**Single Cell:**

* Read individual cell values
* Great for configuration settings or single metrics
* Returns the specific cell content
* No filtering available for single cells

***

## Range Format Examples

| Format     | Description          | Use Case            |
| ---------- | -------------------- | ------------------- |
| **A1:B10** | Cells A1 through B10 | Specific data table |
| **A:A**    | Entire column A      | Single column data  |
| **A:C**    | Columns A through C  | Multi-column data   |
| **A5:D20** | Rectangle of cells   | Data subset         |

***

## Value Rendering Options

**Unformatted Values (Default):**

* Raw data as stored in Google Sheets
* Numbers without formatting (1000 not \$1,000)
* Best for data processing and calculations

**Formatted Values:**

* Data as displayed in Google Sheets UI
* Includes currency symbols, percentage signs
* Good for presentation-ready content

**Formulas:**

* Returns the actual formulas instead of calculated values
* Shows =SUM(A1:A10) instead of the result
* Useful for formula analysis or copying

***

## Data Filtering

Filter your data using column names from the first row (headers) to get only the rows that meet your criteria. Filtering is available when loading all data or using range selection (not available for single cell selection).

### How Filtering Works

1. **Column Names:** Use the actual column names from your first row, not column letters (A, B, C). For example, if your first row contains "Campaign Name", "Clicks", "Cost", use these exact names.

2. **Case Sensitive:** Column names are case-sensitive. "Campaign Name" is different from "campaign name".

3. **Error Handling:** If a column name doesn't exist or there's an error in your filter conditions, the original unfiltered data is returned to ensure you still get your data.

### Available Filter Conditions

| Condition              | Description               | Example Use Case                      |
| ---------------------- | ------------------------- | ------------------------------------- |
| **EQUALS**             | Exact match               | Campaign Name equals "Summer Sale"    |
| **NOT\_EQUALS**        | Does not match exactly    | Status not equals "Paused"            |
| **CONTAINS**           | Contains the text         | Campaign Name contains "Sale"         |
| **DOES\_NOT\_CONTAIN** | Does not contain the text | Campaign Name does not contain "Test" |
| **STARTS\_WITH**       | Begins with the text      | Campaign Name starts with "2024"      |
| **ENDS\_WITH**         | Ends with the text        | Campaign Name ends with "Mobile"      |
| **GREATER\_THAN**      | Numeric comparison        | Clicks greater than 1000              |
| **LESS\_THAN**         | Numeric comparison        | Cost less than 500                    |
| **REGEXP\_MATCH**      | Regular expression match  | Campaign Name matches pattern         |
| **NOT\_REGEXP\_MATCH** | Does not match regex      | Campaign Name does not match pattern  |
| **IN\_LIST**           | Value is in a list        | Status in "Active,Paused"             |
| **NOT\_IN\_LIST**      | Value is not in a list    | Status not in "Deleted,Removed"       |
| **IS\_NULL**           | Cell is empty             | Notes is null                         |
| **IS\_NOT\_NULL**      | Cell has any value        | Notes is not null                     |

### Filter Examples

**Example 1: Active Campaigns Only**

* Column: "Status"
* Condition: "EQUALS"
* Value: "Active"

**Example 2: High-Performing Campaigns**

* Column: "Clicks"
* Condition: "GREATER\_THAN"
* Value: "1000"

**Example 3: Campaign Name Filtering**

* Column: "Campaign Name"
* Condition: "CONTAINS"
* Value: "2024"

**Example 4: Multiple Status Values**

* Column: "Status"
* Condition: "IN\_LIST"
* Value: "Active,Enabled,Running"

***

## Configuration Examples

### Read Complete Sheet

**Scenario:** Import all data from a marketing metrics sheet

**Configuration:**

* **Spreadsheet URL/ID:** Your Google Sheets link
* **Working Sheet:** "Marketing Metrics"
* **Load All Data:** On

**Result:** All data from the sheet becomes available for processing.

### Read Campaign Data Range

**Scenario:** Get specific campaign performance data

**Configuration:**

* **Load All Data:** Off
* **Selection Type:** "Range"
* **Range:** "A1:E50"
* **Value Rendering:** "Unformatted Values"

**Result:** Rows 1-50 of columns A-E are loaded for analysis.

### Read Configuration Value

**Scenario:** Get a single setting or metric

**Configuration:**

* **Load All Data:** Off
* **Selection Type:** "Cell"
* **Cell:** "B2"
* **Value Rendering:** "Formatted Values"

**Result:** Single cell value retrieved for use in workflow.

### Filter Active Campaigns

**Scenario:** Get only active campaigns from a marketing data sheet

**Configuration:**

* **Spreadsheet URL/ID:** Your Google Sheets link
* **Working Sheet:** "Campaign Data"
* **Load All Data:** On
* **Data Filters:**
  * Column: "Status"
  * Condition: "EQUALS"
  * Value: "Active"

**Result:** Only rows where the Status column equals "Active" are returned.

***

## Best Practices

### Sheet Organization

* **Use consistent headers** in row 1 for easy data processing
* **Keep data types consistent** within columns
* **Avoid merged cells** in data ranges for better processing
* **Use descriptive sheet names** for easy identification

### Range Selection

* **Start with Load All Data** for initial setup and testing
* **Use specific ranges** for performance optimization
* **Include headers** when selecting ranges for data context
* **Test ranges** with sample data before automation

### Data Quality

* **Clean your data** before reading (remove extra spaces, formatting)
* **Use consistent date formats** across your sheets
* **Avoid special characters** that might cause processing issues
* **Keep numeric data** as numbers, not text

### Data Filtering

* **Use descriptive column headers** in your first row for easy filtering
* **Keep column names consistent** and avoid spaces when possible
* **Test your filters** with a small dataset first
* **Use exact column names** from your sheet, not column letters
* **Remember column names are case-sensitive** when setting up filters

***

## Credit Cost

1 credit per successful run.

***

## FAQ

<Accordion title="What's the difference between loading all data vs. specific ranges?">
  **Load All Data** gets everything from the sheet automatically - headers, all rows, all columns. **Specific ranges** let you target exact sections, which is faster for large sheets and gives you precise control over what data you retrieve.
</Accordion>

<Accordion title="How do I find the right range for my data?">
  **Look at your Google Sheets directly.** Column letters are at the top (A, B, C...), row numbers on the left (1, 2, 3...). If your data is in columns A-D and rows 1-100, use "A1:D100". For entire columns, use "A:D".
</Accordion>

<Accordion title="Which value rendering option should I use?">
  **Use Unformatted Values for data processing** - calculations, analysis, sending to other systems. **Use Formatted Values when the data will be displayed** to people exactly as it appears in Google Sheets.
</Accordion>

<Accordion title="Can I read from multiple sheets at once?">
  **No, each Read Data node reads from one sheet at a time.** To read from multiple sheets, use multiple Read Data nodes in your workflow, each targeting a different sheet tab.
</Accordion>

<Accordion title="What happens if my range doesn't exist or is empty?">
  **The node will return an error** if the range is invalid (like Z999:AA1000 on a small sheet). **Empty ranges return no data** but don't cause errors. Always verify your ranges match your actual data.
</Accordion>

<Accordion title="How do I handle sheets with changing data sizes?">
  **Use column ranges like A:C** instead of fixed ranges like A1:C100. Column ranges automatically adjust to include all data in those columns, regardless of how many rows you have.
</Accordion>

<Accordion title="Do formulas in my sheet affect the data I read?">
  **By default, you get calculated values** from formulas. If cell A1 contains =B1+C1 and equals 10, you'll read "10". Choose "Formulas" in Value Rendering if you want the actual formula text instead.
</Accordion>

<Accordion title="How does header recognition work?">
  **The first row of your data is always treated as headers.** Whether you load all data or select a specific range, the first row becomes the column names you'll use for filtering and referencing. Make sure your first row contains clear, descriptive column names like "Campaign Name", "Clicks", "Cost" rather than generic labels.
</Accordion>

<Accordion title="How do I use column names in filters?">
  **Use the exact column names from your first row, not column letters.** If your first row has "Campaign Name", "Status", "Clicks", use these exact names in your filters. Column names are case-sensitive, so "Status" is different from "status". If you're unsure of the exact name, check your Google Sheets first row.
</Accordion>

<Accordion title="What happens if my filter has an error or the column doesn't exist?">
  **You'll get the original unfiltered data** to ensure you still receive your data. This happens when: the column name doesn't exist, there's a syntax error in your filter condition, or the filter value format is incorrect. Check your column names match exactly what's in your first row.
</Accordion>

<Accordion title="Can I use multiple filters at the same time?">
  **Yes, you can add multiple filter conditions.** All conditions must be met for a row to be included (AND logic). For example, you could filter for Status = "Active" AND Clicks > 1000 to get only active campaigns with high click counts.
</Accordion>
