Skip to main content

OAuth 2.0 Authentication

🔐 OAuth 2.0 Flow

Mailchimp uses standard OAuth 2.0 authorization code flow with automatic datacenter detection.

🌐 Environment Variables

VariableDescriptionExample
MAILCHIMP_CLIENT_IDOAuth client ID1234567890
MAILCHIMP_CLIENT_SECRETOAuth client secretabcdef123456
MAILCHIMP_REDIRECT_URIOAuth callback URLhttps://api.dashclicks.com/v1/integrations/mailchimp/callback
MAILCHIMP_AUTHORIZATION_URLOAuth authorization endpointhttps://login.mailchimp.com/oauth2/authorize
MAILCHIMP_TOKEN_URLToken exchange endpointhttps://login.mailchimp.com/oauth2/token
MAILCHIMP_DATACENTER_URLMetadata/datacenter endpointhttps://login.mailchimp.com/oauth2/metadata
MAILCHIMP_RESPONSE_TYPEOAuth response typecode
MAILCHIMP_GRANT_TYPEOAuth grant typeauthorization_code

📋 API Endpoints

MethodEndpointDescriptionAuth Required
GET/v1/integrations/mailchimp/auth/loginInitiate OAuth flow✅ JWT
GET/v1/integrations/mailchimp/callbackOAuth callback handler
DELETE/v1/integrations/mailchimp/authDelete stored token✅ JWT

🔄 Authentication Flow

Step 1: Initiate OAuth

Endpoint: GET /auth/login

Query Parameters:

  • forward_url (required) - URL to redirect after OAuth completes

Request:

GET /v1/integrations/mailchimp/auth/login?forward_url=https://app.dashclicks.com/integrations
Authorization: Bearer {jwt_token}

Process:

  1. Check for existing token in database
  2. If token exists and valid → Redirect to forward_url with success
  3. If token invalidated → Delete and re-authenticate
  4. If no token → Generate JWT state token and redirect to Mailchimp

JWT State Token:

{
aid: "account_id", // DashClicks account ID
uid: "user_id", // DashClicks user ID
forward_url: "https://..." // Return URL
}

Authorization URL Format:

https://login.mailchimp.com/oauth2/authorize
?response_type=code
&client_id={MAILCHIMP_CLIENT_ID}
&redirect_uri={MAILCHIMP_REDIRECT_URI}
&state={JWT_STATE_TOKEN}

Success Response (existing connection):

HTTP/1.1 301 Moved Permanently
Location: https://app.dashclicks.com/integrations?status=success&integration=mailchimp&token={token_id}

Redirect Response (new connection):

HTTP/1.1 302 Found
Location: https://login.mailchimp.com/oauth2/authorize?...

Step 2: OAuth Callback

Endpoint: GET /callback

Query Parameters:

  • code (required) - Authorization code from Mailchimp
  • state (required) - JWT state token from Step 1

Process:

  1. Decode JWT state token
  2. Exchange authorization code for access token
  3. Fetch datacenter metadata
  4. Store token with datacenter info in MongoDB
  5. Redirect to forward_url with success status

Token Exchange Request:

POST https://login.mailchimp.com/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id={CLIENT_ID}
&client_secret={CLIENT_SECRET}
&redirect_uri={REDIRECT_URI}
&code={AUTHORIZATION_CODE}

Token Exchange Response:

{
"access_token": "a0b219e049fb4f027fd927ade6a21d38",
"token_type": "bearer",
"scope": null
}

Datacenter Metadata Request:

GET https://login.mailchimp.com/oauth2/metadata
Authorization: Bearer {access_token}

Datacenter Metadata Response:

{
"dc": "us8",
"login": {
"email": "user@example.com",
"login_id": "12345",
"login_name": "User Name",
"login_email": "user@example.com"
},
"accountname": "Example Account",
"user_id": 67890,
"api_endpoint": "https://us8.api.mailchimp.com"
}

MongoDB Document Created:

