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

# Google Sheets Integration

> Turn any Google Sheet into an automatic order source for Bodha Route Planner — no code, no OAuth, just share the sheet.

> [!NOTE]
>
> The Google Sheets integration is available on the **Pro** plan.

## Overview

Turn any Google Sheet into a live order source. Share your spreadsheet with Bodha Route Planner, map the columns, and rows become delivery orders in your inbox — automatically, on a schedule.

**Why teams love this:**

* Your dispatchers, sales team, or customers keep editing the same sheet they always have
* Bodha Route Planner reads new rows on each sync
* No code, no API, no OAuth consent screens — just share a sheet
* Works with any spreadsheet format you already have

| Feature | Detail |
| - | - |
| **Data flow** | Google Sheet → Bodha Route Planner Orders Inbox |
| **Auth** | Share with a service account email (no OAuth) |
| **Sync** | Configurable: 5 minutes to 24 hours, or manual |
| **Write-back** | Read-only — Bodha Route Planner never modifies your sheet |

***

## How it works

1. You share your Google Sheet with a Bodha Route Planner service account email address
2. You paste the sheet URL and pick which tab to read
3. Bodha Route Planner reads the **header row** (row 1) and shows you every column with a sample value
4. You **map** columns to Bodha Route Planner order fields (address, name, phone, etc.)
5. Bodha Route Planner reads the sheet on a schedule and turns new rows into orders
6. Orders land in your inbox, geocoded and ready to add to routes

> [!NOTE]
>
> **The sheet is read in full every sync.** Google Sheets has no change feed, so Bodha Route Planner reads all rows each time and uses deduplication to avoid creating duplicate orders. Edits to existing rows are picked up automatically.

***

## Setup

**1. Share your sheet**

When you open the Google Sheets integration in Bodha Route Planner, you'll see a service account email address like:

```
bodha-sheets@bodha-route-planner.iam.gserviceaccount.com
```

In Google Sheets:

1. Open the spreadsheet you want to connect
2. Click **Share** (top right)
3. Paste the service account email address
4. Set permission to **Viewer** (Bodha Route Planner only needs to read)
5. Click **Send**

> [!TIP]
>
> **Viewer is enough.** Bodha Route Planner never writes to your sheet — it only reads. No need to give Editor access.

**2. Connect in Bodha Route Planner**

