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