API Post Requests Return Unauthenticated?

Hi, I’m currently trying to get the results of POST api/card/card-id/query/json through node.js. I’m using Axios to request the information on a Metabase hosted locally. However, this doesn’t work and returns ‘unauthenticated’:

axios.post('http://localhost:3000/api/card/1/query/json', {
    headers: {
        'X-Metabase-Session':'90deb8c2-6eba-49ed-8e56-6cd5e881afb6'
    }
}).then(response => {
    console.log(response.data);
}).catch(err => {
    console.log(err);
});

The session token is a new one I just requested. POST requests to api/session work fine but any other POST always returns ‘unauthenticated’. I’ve also tried api/card/1/favorite and api/card/1/query. Am I missing something?

Hi @gliwidilt
Remember to set 'Content-Type': 'application/json' in the headers.

You might find some knowledge in these topics: How to access Metabase rest API using NodeJS and How to access metabase api using vue js

The best way to learn the API, is to just use Metabase while having your browser developer Network-tab open and looking at the request, and what data is being send/received.

Hi @flamber, thanks for the reply.

In subsequent tests I have added the content type so it now looks like this:

axios.post('http://localhost:3000/api/card/1/query', {

    headers: {

        'Content-Type': 'application/json',

        'X-Metabase-Session': 'd9f5a5da-5c2d-44e0-a528-e65979dd7f5c'

    }

}).then(response => {

    console.log(response.data);

}).catch(err => {

    console.log(err.response);

});

I’ve requested a new token thinking that was the problem, but it still returns 401 Unauthenticated. In the Metabase logs too, it just says 401 Unauthenticated. But if I use the CURL, i.e.:

CURL -X POST -H "Content-Type: application/json" -H "X-Metabase-Session: d9f5a5da-5c2d-44e0-a528-e65979dd7f5c" http://localhost:3000/api/card/1/query

it works just fine.

I’ve also taken a look at the Network tab and this is the CURL form of what I need:

curl 'http://localhost:3000/api/card/1/query' \
  -H 'Connection: keep-alive' \
  -H 'Accept: application/json' \
  -H 'DNT: 1' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://localhost:3000' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Referer: http://localhost:3000/question/1' \
  -H 'Accept-Language: en-US,en;q=0.9,id;q=0.8' \
  -H 'Cookie: metabase.SESSION_ID=8ba1d4e5-4fa3-41d3-95de-4a26cb6a731d' \
  --data-binary '{"ignore_cache":false,"parameters":[]}' \
  --compressed

Am I perhaps missing the ignore_cache and parameters params? I checked with the list of endpoints here but if I didn’t misunderstand ignore_cache isn’t mandatory. As for parameters, there’s nothing.

Any further help would be appreciated.

@gliwidilt If it works with cURL (the simple), then something in the Axios code isn’t behaving as it should.
Try capturing the request (Wireshark/tcpdump) and match cURL with Axios and try to spot the difference.

Thanks for answering! I managed to solve it without the need for Wireshark/tcpdump.

For anyone encountering a similar problem, somehow I solved it by using the other way to make POST requests in axios:

var config = {
    'Content-Type': 'application/json',
    'X-Metabase-Session': session_token     
};
var axiosOptions = {
    method: 'POST',
    url: 'http://localhost:3000/api/card/1/query',
    headers: config
};
axios(axiosOptions).then(response => {
    console.log(response.data);
}).catch(err => {
    console.log(err);
});

To be honest, I’m not sure why this works and axios.post() doesn’t, but it worked for me!

1 Like