1. Go to **Integrations** in the main navigation
2. Find **Google Sheets** and click **Connect**
3. Give the connection a name (e.g. "Daily Orders Sheet")
4. Paste your **Google Sheet URL** (the full URL from your browser's address bar)
5. Optionally, enter the **tab name** if you want to read a specific tab instead of the first one
6. Click **Test Connection** — Bodha Route Planner verifies it can read the sheet

**3. Map your columns**

Bodha Route Planner reads the header row and the first data row, and shows you every column with a sample value. Map each column to the matching Bodha Route Planner field:

| Bodha Route Planner field | What to map it to | Required |
| - | - | - |
| **Address** | Your delivery address column | **Yes** |
| **Address line 2** | Apartment, unit, or suite | No |
| **City** | City column | No |
| **State** | State/province column | No |
| **Postcode** | Postal/ZIP code column | No |
| **Country** | Country column | No |
| **Recipient name** | Customer or recipient name | No |
| **Email** | Customer email | No |
| **Phone** | Customer phone | No |
| **Order number** | Your reference/order ID column | No |
| **Delivery date** | Due date or delivery date | No |
| **Parcel count** | Number of packages | No |
| **Parcel weight** | Weight in kg | No |
| **Time window start** | Earliest delivery time (e.g. "09:00") | No |
| **Time window end** | Latest delivery time (e.g. "17:00") | No |
| **Notes** | Delivery instructions or notes | No |

> [!NOTE]
>
> **The header row is row 1.** Your first row must contain column names (Address, Name, Phone, etc.). Data starts from row 2. If your sheet doesn't have a header row, add one.

**4. Preview and confirm**

Click **Preview** to see what the first few rows will look like as orders. Check that addresses and details look correct.

When you're happy, click **Save**. The first sync runs immediately.

***

## Sync settings

| Setting | Default | Description |
| - | - | - |
| **Sync frequency** | 15 minutes | How often Bodha Route Planner reads the sheet. Range: 5 minutes to 24 hours. |
| **Auto-geocode** | On | Automatically geocode addresses when orders are ingested. |
| **Cutoff time** | None | After this time, new orders are flagged for the next day. |
| **Service area** | None | Only import orders within a radius of your depot. Orders outside are flagged "needs review". |

You can trigger a sync manually by clicking **Sync Now** on the integration page.

> [!WARNING]
>
> **Large sheets and frequent syncs:** Every sync reads the entire sheet. If your sheet has thousands of rows and syncs every 5 minutes, that's a lot of reads. For large sheets, consider a longer sync interval (30 minutes or hourly) or archiving old rows to a separate tab.

***

## How deduplication works

Since the entire sheet is read every sync, Bodha Route Planner needs to know which rows it has already seen.

### With a key column (recommended)

If you map an **Order number** or **Reference ID** column, that value is the unique key. The same reference always maps to the same order — editing the row updates the existing order instead of creating a new one.

**This is the best approach** because:

* You can reorder rows freely
* You can insert or delete rows without affecting other orders
* Editing an address updates the order rather than creating a duplicate

### Without a key column

If no key column is mapped, Bodha Route Planner generates an ID from the row's content (a hash of the address, name, phone, and email). This means:

* **Editing** an address creates a new order (because the hash changes)
* **Identical rows** are treated as one order (same hash = same order)
* The order survives rows being reordered or new rows being inserted

> [!TIP]
>
> **Best practice:** Always include an order number or reference ID column in your sheet and map it. Even a simple incrementing number (1, 2, 3...) works. This gives you the most predictable behavior when editing rows.

***

## Sheet format tips

### Dates

Bodha Route Planner recognizes these date formats in your sheet:

| Format | Example | Notes |
| - | - | - |
| **ISO** | `2026-10-29` | Always works |
| **Day/Month/Year** | `29/10/2026` or `29-10-2026` | Default interpretation |
| **Short year** | `29/10/26` | Two-digit year treated as 2000s |

> [!NOTE]
>
> Dates are interpreted as **day/month/year** by default. If your sheet uses month/day/year (US format), contact support to adjust the date parsing for your connection.

### Null values

These values in your sheet are treated as empty (not as literal text):

`\N`, `NULL`, `null`, `N/A`, `n/a`, `-`, `#N/A`

This is useful when your sheet is exported from a database or other tool that writes null markers.

### Blank rows

Blank rows (all cells empty) are automatically skipped. They don't create orders and don't cause errors.

### Rows without an address

Rows that have no value in the mapped **Address** column are skipped. They're treated as spacer rows, totals, or notes — not as orders.

***

## Multiple sheets

You can connect **multiple Google Sheets** as separate integrations. Each one has its own:

* Name
* Column mapping
* Sync frequency
* Service area

This is useful when:

* Different teams submit orders in separate sheets
* You have separate sheets for different regions or depots
* Customers send you their own spreadsheets

***

## What Bodha Route Planner can see

When you share a sheet with Viewer access, Bodha Route Planner can:

| Can do | Can't do |
| - | - |
| Read all rows and columns in the shared sheet | Modify any cell |
| Read all tabs (if no specific tab is named) | Delete rows or sheets |
| See formatting (but only uses cell values) | Access other files in your Google Drive |
| See new rows added after sharing | Share the sheet with anyone else |

The service account has **read-only** scope (`spreadsheets.readonly`). It cannot write to your sheet even if you grant Editor access.

***

## Troubleshooting

> **'Google refused access — share the sheet'**
>
> The sheet isn't shared with the Bodha Route Planner service account.
>
> 1. Open your Google Sheet
> 2. Click **Share**
> 3. Check that the service account email is listed with at least **Viewer** access
> 4. If not, add it and click Send
> 5. In Bodha Route Planner, click **Test Connection** again

> **'Google Sheets access is not switched on for Bodha yet'**
>
> This is a server-side configuration issue, not a problem with your sheet. The Google Sheets API needs to be enabled for the Bodha Route Planner Google project. Contact [support@bodharouteplanner.com](mailto:support@bodharouteplanner.com) — the team will enable it.

> **'That sheet or tab could not be found'**
>
> Either the sheet URL is wrong or the tab name doesn't match.
>
> * Check the URL you pasted — it should be the full URL from your browser
> * If you specified a tab name, make sure it matches exactly (case-sensitive)
> * Make sure the sheet hasn't been moved to trash

> **'The first row is empty'**
>
> Your sheet needs a header row in row 1 (Address, Name, Phone, etc.). Data starts from row 2.
>
> * Open your sheet and add column headers in row 1
> * Try the connection test again

> **Orders not updating when I edit the sheet**
>
> If you're editing existing rows and don't have a key column mapped:
>
> * Changing an address creates a **new** order (the content hash changed)
> * To enable true updates, add an Order Number column and map it
> * With a key column, editing any field on a row updates the existing order

> **Duplicate orders appearing**
>
> Check these common causes:
>
> 1. **No key column:** Map an Order Number column so each row has a stable identity
> 2. **Same data via two sources:** Are you also importing the same data via CSV or API?
> 3. **Tab name wrong:** You might be reading a different tab that has similar data

> **Old rows keep syncing**
>
> The entire sheet is read every sync. To stop old orders from being re-read:
>
> * Move completed/old rows to an archive tab
> * Use a cutoff time so only recent entries become today's orders
> * Or use a filter column: add a "Status" column and only map rows where Status is "New"

***

## Limits

| Limit | Value |
| - | - |
| **Connections per org** | No limit (one per sheet/tab) |
| **Columns read** | A through Z (26 columns) |
| **Rows per sync** | No hard limit (entire sheet is read) |
| **Sync frequency range** | 5 minutes – 24 hours |
| **Write-back** | Not available (read-only) |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.