# Api Key Refresh

**URL:** <https://integration.keap.com/t/api-key-refresh/16256>\
**Category:** API Q&A\
**Created:** [October 1, 2017, 10:38pm UTC](https://integration.keap.com/t/api-key-refresh/16256 "2017-10-01T22:38:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gavin\_Nathan](https://avatars.discourse-cdn.com/v4/letter/g/b5a626/32.png) [@Gavin\_Nathan](https://integration.keap.com/u/Gavin_Nathan)\
**Post date:** [October 1, 2017, 10:38pm UTC](https://integration.keap.com/t/api-key-refresh/16256/1 "2017-10-01T22:38:58Z")

</div>

Hello.

I am trying to use the API to request info from my Infusionsoft Dashboard.

All personal info in this post has been obfuscated.

1. From [https://keys.developer.infusionsoft.com/apps/mykeys](https://keys.developer.infusionsoft.com/apps/mykeys) i can get access to my Client ID and my Client Secret.

 ![devdash](https://us1.discourse-cdn.com/flex019/uploads/infusionsoft1/original/2X/8/8ba166e2d462cb0ad95f9ffd0a8ad18ddf8c0fc7.png)

1. Using these two values i can generate a access token and refresh token from [https://accounts.infusionsoft.com/app/central/home](https://accounts.infusionsoft.com/app/central/home)

 ![appDash](https://us1.discourse-cdn.com/flex019/uploads/infusionsoft1/original/2X/a/ac95e2b3fde6e453489b1e8e4d305a9a466c6c54.png)

So now i have an access token and a refresh token.

Using the REST Api, i can get client information using curl.

**curl ‘[https://api.infusionsoft.com/crm/rest/v1/contacts/6](https://api.infusionsoft.com/crm/rest/v1/contacts/6)’ -H “Authorization: Bearer #########” -H ‘Accept: application/json’ -H ‘Content-Type: application/json’ -X GET**

This works and returns my customer information.

Now i want to refresh an access token using the REST api.

Here the Auth header is “Basic + base64\_encode(CLIENT\_ID + ‘:’ + CLIENT\_SECRET)” where CLIENT\_ID & CLIENT\_SECRET are taken from the developer dashboard, shown in image 1. This tool was used to encode the id and secret - [https://www.base64encode.org](https://www.base64encode.org) before entering it into curl

**curl ‘[https://api.infusionsoft.com/token](https://api.infusionsoft.com/token)’ -H ‘Authorization: Basic ##########’ -H ‘Accept: application/json’ -H ‘Content-Type: application/json’ -X POST -d ‘{ “grant\_type”:“refresh\_token”, “refresh\_token”:“###########”}’**

The response is {“error”:“invalid\_request”,“error\_description”:“response\_type or grant\_type is required”}

A similar issue is found in the forum but their solution does not work here. The OP closed the question and creates the following post.

> [@Invalid client (401) when refreshing token](https://integration.keap.com/t/invalid-client-401-when-refreshing-token/675):
>
> Hello, I’m trying to refresh my API token using a PHP Laravel setup and am running into some problems. I’ve tried a lot of times, but I keep getting the invalid client (401) error. Now, I’ve made double-sure that the values stored in DB and env file are correct, but am likely not using something correctly. How I began the process was by obtaining the access code through browser and then sending a CURL POST request from the registered domain’s command line. Once I have the access\_token and refre…

In this question, the OPs issue is the space in the Auth Header. Not the issue here.

> [@Invalid client when trying to refresh token from command line](https://integration.keap.com/t/invalid-client-when-trying-to-refresh-token-from-command-line/686):
>
> I’m getting the invalid\_client error when trying to refresh my token. To keep things simple, this time I sent the refresh request from command line itself: curl --header "Authorization: BasicBASE64ENCODED" --data "refresh\_token=REFRESH\_TOKEN&grant\_type=refresh\_token" https://api.infusionsoft.com/token Am I doing something wrong?

If you need any more information, please let me know.

---

<div class="post-metadata">

**Author:** ![John\_Borelli](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/john_borelli/32/11880_2.png) [@John\_Borelli](https://integration.keap.com/u/John_Borelli)\
**Post date:** [October 2, 2017, 7:36am UTC](https://integration.keap.com/t/api-key-refresh/16256/2 "2017-10-02T07:36:56Z")

</div>

This:

> [@Gavin\_Nathan](#):
>
> “Basic + base64\_encode(CLIENT\_ID + ‘:’ + CLIENT\_SECRET)”

will not resolve correctly. Your header should be "Authorization: Basic "+Base64(id:secret) but the way your quotes (double and single) and plus signs are arranged, that’s not what you’ll get. Have you tried printing this to the screen to see that it resolves to the string you’re looking for?

---

<div class="post-metadata">

**Author:** ![Gavin\_Nathan](https://avatars.discourse-cdn.com/v4/letter/g/b5a626/32.png) [@Gavin\_Nathan](https://integration.keap.com/u/Gavin_Nathan)\
**Post date:** [October 2, 2017, 8:06am UTC](https://integration.keap.com/t/api-key-refresh/16256/3 "2017-10-02T08:06:22Z")

</div>

@John_Borelli I’ve repeated the request with adjusted formatting

curl ‘[https://api.infusionsoft.com/token](https://api.infusionsoft.com/token)’ -H ‘Authorization: Basic ###########=’ -H ‘Accept: application/json’ -H ‘Content-Type: application/json’ --data ‘{“grant\_type”:“refresh\_token”,“refresh\_token”:“#######”}’ -X POST

{“error”:“invalid\_request”,“error\_description”:“response\_type or grant\_type is required”}

As for the plus signs… that is cut and pasted from the documentaiton.  
Example pseudo code: Basic + base64\_encode(CLIENT\_ID + ‘:’ + CLIENT\_SECRET) here [OAuth2 Authentication - Keap Developer Portal](https://developer.infusionsoft.com/authentication/)

To generate the base64\_encoded string is used [https://www.base64encode.org](https://www.base64encode.org).

If i put the incorrect string for the basic auth token i get {“error”:“invalid\_client”}

This suggests that the header is correct as the issue i am facing is not authorization but the grant\_Type.

“error”:“invalid\_request”,“error\_description”:“response\_type or grant\_type is required”}

Should i be using JSON as the -d parameter in curl? Or should it be url encoded?

---

<div class="post-metadata">

**Author:** ![John\_Borelli](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/john_borelli/32/11880_2.png) [@John\_Borelli](https://integration.keap.com/u/John_Borelli)\
**Post date:** [October 2, 2017, 2:54pm UTC](https://integration.keap.com/t/api-key-refresh/16256/4 "2017-10-02T14:54:03Z")

</div>

So start at the beginning. How are you sending cURL? command line, code, Postman? This can make a difference in answering the rest.

---

<div class="post-metadata">

**Author:** ![Gavin\_Nathan](https://avatars.discourse-cdn.com/v4/letter/g/b5a626/32.png) [@Gavin\_Nathan](https://integration.keap.com/u/Gavin_Nathan)\
**Post date:** [October 2, 2017, 3:35pm UTC](https://integration.keap.com/t/api-key-refresh/16256/5 "2017-10-02T15:35:43Z")

</div>

@John_Borelli Certainly. I am using cUrl from the command line. On a mac.

---

<div class="post-metadata">

**Author:** ![mike.christianson](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/mike.christianson/32/74_2.png) [@mike.christianson](https://integration.keap.com/u/mike.christianson)\
**Post date:** [October 2, 2017, 11:12pm UTC](https://integration.keap.com/t/api-key-refresh/16256/6 "2017-10-02T23:12:28Z")

</div>

@Gavin_Nathan Thanks for taking the time to post what you’ve tried. I think at least part of the trouble is how curl is being told to make the request.

> [@Gavin\_Nathan](#):
>
> curl ‘[https://api.infusionsoft.com/token’](https://api.infusionsoft.com/token%E2%80%99) -H ‘Authorization: Basic ##########’ -H ‘Accept: application/json’ -H ‘Content-Type: application/json’ -X POST **-d ‘{ “grant\_type”:“refresh\_token”, “refresh\_token”:“###########”}’**

Instead, of using `-d` (or `--data`) with JSON, use [query string parameters](https://en.wikipedia.org/wiki/Query_string). Let me know how that goes for you.

(Updated this post to remove erroneous info and provide correct info as provided by [Brad](https://integration.keap.com/t/api-key-refresh/16256/7).)

---

<div class="post-metadata">

**Author:** ![bradb](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/bradb/32/13_2.png) [@bradb](https://integration.keap.com/u/bradb)\
**Post date:** [October 3, 2017, 5:26pm UTC](https://integration.keap.com/t/api-key-refresh/16256/7 "2017-10-03T17:26:49Z")

</div>

The POST needs to be `application/x-www-form-urlencoded` like the example below.

```http
POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

```

---

<div class="post-metadata">

**Author:** ![Gavin\_Nathan](https://avatars.discourse-cdn.com/v4/letter/g/b5a626/32.png) [@Gavin\_Nathan](https://integration.keap.com/u/Gavin_Nathan)\
**Post date:** [October 4, 2017, 4:41am UTC](https://integration.keap.com/t/api-key-refresh/16256/8 "2017-10-04T04:41:36Z")

</div>

@bradb @mike.christianson

```
public OAuthModel RefreshApiToken(string refreshToken)
        {
            // exchange authorization code at authorization server for an access and refresh token
            Dictionary<string, string> post = null;
            post = new Dictionary<string, string>
            {
                {"refresh_token", refreshToken},
                {"grant_type", "refresh_token"}
            };
            using (var client = new HttpClient())
            {
                try
                {
                    client.BaseAddress = new Uri(tokenUrl);
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                                        "Basic",
                                        Convert.ToBase64String(
                                        System.Text.ASCIIEncoding.ASCII.GetBytes(
                                        string.Format("{0}:{1}", _businessId, _apiKey))));

                    var postContent = new FormUrlEncodedContent(post);
                    var tokenResponse = client.PostAsync("token", postContent).Result;

                    tokenResponse.EnsureSuccessStatusCode(); // Throw in not success
                    var content = tokenResponse.Content.ReadAsStringAsync().Result;
                    var responseModel = JsonConvert.DeserializeObject<OAuthModel>(content);
                    return responseModel;
                }
                catch (HttpRequestException e)
                {
                }
                return new OAuthModel();
            }
        } 

```

This totally worked! Thank you!

Using - FormUrlEncodedContent

Regards,

Daniel
