Help

Re: How to post via API from google scripts

Solved
Jump to Solution
5589 0
cancel
Showing results for 
Search instead for 
Did you mean: 
David_Weinstein
5 - Automation Enthusiast
5 - Automation Enthusiast

I have the following code in a Google Scripts:

var data = {
    "records": [
          {
          "fields": {
              "Contract Address": "test",
              "0x8df3aad3a84da6b69a4da8aec3ea40d9091b2ac4": "1234"
          }
          }
    ]
};

var options = {
  "method" : "post",
  "payload" : data

};

function tryAPost(){
  var url = "https://api.airtable.com/v0/xxxxxxxxxxxxx/Balance%20Tracking?api_key=keyxxxxxxxxxx";
  var response = UrlFetchApp.fetch(url, options);
};

I get the following error:

Exception: Request failed for https://api.airtable.com returned code 422. Truncated server response: {"error":{"type":"INVALID_REQUEST_UNKNOWN","message":"Invalid request: parameter validation failed. Check your request data."}} (use muteHttpExceptions option to examine full response)

The authorization and URL work for a get request, and the data payload works in the body of post request in Postman.

What am I doing wrong?

1 Solution

Accepted Solutions
Bill_French
17 - Neptune
17 - Neptune

This is a common Google Apps Script pattern I use. The payload is a JSON object; serialization occurs within the function.

Note the use of constants for:

  • cMyAirtableAPIKey
  • cAirtableAPIEndpoint
//
// post to airtable (universal)
//
function atPostTable_(baseKey, tableName, payload)
{
  var options = 
      {
        method: 'POST',
        headers: {
          'Authorization' : 'Bearer ' + cMyAirtableAPIKey,
          'Content-Type'  : 'application/json'
        },
        payload : JSON.stringify(payload),
        muteHttpExceptions : true,
        followRedirects: true
      };
  var response = UrlFetchApp.fetch(cAirtableAPIEndpoint + baseKey + "/" + encodeURIComponent(tableName), options).getContentText();
  return(response);
}

See Solution in Thread

5 Replies 5
Mariusz_S
7 - App Architect
7 - App Architect
// Because payload is a JavaScript object, it is interpreted as
// as form data. (No need to specify contentType; it automatically
// defaults to either 'application/x-www-form-urlencoded'
// or 'multipart/form-data')

Since you’re passing a nested object and x-www-form-urlencoded does not support nested data structures you need to use JSON.

Please check this thread here

Thanks so much for responding! I don’t, however, understand. I thought my data variable was a JSON object. That structure of data works in Postman. Or, are you saying I have to restructure the headers?

As I understand and according to the documentation if you don’t specify the contentType it defaults to
'application/x-www-form-urlencoded' or 'multipart/form-data'
That’s why you’re getting error 422. The server can’t read that.

If the structure of encoded data is guaranteed to be a flat list of name-value pairs, x-www-form-urlencoded seems sufficient. If the structure could be (arbitrarily) complex (e.g. nesting lists or associative arrays), then definitely use JSON.

Since the data object in your example is a nested JSON object you need to use 'contentType': 'application/json' .

Bill_French
17 - Neptune
17 - Neptune

This is a common Google Apps Script pattern I use. The payload is a JSON object; serialization occurs within the function.

Note the use of constants for:

  • cMyAirtableAPIKey
  • cAirtableAPIEndpoint
//
// post to airtable (universal)
//
function atPostTable_(baseKey, tableName, payload)
{
  var options = 
      {
        method: 'POST',
        headers: {
          'Authorization' : 'Bearer ' + cMyAirtableAPIKey,
          'Content-Type'  : 'application/json'
        },
        payload : JSON.stringify(payload),
        muteHttpExceptions : true,
        followRedirects: true
      };
  var response = UrlFetchApp.fetch(cAirtableAPIEndpoint + baseKey + "/" + encodeURIComponent(tableName), options).getContentText();
  return(response);
}

I have an odd situation. When I send one or two records, it sends from GAS to AirTable quickly. But if I try to send more than 5 records at the same time, it bogs down to a crawl. There seems to be some kind of exponential processing going on because even just doing 10 records simultaneously lasts for a long time 30+ minutes. How can I send more than one record at the same time without AirTable slowing down to a crawl?