Access Data on Behalf of Other Users with OAuth 2

At a glance

OAuth 2 authentication provides developers with a secure way to access Mailchimp Marketing API data on behalf of other Mailchimp users. Most commonly, OAuth 2 authentication is useful to set up integrations between third-party applications and Mailchimp. Popular integrations include Zapier, Slack, and Shopify via ShopSync — you can see a full list here

You might use OAuth 2 authentication to set up integrations that help you:

  • Sync your application data with Mailchimp so Mailchimp can send marketing and transactional email

  • Keep your audiences up-to-date and synced with your CRM, where you maintain a list of contacts

In this guide, we’ll walk through how to set up OAuth 2 to authenticate users of your app, then demonstrate how to make a call to the Marketing API using an OAuth 2 access token.

When not to use OAuth 2

Before doing the work of setting up authentication with OAuth 2, it’s worth understanding when you don’t need to use OAuth 2, and should use your API key instead. 

Simply put: Use your API Key if you’re writing code that tightly couples your application’s data to your Mailchimp account’s data. If you ever need to access someone else’s Mailchimp account’s data, you should be using OAuth 2.

Note: We strongly discourage asking your users to copy and paste their API Key into your application or integration. Not only is it less secure than using OAuth 2, it’s also prone to errors.

Even if you’re intending to use OAuth later, you may still want to use your API Key to start writing code against the Mailchimp Marketing API more quickly; using the API Key doesn’t require a server to handle the OAuth 2 flow, so you can start writing application code first, then switch to OAuth 2 further along in your development.

OAuth 2 workflow overview

Even if you’ve used OAuth 2 in the past, workflows can differ slightly, so here’s a quick overview of Mailchimp’s OAuth 2 workflow (which conforms to the Authorization Code flow):

When a user indicates that they allow you to authenticate with Mailchimp on their behalf, your application will direct them to Mailchimp’s OAuth page, where they will login to Mailchimp and authorize your application.

Then Mailchimp will then redirect the user back to your server with a query parameter named code; you’ll send that code in a request from your server to Mailchimp, to exchange it for an access token. 

Finally, using the access token, you’ll make a call to the OAuth Metadata endpoint, which will give you the server prefix for this user. You will want to persist both the access token and the server prefix in your application so you can use them for all subsequent requests to the Marketing API on the user’s behalf.

Note: Mailchimp Marketing access tokens do not expire, so you don’t need to use a refresh_token. The access token will remain valid unless the user revokes your application’s permission to access their account.

Register your application

To get the credentials you need in order to set up your OAuth 2 workflow, you’ll first need to register your application with Mailchimp:

  1. Navigate to the Registered Apps page in your Mailchimp account.

  2. Click the Register An App link.

  3. Fill out the Register An App form and click Create.

In order to fill out the registration form, you’ll need to know the Redirect URI for your application. This is the URL that Mailchimp Marketing servers will redirect users to after they have consented to giving your application access to their Mailchimp Marketing data. 

After successfully registering your application, you’ll see the client_id and client_secret at the bottom of the page. You’ll need these for the next step.

Implement the OAuth 2 workflow on your server

Since it’s hard to walk through the OAuth 2 workflow via description alone, let’s instead take a look at some sample server code. We’ll handle each step of the OAuth process: 1) user authentication 2) exchanging the code for the access token and 3) making your first authenticated request on behalf of the user.

Implement the OAuth 2 workflow on your server

const express = require("express");
const querystring = require("querystring");
const bodyParser = require("body-parser");
const fetch = require("node-fetch");
const { URLSearchParams } = require("url");
const mailchimp = require("@mailchimp/mailchimp_marketing");

// Basic express app setup
const app = express();
app.use(bodyParser.json());
app.use(
  bodyParser.urlencoded({
    extended: true
  })
);

// You should always store your client id and secret in environment variables for security — the exception: sample code.
const MAILCHIMP_CLIENT_ID = "YOUR_CLIENT_ID";
const MAILCHIMP_CLIENT_SECRET =
  "YOUR_CLIENT_SECRET";
