Name is required.
Email address is required.
Invalid email address
Answer is required.
Exceeding max length of 5KB

POST in API Profile

I'm trying to use POST in an API profile for the first time and I'm failing ...

Here is the curl command I am trying to mimic:

curl -d "grant_type=refresh_token" https://app.teem.com/oauth/token/

This API actually expect more than 1 post parameter and this specific example is expected to return a Missing refresh parameter error. If I could that error in Matillion, I'd be making progress. However, the error I get in Matillion is unsupported_grant_type, which occurs when you don't send a grant_type at all.

My rsd looks like this:

...
<rsb:set attr="uri" value="https://app.teem.com/oauth/token/" />
<rsb:script method="GET">
<rsb:set attr="method" value="POST" />
<rsb:set attr="data">
"grant_type":"refresh_token"
</rsb:set>
<rsb:call op="jsonproviderGet">
<rsb:push/>
</rsb:call>
</rsb:script>

I've also tried adding:

<rsb:set attr="ContentType" value="application/json; charset=UTF-8" />

but that made no difference.

Can you suggest why my post is not working?

10 Community Answers

Matillion Agent  

Arawan Gajajiva —

Hi Quinn -

In reviewing the documentation for the API you are trying to integrate with, I think your RSD should look like this:

<rsb:set attr="uri" value="https://app.teem.com/oauth/token/?client_id=$APP_ID&amp;client_secret=$APP_SECRET&amp;refresh_token=$REFRESH_TOKEN&amp;grant_type=refresh_token" /> 
<rsb:script method="GET">
  <rsb:set attr="method" value="POST" />
<rsb:call op="jsonproviderGet">
<rsb:push/>
</rsb:call>
</rsb:script>  

This API is looking for a POST, but it does not accept JSON for the POST body. Using your “curl” statement as an example, it is performing a POST, but the ContentType is “application/x-www-form-urlencoded”. This ContentType essentially emulates submitting the values from a web form similar to the way one would pass query parameters in a GET request. The above example emulates submitting the values as query parameters in the URI, but preserves the “POST” http method. Note that the URI needs to be URL encoded, which is why “&” is used instead of a “&” to separate the query parameters in the URI.

Your original RSD would be correct if the API endpoint expects JSON as the Content Type for the POST body.

Give the above a try and let us know if this helps.

Best regards,
Arawan


Quinn Wildman —

Yeah, I knew about the additional parameters. I was just trying to make it ultra simple by including only 1. As I said, including only the grant type should produce the Missing refresh parameter error, which it now does. By removing data from post and putting it in the URI instead, this indeed does resolve this issue. Thanks.


Quinn Wildman —

OK, you definitely resolved my initial question, however; now it appears my problem is the refresh_token is not being sent correctly somehow, as I'm getting the same error (invalid grant) if my refresh token is incorrect. I've tried this is 3 similar ways:

<rsb:set attr="uri" value="[userns.api]?grant_type=refresh_token&amp;client_secret=[userns.client_secret]&amp;client_id=[userns.client_id]&amp;refresh_token=<hard coded token here>" />

<rsb:set attr="uri" value="[userns.api]?grant_type=refresh_token&amp;client_secret=[userns.client_secret]&amp;client_id=[userns.client_id]&amp;refresh_token=[userns.refresh_token]" />

<rsb:set attr="uri" value="[userns.api]?grant_type=refresh_token&amp;client_secret=[userns.client_secret]&amp;client_id=[userns.client_id]&amp;refresh_token=[_input.refresh_token]" />

I've got an API Profile using a job variable for the last one.

I've fiddled with this enough to believe that client_secret and client_id are being send correctly, as I've gotten the correct errors when I intentionally set them incorrectly.


Matillion Agent  

Arawan Gajajiva —

Hi Quinn -

Can you share an example refresh token? I’m wondering if perhaps the value needs to be url encoded. Have you tried validating the full call through “curl”, like you did initially? That’s always a helpful validation as well.

Thanks,
Arawan


Quinn Wildman —

Yes, I have verified curl works.

Here is a sample refresh token:

0YZz5MGpwXcpgABLYp1IpnWGBgQgS9


Matillion Agent  

Arawan Gajajiva —

Hi Quinn -

Thanks, it does not look like the refresh token needs to be url encrypted, so something else must be going on. Can you test by hardcoding the client id, client secret and refresh token values into your URI, and confirm if that works? If that test is successful, then we should look at how you are passing in the refresh token into the API call. If you still have the same behavior with hardcoded values, then that tells us something else is wrong with the way the URI is structured.

I tried testing with hardcoded values, but since I don’t have a client id or client secret, i ended up wit an error of “invalid client”.

Best regards,
Arawan


Quinn Wildman —

I tried hard coding the values, but I got the same problem. I am going to create a support ticket so my data isn't public.


Matillion Agent  

Arawan Gajajiva —

Hi Quinn -

Thanks, I was going to suggest exactly that.

Best regards,
Arawan


Quinn Wildman —

OK, more progress made. I didn't quite understand the scope of the refresh key was my problem. So, I'm using all variables now - an _input variable for the refresh key. I've got an API Profile component with a SQL Query of:

SELECT * from refresh
where refresh_token='${teem_refresh_token}'

when teem_refresh_token is set wrong, I get an invalid client error as expected.

However, when it is set correctly, I see:

2018-12-19T22:25:41.188+0000 4 [Connection: 1855] Executed sys_disconnect: Success: (0 ms)
2018-12-19T22:25:41.188+0000 1 [Connection: 1855] Closed REST connection.

However, my target table gets no data. Any guesses as to why my target table gets no data, or should I create a support ticket so I can provide my private data?


Matillion Agent  

Arawan Gajajiva —

Hi Quinn -

It sounds like you are indeed getting very close. If you call your API Profile from an API Query component, you get set a couple parameters:

  • Auto Debug = On
  • Debug Level = 3

If you set these parameters, when you execute the component, you will get additional debug information in your task information. That debug info should include the actual API call that is sent to the API and the response data that comes back. Looking at that information may be helpful in understanding what the current issue is. If you’d like for us to help you look at that further, I would recommend you create a ticket (you can email us at support@matillion.com). You can share your debug info in the ticket and we can take a look together and see if we can get you sorted.

Thanks!

Arawan

Post Your Community Answer

To add an answer please login