Help

Welcome to the Airtable Community! If you're new here, check out our Getting Started area to get the most out of your community experience.

Post to Airtable not working, but GET is OK

Topic Labels: API
Solved
Jump to Solution
6341 16
cancel
Showing results for 
Search instead for 
Did you mean: 

So this is what I am using to get my data from airtable

import axios from "axios"
formSubmitHandler = e => {
   
    axios
      .get(
        "https://api.airtable.com/v0/" + app_id + "/" + view,
        { headers: { Authorization: "Bearer " + app_key } },
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))
    e.preventDefault()
  }

This works very well, however when I try to post something into the same table and now using this:

formSubmitHandler = e => {
    const { name, email } = this.state
    const data = {
      "records": [
        {
          "fields": {
            "Name": name,
            "Email": email,
          }
        }
      ]
    }
    console.log(data)
    axios
      .post(
        "https://api.airtable.com/v0/" + app_id + "/" + view,
        { headers: { Authorization: "Bearer " + app_key } },
        data
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))
    e.preventDefault()
  }

It doesn’t work and I always get ERROR 401, and that shouldn’t be the case as I already managed to get the information out of my airtable.

Any ideas why this is happening?

Thank you,
Tiago

1 Solution

Accepted Solutions

Thank you! I think the order was the thing that was wrong!

const data = {
      "records": [
        {
          "fields": {
            "Name": name,
            "Email": email,
          }
        }
      ]
    }
    
    let url = "https://api.airtable.com/v0/" + app_id + "/" + view
    let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }
    axios
      .post(
        url,
        data,
        axiosConfig
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))

Like this works!
Thank you so much for the help!
Really appreciate!

See Solution in Thread

16 Replies 16

Hi @Tiago_Formosinho_San - not sure if Axios is taking care of this for you, but looking at the AT API, I think you need to set the Content-Type header in a POST request (not required in a GET).

curl -v -X POST https://api.airtable.com/v0/APP_ID/Events \
  -H "Authorization: Bearer API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "records": [
    {
      "fields": {
        "Name": "Event 1",
        "Date": "2019-09-16"
      }
    },
    {
      "fields": {
        "Name": "Event 2",
        "Date": "2019-10-01"
      }
    }
  ]
}' 

JB

Hi @JonathanBowen, thank you for the super prompt repy!
well, get also needs it

curl https://api.airtable.com/v0//MailingList/
  -H "Authorization: Bearer YOUR_API_KEY"
EXAMPLE RESPONSE
{
    "id": "recEx8a5ewvtGGF3u",
    "fields": {
        "Email": "tiago@tiago.test",
        "Name": "Tiago"
    },
    "createdTime": "2019-09-26T03:47:45.000Z"
}

and if I take out from my axios, it doesn’t work so I need to use it for the get.

 axios
      .get(
        "https://api.airtable.com/v0/" + app_id + "/" + view,
        { headers: { Authorization: "Bearer " + app_key } },
        {data}
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))

What I was trying to say was both GET and POST need this:

-H "Authorization: Bearer API_KEY" \

But it looks like POST also needs this:

-H "Content-Type: application/json" \

Have you tried a POST with “Content-Type: application/json”?

Yes, I have tried that as well…

axios
      .post(
        url,
        {
          headers: {
            "Authorization": "Bearer " + app_key,
            "Content-Type": "application/json"
          }
        },
        data
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))

But it does’t work :frowning:

Any other recommendation so that I can try?

Super thank you for the help.

@Tiago_Formosinho_San,

The error you mentioned (401) suggests your troubles are security related and that has me thinking Content-Type is probably not the issue.

Describe for me what the value of view looks like? Is it URL-encoded?

Thank @Bill.French!

const view = "MailingList"
const app_id = "MYAPPID"
const app_key = "MYAPPKEY"
const url = "https://api.airtable.com/v0/" + app_id + "/" + view;

The url would then be https://api.airtable.com/v0/MYAPPID/MailingList

Does it make sense?
I think that should be fine as it is working well for the get

Hi @Tiago_Formosinho_San - this worked for me:

<script type="text/javascript">

  const data = {
        "records": [
          {
            "fields": {
              "Name": "Event 7",
              "Date": "2019-10-02"
            }
          }
        ]
      };

  let axiosConfig = {
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY_HERE',
        'Content-Type': 'application/json'
    }
  };
axios.post('https://api.airtable.com/v0/YOUR_APP_ID_HERE/YOUR_TABLE_NAME_HERE', data, axiosConfig)
    .then(function (response) {
      // handle success
      console.log(response);
    })
    .catch(function (error) {
      // handle error
      console.log(error);
    })
    .finally(function () {
      // always executed
    });

</script> 

Can you work this into your code?

JB

(forget the “finally” function - not mandatory, I think. Was just copying some Axios boilerplate)

Looking at your code above you’ve got:

axios.post(url, config/headers, data)

I think you need:

axios.post(url, data, config/headers)

That looks okay but you might try using a table name instead of a view name. I say this only because I’m unsure about Axios requirements - best to eliminate this as a potential cause.

Since you’re getting a 401 are you absolutely sure that the API key of the user with access to the base granted read and write authority? This is unlikely to be the issue, but I always like to ask the obvious because that would cause the behavior you are experiencing - read/GET works, write/POST fails.

Thank you! I think the order was the thing that was wrong!

const data = {
      "records": [
        {
          "fields": {
            "Name": name,
            "Email": email,
          }
        }
      ]
    }
    
    let url = "https://api.airtable.com/v0/" + app_id + "/" + view
    let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }
    axios
      .post(
        url,
        data,
        axiosConfig
      )
      .then(resp => console.log(resp))
      .catch(error => console.log(error))

Like this works!
Thank you so much for the help!
Really appreciate!

Since you’re getting a 401 are you absolutely sure that the API key of the user with access to the base granted read and write authority? This is unlikely to be the issue, but I always like to ask the obvious because that would cause the behavior you are experiencing - read/GET works, write/POST fails.

@snow_jhon, nope the issue was that my axiosConfig was incomplete. ‘Content-Type’: ‘application/json’ needs to be there.

By the way, the reason I was trying to implement this was because I wanted to put a contact from in my blog. I actually wrote about it on this post https://tiagofsanchez.netlify.com/2019-10-06-blog-series-building-a-contact-form-with-airtable/ it anyone is keen to have a read.
Again, thank you for the help.

As a developer you get to create a database with a very nice to use interface.

I can confirm this was the exact problem and solution I had as well.

I think my issue was not wrapping the headers inside a property like you did:

    let axiosConfig = { headers: { Authorization: "Bearer " + app_key , 'Content-Type': 'application/json' } }

Mine was:

const headers = {
            'Authorization': `Bearer <apiKey>`,
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        };

        axios.post(url, data, headers).then((result) => {
            Log(result)
            let raw = formatRecords(result?.data?.records);
            state.value.record = raw;
            Log("state.value.records", state.value.records);
        }).catch(error => {
            loading.value = false;
            error.value = error;
        })

This makes sense, if axios was looking for a “headers” prop, but found no such prop.