Scheduling and Route Planning Updating Monday.com with Route Schedules

Once your route schedules and drive times are calculated, the final step is pushing that data back to your Monday.com board. This guide walks you through building and executing batched GraphQL mutations to update planned start and end times, driver departure/arrival times, and route metadata.

By batching these updates into a single "atomic" request, you ensure your board updates instantly while minimizing API calls.

Monday.com API Reference

Learn more about the Monday.com GraphQL API and column types.

Update Workflow

The update process follows a specific sequence to ensure stale data is removed before new route times are applied.

flowchart TD
    A[Calculate Route Times] --> B[Generate Google Maps Link]
    B --> C["Build Wipe Mutations (Clear Old Data)"]
    C --> D["Build Update Mutations (Set New Times)"]
    D --> E[Send Batched GraphQL Request]
    E --> F["Monday.com Board Updated"]

Understanding the Metadata

Before building the mutations, it helps to understand the column values we are updating on the Monday.com board:

Data PointColumn TypeDescription
Planned Start/EndTimeline / TextThe calculated arrival and departure time for a specific stop.
Leave TimeText / HourThe time the driver leaves their starting location (applied only to the first stop).
Home TimeText / HourThe time the driver returns home (applied only to the last stop).
Drive TimeNumericThe travel time in minutes to reach the stop.
Route LinkLinkA generated Google Maps URL containing all stops for the driver's day.
ActionStatusFlags for special conditions, such as Overtime 🚩.

Implementation Steps

Follow these steps to construct your Python script for updating Monday.com.

  1. 1

    Generate the Route Link

    First, create a single Google Maps URL that includes the driver's starting location, all routed stops, and their ending location. This provides a convenient clickable link directly inside Monday.com.

  2. 2

    Clear Previous Metadata

    If an item was previously routed but the schedule has changed, you need to clear the old data. Build a "wipe" mutation for these items to reset their columns to empty values.

  3. 3

    Build the Update Mutations

    Loop through your calculated route results. For each stop, build a mutation that applies the new PLANNED_START_COL and PLANNED_END_COL.

    During this loop, identify the first and last stops to apply the LEAVE_TIME_COL and HOME_TIME_COL respectively.

  4. 4

    Execute the Atomic Update

    Combine all your wipe and update mutations into a single GraphQL query string and send it to the Monday.com API via a POST request.

Code Example

Here is a streamlined Python example demonstrating how to batch these mutations.

Double JSON Encoding: Notice the use of json.dumps(json.dumps(col_vals)) in the code below. This is not a typo! Monday.com's GraphQL API requires the column_values argument to be passed as an escaped JSON string.

import json
import requests
import urllib.parse

# 1. Generate the Google Maps Link
locations = [start_addr] + routed_stops + [driver_home]
maps_link = "https://www.google.com/maps/dir/" + "/".join([urllib.parse.quote(a) for a in locations])

mutations = []

# 2. Build Wipe Mutations (Clear old data)
for item_id, meta in items_to_wipe.items():
    # Reset columns to empty strings or None
    w_vals = {
        ACTION_COL: None, 
        LEAVE_TIME_COL: "", 
        HOME_TIME_COL: "", 
        PLANNED_START_COL: "", 
        PLANNED_END_COL: ""
    }
    
    # Prefix the alias with 'w_' to ensure unique mutation names
    mut_str = f'w_{item_id}: change_multiple_column_values(item_id: {item_id}, board_id: {UPDATE_BOARD_ID}, column_values: {json.dumps(json.dumps(w_vals))}) {{ id }}'
    mutations.append(mut_str)

# 3. Build Update Mutations (Apply new route data)
for i, route in enumerate(results):
    col_vals = {
        PLANNED_START_COL: str(route['s']), 
        PLANNED_END_COL: str(route['e']),
        "link_mm27c2k0": {"url": maps_link, "text": "Route"}
    }
    
    # Add drive time if available
    if 'dr' in route: 
        col_vals["numeric_mm1drhtc"] = int(route['dr'])
        
    # Apply Leave Time to the first stop (index 0)
    if i == 0: 
        col_vals[LEAVE_TIME_COL] = route.get('l_time', "")
        
    # Apply Home Time to the last stop
    if i == len(results) - 1: 
        col_vals[HOME_TIME_COL] = str(final_home_dt)
        
    # Flag Overtime if the final home time exceeds the goal
    if "early stop" in route['name'].lower() and final_home_dt > es_goal: 
        col_vals[ACTION_COL] = {"label": "Overtime 🚩"}

    # Prefix the alias with 'u_' to ensure unique mutation names
    mut_str = f'u_{route["id"]}: change_multiple_column_values(item_id: {route["id"]}, board_id: {UPDATE_BOARD_ID}, column_values: {json.dumps(json.dumps(col_vals))}) {{ id }}'
    mutations.append(mut_str)

# 4. Execute the Atomic Update
if mutations:
    query = 'mutation { ' + ' '.join(mutations) + ' }'
    response = requests.post(
        "https://api.monday.com/v2", 
        json={'query': query}, 
        headers=headers
    )

GraphQL Aliases: In the example above, we use w_{item_id}: and u_{route["id"]}: at the start of each mutation. GraphQL requires unique aliases when executing multiple operations of the same type (like change_multiple_column_values) in a single request.

Frequently Asked Questions

Why do we wipe metadata before updating?

If a job is rescheduled, cancelled, or moved to a different day, residual data (like a driver's leave time from a previous routing attempt) might persist on the board. Wiping ensures the board strictly reflects the newest route calculation.

How is the Overtime flag triggered?

The script checks if the final calculated home time (final_home_dt) exceeds a predefined early stop goal (es_goal). If the driver is scheduled to arrive home later than this threshold, the ACTION_COL is updated with a status label of Overtime 🚩.

What are NOE items?

NOE (Notice of Entry) items are specific calendar events or administrative stops that don't require standard planned start/end times. For these items, the script typically skips assigning time blocks and only attaches the generated route link.