DEV Community

Ankit Verma
Ankit Verma

Posted on

How to Send New Google Sheet Rows to a URL Automatically

Google Sheets is a powerful tool for collecting and managing data. But in many cases, you don’t want the data to just stay inside the sheet—you want it to automatically sync with your backend system, CRM, or API.

In this post, I’ll show you how to send new row data from Google Sheets to a URL endpoint in real-time.


Step 1: Open the Apps Script Editor

  1. Open your Google Sheet.
  2. From the menu, click Extensions > Apps Script.
  3. This opens the script editor where we’ll add our automation code.

Step 2: Add the Script

Paste the following script into the editor:

// Replace with the URL where you want to send the row data
const POST_URL = "https://your-endpoint-url.com/api/data"; 

// --- Use this function for MANUAL edits in the sheet ---
function pushData(e) {
  try {
    const range = e.range;
    const sheet = range.getSheet();
    const editedRow = range.getRow();

    // Stop the script if the edit is in the header row (row 1)
    if (editedRow === 1) {
      Logger.log('Edit was in the header row. Aborting.');
      return; 
    }

    // Use first row as keys (headers)
    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];

    // Get the full data from the edited row
    const rowData = sheet.getRange(editedRow, 1, 1, sheet.getLastColumn()).getValues()[0];

    // Build JSON payload
    const payload = {};
    headers.forEach((header, index) => {
      payload[header] = rowData[index];
    });

    // Add sheet name for context
    payload['sourceSheet'] = sheet.getName();

    // Send request
    const options = {
      method: 'post',
      contentType: 'application/json',
      payload: JSON.stringify(payload),
    };

    UrlFetchApp.fetch(POST_URL, options);
    Logger.log(`Row ${editedRow} sent successfully.`);

  } catch (error) {
    SpreadsheetApp.getActiveSpreadsheet().toast('Error: ' + error.message);
    Logger.log('Error sending data: ' + error.toString());
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Set Up the Trigger

  1. In the script editor, click the Triggers icon (clock symbol).
  2. Click + Add Trigger.
  3. Configure it like this:
    • Function: pushData
    • Event source: From spreadsheet
    • Event type: On form submit
  4. Save the trigger.

Step 4: Test It Out

Add a new row in your sheet. The script will push the full row as JSON to your URL.

Example JSON payload:

{
  "Name": "John Doe",
  "Email": "john@example.com",
  "Message": "Interested in your service",
  "sourceSheet": "Leads"
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

With this setup, your Google Sheet becomes a live data pipeline 🚀

Every new row is pushed instantly to your backend, CRM, or API without any manual effort.

if pushdata() not working properly use this

function pushData(e) {
  try {
    let sheet;
    let editedRow;

    // Check if the event object has a 'range' property (indicates an onEdit event).
    Logger.log('changeType pushData_new():');
    Logger.log(e.changeType);
    if (e.range) {
      sheet = e.range.getSheet();
      editedRow = e.range.getRow();
      // Stop the script if the edit is in the header row (row 1)
      if (editedRow === 1) {
        Logger.log('Edit was in the header row. Aborting.');
        return;
      }
    } 
    // If no 'range' property, check the changeType for a new row insertion.
    else if (e.changeType === 'INSERT_ROW') {
      sheet = e.source.getActiveSheet();
      editedRow = sheet.getLastRow();
      // Do not proceed if it's an empty sheet
      if (editedRow <= 1) { 
        Logger.log('No new data found on the sheet. Aborting.');
        return;
      }
    } else {
      // For any other change type, we exit the function.
      Logger.log('Change type not supported. Aborting.');
      return;
    }

    // Get the header row to use as JSON keys.
    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    // Get all the data from the identified row.
    const rowData = sheet.getRange(editedRow, 1, 1, sheet.getLastColumn()).getValues()[0];

    // Build the payload dynamically.
    const payload = {};
    headers.forEach((header, index) => {
      payload[header] = rowData[index];
    });

    // Add the sheet's name to the payload.
    payload['sourceSheet'] = sheet.getName();

    // Define the request options.
    const options = {
      'method': 'post',
      'contentType': 'application/json',
      'payload': JSON.stringify(payload)
    };

    // Send the data.
    UrlFetchApp.fetch(POST_URL, options);
    Logger.log(`Data from row ${editedRow} sent successfully.`);

  } catch (error) {
    SpreadsheetApp.getActiveSpreadsheet().toast('Error: ' + error.message);
    Logger.log('Error sending data on edit: ' + error.toString());
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)