Apps Script doPost function unable to retrieve POST request data

I’m trying to connect a web form to Google Sheets using Apps Script. The form data should be sent via POST request and then added to my spreadsheet. Everything seems set up correctly but I’m getting errors.

Here’s my client-side code that sends the data:

const formData = {
  fullName: "jane smith",
  userEmail: "[email protected]",
  contactNumber: "9876543210",
  userMessage: "What time does the event begin?"
}

const webAppUrl = 'YOUR_WEB_APP_URL';

try {
  const result = await fetch(webAppUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: new URLSearchParams(formData)
  });

  if (result.ok) {
    console.log('Data sent successfully');
  } else {
    console.log('Failed to send data');
  }
} catch (err) {
  console.error('Request error:', err);
}

And here’s my Apps Script function:

function doPost(request) {
  Logger.log(JSON.stringify(request));
  var spreadsheet = SpreadsheetApp.openById('YOUR_SHEET_ID_HERE').getActiveSheet();
  var dataRow = [];

  dataRow.push(new Date());
  dataRow.push(request.parameter.fullName);
  dataRow.push(request.parameter.userEmail);
  dataRow.push(request.parameter.contactNumber);
  dataRow.push(request.parameter.userMessage);

  spreadsheet.appendRow(dataRow);

  var responseHeaders = {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type,Authorization"
  };

  return ContentService.createTextOutput("Data saved")
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders(responseHeaders);
}

When I test this with Postman, I get an error saying: “Unexpected error while getting the method or property openById on object SpreadsheetApp.” The spreadsheet ID is definitely correct though. What could be causing this issue?

Your content type doesn’t match your request body format. You’re setting Content-Type to ‘application/json’ but using URLSearchParams, which creates form-encoded data, not JSON. Apps Script can’t parse this mismatch properly. Fix it by either sending actual JSON with body: JSON.stringify(formData) and keeping the application/json header, or switch to ‘Content-Type’: ‘application/x-www-form-urlencoded’ to match URLSearchParams. I’ve hit this exact issue before - the content type mismatch was always the problem. Also check that your web app’s deployed with execute permissions set to ‘Anyone’ and access to ‘Anyone, even anonymous’ if you’re testing externally.

Had the same issue last month - turned out to be deployment settings and permissions. First, redeploy your web app after any changes (this trips up most people). The SpreadsheetApp error usually means your script can’t access the sheet. Open script editor and manually run doPost to trigger the auth dialog. Also check if your spreadsheet’s in a shared drive or has restricted access blocking the script. One more tip: log the entire request object to see what you’re actually getting. Sometimes the parameter structure isn’t what you expect, and seeing the raw data makes debugging way easier.

Double-check your spreadsheet ID and make sure the script has the right permissions. That openById error typically means either the ID’s wrong or your script can’t reach the sheet. Also verify you deployed the web app properly - it should run as you with access set to anyone.