const BASE_URL = "http://127.0.0.1:3000";
const OAUTH_CALLBACK = `${BASE_URL}/oauth/mailchimp/callback`;

// 1. Navigate to http://127.0.0.1:3000 and click Login
app.get("/", function(req, res) {
  res.send(
    '<p>Welcome to the sample Mailchimp OAuth app! Click <a href="/auth/mailchimp">here</a> to log in</p>'
  );
});

// 2. The login link above will direct the user here, which will redirect
// to Mailchimp's OAuth login page.
app.get("/auth/mailchimp", (req, res) => {
  res.redirect(
    `https://login.mailchimp.com/oauth2/authorize?${querystring.stringify({
      response_type: "code",
      client_id: MAILCHIMP_CLIENT_ID,
      redirect_uri: OAUTH_CALLBACK
    })}`
  );
});

// 3. Once // 3. Once the user authorizes your app, Mailchimp will redirect the user to
// this endpoint, along with a code you can use to exchange for the user's
// access token.
app.get("/oauth/mailchimp/callback", async (req, res) => {
  const {
    query: { code }
  } = req;

  // Here we're exchanging the temporary code for the user's access token.
  const tokenResponse = await fetch(
    "https://login.mailchimp.com/oauth2/token",
    {
      method: "POST",
      body: new URLSearchParams({
        grant_type: "authorization_code",
        client_id: MAILCHIMP_CLIENT_ID,
        client_secret: MAILCHIMP_CLIENT_SECRET,
        redirect_uri: OAUTH_CALLBACK,
        code
      })
    }
  );

  const { access_token } = await tokenResponse.json();
  console.log(access_token);

  // Now we're using the access token to get information about the user.
  // Specifically, we want to get the user's server prefix, which we'll use to
  // make calls to the API on their behalf.  This prefix will change from user
  // to user.
  const metadataResponse = await fetch(
    "https://login.mailchimp.com/oauth2/metadata",
    {
      headers: {
        Authorization: `OAuth ${access_token}`
      }
    }
  );

  const { dc } = await metadataResponse.json();
  console.log(dc);

  // Below, we're using the access token and server prefix to make an
  // authenticated request on behalf of the user who just granted OAuth access.
  // You wouldn't keep this in your production code, but it's here to
  // demonstrate how the call is made.

  mailchimp.setConfig({
    accessToken: access_token,
    server: dc
  });

  const response = await mailchimp.ping.get();
  console.log(response);

  res.send(`
    <p>This user's access token is ${access_token} and their server prefix is ${dc}.</p>

    <p>When pinging the Mailchimp Marketing API's ping endpoint, the server responded:<p>

    <code>${response}</code>
  `);

  // In reality, you'd want to store the access token and server prefix
  // somewhere in your application.
  // fakeDB.getCurrentUser();
  // fakeDB.storeMailchimpCredsForUser(user, {
  //   dc,
  //   access_token
  // });
});

app.listen(3000, "127.0.0.1", function() {
  console.log(
    "Server running on port 3000; visit http://127.0.0.1:3000"
  );
});

This code will handle the entire OAuth workflow, resulting in (but not persisting) an access token you can use to make a request on behalf of the authenticating user. In this case, we’re making a trivial request to the Ping endpoint, but doing so confirms that the token is working as expected.

Note: All requests to the Mailchimp OAuth 2 endpoints are made over HTTPS. For security, we strongly recommend — but do not enforce — using HTTPS for your redirect_uri.

Read through the code above if you want to understand every detail of the workflow, but briefly, here’s what's happening on your server:

  • To begin the process, you’ll redirect your user to this URL: https://login.mailchimp.com/oauth2/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI

  • When the user approves your application, they’ll be sent back to your application with a query string parameter named code you can use to request your access token via a POST request to this URL: https://login.mailchimp.com/oauth2/token

Finally, to retrieve the server prefix, you’ll send a GET request to the Metadata endpoint with an Authorization header set to OAuth USERS_OAUTH_TOKEN: https://login.mailchimp.com/oauth2/metadata