Skip to main content

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

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 😦


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


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)


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 😦


Any other recommendation so that I can try?


Super thank you for the help.


Looking at your code above you’ve got:


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


I think you need:


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


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



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.


Looking at your code above you’ve got:


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


I think you need:


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



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


const data = {
"records": r
{
"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.


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.



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


const data = {
"records": c
{
"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!


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.


Reply