Creating and updating contacts in Oauth


First, I am new to OAuth and am pretty sure it is the wrong tool for what I’m trying to do. With that said, I may be missing something obvious to someone just because I’m just learning this. With that said, I have been going through here and the FB group trying to figure this out.

I’m trying to add a contact and then add a tag. I thought I had this figured out using the OAuth API when I then figured out that there isn’t a client_credential grant. To give some context I am aiming to do the following on my Node.js server:

  1. Get a text from Twilio
  2. Create a contact using a phone number, a zip code, a tag, and a custom field.
  3. If a user texts in STOP: Search for user by phone, remove tag.
  4. If a user texts in START: Search for user by phone, add tag.

I almost have this worked out, but am seeing that the auth token that I receive is for 24 hours.

With a client_credential I think I know how to handle refreshing this programmatically, but I am not sure with how this is working. From reading around I think I could maybe:

  1. Manually get the Auth Token
  2. Set a timer for 20 hours and try to refresh (as was suggested here: Using OAuth2 and Infusionsoft API/REST - YouTube)
  3. Assuming the refresh works, I never have to manually retrieve the Auth Token again?

Thoughts? Will I need to attach a database to my server for this to work?


I could maybe get by if I could just add the user using the API Passphrase & Encrypted Key since I don’t believe OAuth is really designed for my purposes. Does anyone know if it is possible at this point to do an HTTP post with just those? I see that a number of 3rd party apps just ask for those two items to integrate, so I’m assuming it is, but didn’t find (or recognize?) an example.

Thanks in advance.

UPDATE on 20190318:

This entire process was very painful for me, so in hopes of helping someone out, I’m going to note some things:

  • I am not using this for user authentication (letting people sign into something using InfusionSoft authentication). I am just using it to create a customer, from my server, with some custom fields, and then add a tag to that user (you cannot at this time add a tag while creating a user)

  • As crazy as this may or may not sound, the authentication to use this REST api has to be refreshed every 24 hours using your refresh token

  • the refresh token expires every 6 months OR when you get a new access token, which will likely be every 24 hours. Getting a new access token will also provide you a new refresh token).

  • You can either schedule to refresh your access and refresh tokens prior to that 24 hour mark (best practice) or you could just wait for it to fail and then refresh it then (what I’m currently doing, I will change soon).

Here is some code I am using in a Node.js and Express app that creates a contact using the REST API:

const express = require('express');
const request = require('request');

function keapCreateContact(keapZip, keapPhone, keapURL, keapMarketInfo) {
    // the below tokens are expired. best practice is to not hard code this
    var accessToken = '9frcdjdywh9zmbp87dqm4zu5'; 
    var refreshToken = 'jzhtn9whzvzgzmbyu9hc8ypb';  

    var rootUrl = '';
    var authToken = 'Bearer ' + accessToken;

    var createContact = {
        method: 'PUT',
        url: rootUrl + '/contacts',
            Authorization: authToken,
            'Content-Type': 'application/json'
            addresses: [{ zip_code: keapZip, field: 'BILLING' }],
            phone_numbers: [{ field: 'PHONE1', number: keapPhone }],
            custom_fields: [{ content: keapURL, id: 183 }, { content: keapMarketInfo, id: 177 }],
            duplicate_option: 'Email',
            // email_addresses: [{ email: keapEmail, field: 'EMAIL1' }]
        json: true

    request(createContact, function (error, response, body) {
        if (error) throw new Error(error);
        console.log('[INFO] Contact created');
        var contactId =;
        var addTag = {
            method: 'POST',
            url: rootUrl + '/contacts/' + contactId + '/tags',
                Authorization: authToken,
                'Content-Type': 'application/json'
            body: { tagIds: [2069] }, // whatever tag(s) you want added
            json: true
        request(addTag, function (error, response, body) {
            if (error) throw new Error(error);

Here is the code I’m using to refresh with:

// this is working as of: (20190315•01:53:00)
var request = require('request');

var client_id = *clientIdVariable*; 
var client_secret = *clientSecretVariable*;

var base64Variable = Buffer.from(client_id + ':' + client_secret).toString('base64');

var options = {
    method: 'POST',
    url: '',
    headers: {
        'cache-control': 'no-cache',
        host: '',
        authorization: 'Basic ' + base64Variable,
        'content-type': 'application/x-www-form-urlencoded' },
    form: {
        grant_type: 'refresh_token',
        refresh_token : *refreshTokenVariable*,
        client_id: *client_id*

request(options, function (error, response, body) {
    if (error) throw new Error(error);

Good luck…and

The only grant type if full. IS hasn’t implemented grant levels yet. As to the api key method, if you’re using REST then OAuth is required. The api key method only applies to the legacy xml-rpc and it’s not even publicly available any longer (though if you already had the support files you could still use it). But again, using REST will not work with the api key authentication.

OAuth will work as I’ve developed many projects far more complex using it and REST. I’ve done a video on it’s use and maybe it might fill in some of the ‘blanks’ for you?

1 Like

Hi John,

Thanks for the reply. I have been watching your video and it has been helpful - my understanding from that is I get an Auth Token however (I can get it from Postman) and then I can programmatically refresh the token at 20 hours and I’ll be good to go - correct? (Not sure I know how to implement that but…I’ll figure it out eventually)

Correct. One thing to specify and that is often mis-understood, is that when you refresh you get a completely new set of access/refresh tokens. The current ones immediately become invalid and you must overwrite the new ones to the DB fields with the new date/time it was requested so you can calculate the new TTL.

I’m probably asking too much at this point, but am I correct in thinking I’ll have to add a database for this? I’ve avoided this so far but…I’m thinking that might be unavoidable at this point with the token?

UPDATE: Looking at this post:

I am thinking that I can just do a try-catch to take care of this whenever it fails, but your (John’s) YouTube video makes me feel like that isn’t an option?

As the video I shared above mentions, a DB is the most seamless way to handle it :wink:

1 Like

Thanks for the reply. I am thinking I’m just going to use a .json file to store it for the moment.

Now all I have left is to iron out my code to refresh with.

Note, that if you use a json file, it can be read in most configurations and used to access your Infusionsoft app. It’s not advisable from a security stand point :wink:

1 Like