{
token: {
access_token: "a0b219e049fb4f027fd927ade6a21d38",
token_type: "bearer",
scope: null,
metadata: {
dc: "us8" // Datacenter extracted from metadata
}
},
account_id: "12345",
owner: "user_Lwh9EzeD8",
token_invalidated: false
}

Success Response:

HTTP/1.1 301 Moved Permanently
Location: https://app.dashclicks.com/integrations?status=success&integration=mailchimp&token={token_id}

Error Response:

HTTP/1.1 301 Moved Permanently
Location: https://app.dashclicks.com/integrations?status=error&reason={error_message}&integration=mailchimp

Step 3: Delete Token

Endpoint: DELETE /auth

Request:

DELETE /v1/integrations/mailchimp/auth
Authorization: Bearer {jwt_token}

Success Response:

{
"success": true,
"message": "Access Token has been successfully deleted"
}

Error Response (token not found):

{
"success": false,
"errno": 400,
"message": "Access Token Not Found"
}

🔑 Token Management

Token Storage

Tokens stored in integrations.mailchimp.key collection:

{
_id: ObjectId("..."),
token: {
access_token: "...",
token_type: "bearer",
scope: null,
metadata: { dc: "us8" }
},
account_id: "12345",
owner: "user_Lwh9EzeD8",
token_invalidated: false
}

Token Lookup

Model Method: searchTokenQuery(owner_id, account_id)

const result = await MailchimpKey.findOne({
account_id: account_id,
owner: owner_id,
})
.lean()
.exec();

Returns:

  • Success: { id, token, account_id, owner, ... }
  • Not found: { error: 'No token found' }

Token Invalidation

Tokens can be marked as invalidated:

{
token_invalidated: true; // Flag for soft deletion
}

When invalidated token is found during login, it's deleted and user re-authenticates.

🎯 Authorization Middleware

All protected endpoints require JWT authentication:

req.auth = {
status: 'VALID_TOKEN',
auth: {
workspace_id: '1234567890',
account_id: '12345',
uid: 'user_Lwh9EzeD8',
scope: 'mailchimp, mailchimp.create mailchimp.delete mailchimp.read',
// ... other JWT claims
},
};

Required Scopes

OperationRequired Scopes
Loginmailchimp, mailchimp.create
Deletemailchimp, mailchimp.delete
Exportmailchimp, mailchimp.read

🌍 Datacenter Detection

Why Datacenters Matter

Mailchimp accounts are region-specific. API requests must use datacenter-specific URLs:

https://{dc}.api.mailchimp.com/3.0/...

Common datacenters:

  • us1 - United States (East)
  • us8 - United States (Central)
  • us19 - United States (West)

Automatic Detection

The integration automatically:

  1. Fetches metadata after OAuth
  2. Extracts dc field
  3. Stores in token metadata
  4. Uses for all subsequent API calls

⚠️ Error Handling

ErrorStatusResponse
Missing forward_url400{ success: false, errno: 400, message: "forward url is required!" }
Token already exists403{ success: false, errno: 400, message: "Access Token is already stored! Please delete it." }
Query code missing403{ success: false, errno: 400, message: "Query Code not found" }
Token not found (delete)404{ success: false, errno: 400, message: "Access Token Not Found" }
OAuth exchange failed400Redirects to forward_url with error

🔒 Security Features

JWT State Token

  • Expiry: 1 hour
  • Secret: process.env.APP_SECRET
  • Claims: Account ID, User ID, Forward URL
  • Purpose: Prevent CSRF attacks and maintain session state

Token Encryption

Tokens stored in MongoDB may be encrypted at rest depending on deployment configuration.

Single Connection Per User

Only one active connection allowed per user/account combination to prevent token proliferation.

📝 Important Notes

  • 🔒 Never Expires: Mailchimp access tokens have no expiration
  • 🔄 No Refresh: No refresh token needed - access tokens are persistent
  • 🌍 Datacenter Required: All API calls need correct datacenter
  • 👤 One Token: Single connection per user/account pair
  • Fast Auth: No token refresh overhead in API calls
💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:30 AM