HTTP Status 401 - Invalid token

Regular Participant

HTTP Status 401 - Invalid token

I implemented the PHP Library into my website, filled out my form and received a notice that I must "Click here to authorize".  Once I clicked the link it took me to a page to login, which I did, and then prompted me to either Grant Access or Deny.  I copied the token from the URL before granting access, then granted access.  I put the token, along with my username, key, secret, etc. into the config.php file.  I retried the addContact example but I still received the "Click here to autorize" notice.


Instead of changing Authentication.php's CTCTDataStore->addUser() to save the info to a database, I hardcoded the array (for testing purposes):


function lookupUser($username){
        $user = array();
        $user['username'] = $username;
        $user['key'] ='***';  // The token, which I copied from the Grant Access line of URLs
        $user['secret'] = '*****';  // API ConsumerSecret
        return $user;



I am now receiving HTTP Status 401 - Invalid token.


Where did I go wrong?


Thanks, Brett

Regular Participant

I made a mistake in my function reference:


**Instead of changing Authentication.php's CTCTDataStore->lookupUser($username) to save...**

Regular Participant

Can someone please just point me towards a solid step-by-step guide on integration?


Is the new BETA code even working properly?  I have been doing API integrations for years (mailchimp, countless payment gateways, google, fb, etc.) and I've never had this much trouble with something that should be so simple.

Regular Participant

Is the access token static or does it change every time you refresh the session?

Are you using OAuth 2.0 for the authentication method?  If so, it's likely that you haven't received an access token for the account you're working on by going through the OAuth 2.0 flow.  OAuth 2.0 is a user authentication flow used by most web applications (Facebook, Twitter, etc.) to allow an end user to provide a 3rd party access to their information without providing them their password.  If you're using OAuth 2.0 and want to hard code the data, you will need to at least set up a dummy OAuth 2.0 flow to get a token to store in your code.  You can find the documentation for implementing OAuth 2.0 here:


Sorry for the confusion on this code.  The PHP code you're using is designed for a one to many provider environment where your software could potentially be used by 100s or even 1000s of Constant Contact customers.  That is why we put in some stub database storing and lookup methods.  You can remove those and just use a single hard coded object for one account.  Regardless, if you're using OAuth 2.0, you will need to get an OAuth 2.0 Access Token through the above linked flow to use that authentication method.

Dave Berard
Senior Product Manager, Constant Contact
Regular Participant

Yeah, I was going in circles with the token authentication.  I don't really know what finally made it work but all is good now...after a lot of hacking.

Regular Participant

To be honest, I'm not exactly sure what the issue was.  It was a cross between a codeigniter session and a rogue session that was used for the authentication.  After a few attempts at the rogue authentication and copying over the token, I got it to work.  I was trying to use the index.php and example_verification.php from the root folder to gain the auth token I needed, but what got it working was moving over to examples/addContact.php and grabbin the token from there.  The end result is a hard-coded key & secret in Authentication.php (which will be moved to the database in due time).


Thanks for your help.



The wrapper, out of the box, stores the access token in the session, so one way I've gotten it in the past is to var_dump the session after authentication.  Storage in the session can cause some retention issues if the session isn't maintained for some reason, so we definitely encourage secure local storage of hard-coding the access token, once you get it.


Our tokens have exceedingly large periods before expiry, so once you obtain and hard-code it, it will work indefinitely.


Let us know if you have any more questions. 

Mark Coleman
Support Engineer
Regular Participant


Developer Portal

View API documentation, code samples, get your API key.

Visit Page