# How to Integrate Retool with Campaign Monitor

- Tool: Retool
- Difficulty: Beginner
- Time required: 15 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Campaign Monitor by creating a REST API Resource using your Campaign Monitor API key as Basic Auth. The base URL is https://api.createsend.com/api/v3.3. Once configured, build queries to manage subscriber lists across multiple client accounts, view campaign performance stats, and track email delivery metrics from a centralized marketing operations dashboard.

## Build a Campaign Monitor Email Marketing Dashboard in Retool

Campaign Monitor is built for agencies managing email campaigns on behalf of multiple clients. While Campaign Monitor's native interface handles individual client management well, agencies need a unified view across all their clients — which clients have active campaigns, which subscriber lists are growing or shrinking, and which campaigns are underperforming relative to benchmarks. Retool provides the flexible Table, Chart, and filtering components to build this cross-client view that Campaign Monitor's native UI doesn't offer.

Campaign Monitor's API v3.3 provides full programmatic access to the entire data model: clients, campaigns, subscriber lists, subscribers, and transactional email logs. Authentication uses a standard API key in Basic Auth format, making the Retool integration straightforward to configure. The API is organized around a client-centric hierarchy — you first fetch clients, then access their campaigns and lists.

With Retool, marketing agencies can build a command center showing all client campaign performance side-by-side, enabling quick identification of underperforming sends, list growth trends, and subscriber engagement patterns — giving account managers the data they need to make informed recommendations without navigating Campaign Monitor's per-client interface.

## Before you start

- A Campaign Monitor account with at least one client account set up
- A Campaign Monitor API key (found in Account Settings → API Keys in Campaign Monitor)
- Access to the specific client account IDs you want to query (returned by the /clients endpoint)
- A Retool account with permission to create Resources
- Basic familiarity with Retool's query editor and Table/Chart components

## Step-by-step guide

### 1. Retrieve your Campaign Monitor API key

In Campaign Monitor, click your account name in the top-right corner and select Account Settings. Navigate to the API Keys section. If you don't have an API key yet, click Generate API Key. Copy the key — it's a long alphanumeric string.

Campaign Monitor's API uses Basic Auth where the API key is the username and any string can be the password — the conventional placeholder is 'x'. This is similar to how Mailchimp's API key authentication works. The API key gives access to all clients and accounts associated with your Campaign Monitor login.

Note that Campaign Monitor has two levels of API keys:
1. Account-level API key (from Account Settings) — gives access to all clients under your account. This is what you want for a multi-client agency dashboard.
2. Client-level API key — scoped to a single client, available from the client's settings. Use this if you're building a dashboard for a specific client only.

For most agency Retool dashboards, you'll use the account-level API key. Campaign Monitor's API base URL is https://api.createsend.com/api/v3.3 — note the version number (v3.3 is the current stable version as of 2024).

**Expected result:** You have a Campaign Monitor account-level API key and understand it uses Basic Auth with the key as username and 'x' as password.

### 2. Create the Campaign Monitor REST API Resource in Retool

In Retool, navigate to the Resources tab and click Add Resource. Select REST API from the resource type list.

Configure the resource:
- Name: Campaign Monitor API
- Base URL: https://api.createsend.com/api/v3.3

For authentication, select Basic Auth from the Authentication dropdown. Set Username to your Campaign Monitor API key and Password to x (the literal letter 'x' — Campaign Monitor ignores the password field).

If you prefer to store the API key in Configuration Variables (recommended for production), go to Settings → Configuration Variables, create CAMPAIGN_MONITOR_API_KEY, mark it as secret, then use {{ retoolContext.configVars.CAMPAIGN_MONITOR_API_KEY }} as the Username.

Add a Content-Type header: Key: Content-Type, Value: application/json. This is needed for POST and PUT requests.

Click Create Resource. Test the connection by creating a query with method GET and path /clients.json. If it returns a JSON array of client objects (each with ClientID, Name), the authentication is working. A 401 response indicates the API key is incorrect or the Basic Auth format is wrong.

**Expected result:** The Campaign Monitor API resource is configured and a test GET /clients.json returns an array of client objects with ClientID and Name fields.

### 3. Fetch clients and campaigns

Create a query named getClients with method GET and path /clients.json. This returns all client accounts under your Campaign Monitor login. Each client object contains: ClientID, Name.

Bind this to a Select component named select_client with value field ClientID and label field Name. This drives all subsequent queries.

Create a getCampaigns query with method GET and path /clients/{{ select_client.value }}/campaigns.json. This returns all sent campaigns for the selected client. Each campaign includes: CampaignID, Subject, Name, SentDate, TotalRecipients, and a FromName.

For draft/scheduled campaigns, use a separate query with path /clients/{{ select_client.value }}/drafts.json.

Campaign analytics require an additional call per campaign — use path /campaigns/{{ campaign_id }}/summary.json to get opens, clicks, bounces, and unsubscribes. Since fetching summary stats for every campaign would require many API calls, consider using a JavaScript query that fetches summaries for only the most recent 10 campaigns using Promise.all for parallel fetching.

Create a transformer that merges campaign metadata with summary stats for display in the Table component.

```
// Transformer for Campaign Monitor campaigns with stats
// Assumes data is merged from getCampaigns + individual summary calls
const campaigns = data || [];
return campaigns.map(campaign => ({
  id: campaign.CampaignID,
  name: campaign.Name || campaign.Subject,
  subject: campaign.Subject || '',
  sent_date: campaign.SentDate
    ? new Date(campaign.SentDate).toLocaleDateString()
    : '',
  recipients: campaign.TotalRecipients || 0,
  opens: campaign.Opens || 0,
  unique_opens: campaign.UniqueOpens || 0,
  open_rate: campaign.TotalRecipients > 0
    ? `${((campaign.UniqueOpens / campaign.TotalRecipients) * 100).toFixed(1)}%`
    : 'N/A',
  clicks: campaign.Clicks || 0,
  click_rate: campaign.TotalRecipients > 0
    ? `${((campaign.UniqueClicks / campaign.TotalRecipients) * 100).toFixed(1)}%`
    : 'N/A',
  bounces: campaign.Bounced || 0,
  unsubscribes: campaign.Unsubscribed || 0
}));
```

**Expected result:** The getCampaigns query populates a Table with recent campaigns for the selected client, including open rates and click rates.

### 4. Fetch subscriber lists and manage subscribers

Create a getLists query with method GET and path /clients/{{ select_client.value }}/lists.json. This returns all subscriber lists for the selected client. Each list object contains: ListID, Name.

When a specific list is selected, create a getSubscribers query with method GET and path /lists/{{ select_list.value }}/active.json to fetch active subscribers. Add query parameters:
- page: {{ pagination.page || 1 }}
- pagesize: 50
- orderfield: email
- orderdirection: asc

The active subscribers endpoint returns: TotalNumberOfRecords (use for pagination), PageNumber, ResultsOrderedBy, OrderDirection, and a Results array. Each subscriber has: EmailAddress, Name, Date (subscription date), State, and CustomFields (an array of custom field key-value pairs).

For managing subscribers:
- Add subscriber: POST /subscribers/{{ select_list.value }}.json with body {"EmailAddress": "...", "Name": "...", "CustomFields": [], "Resubscribe": true}
- Unsubscribe: POST /subscribers/{{ select_list.value }}/unsubscribe.json with body {"EmailAddress": "{{ table_subscribers.selectedRow.data.email }}"}
- Update subscriber: PUT /subscribers/{{ select_list.value }}.json with updated fields
- Delete subscriber: DELETE /subscribers/{{ select_list.value }}.json?email={{ encodeURIComponent(table_subscribers.selectedRow.data.email) }}

Wire each action to a button component with confirmation dialogs for unsubscribe and delete operations.

```
// Transformer for Campaign Monitor subscriber list
const subscribers = data.Results || [];
return subscribers.map(sub => {
  // Flatten custom fields array into an object
  const customFields = {};
  (sub.CustomFields || []).forEach(field => {
    customFields[field.Key] = field.Value;
  });
  return {
    email: sub.EmailAddress,
    name: sub.Name || '',
    subscribed_date: sub.Date
      ? new Date(sub.Date).toLocaleDateString()
      : '',
    state: sub.State,
    ...customFields
  };
});
```

**Expected result:** The subscriber management panel shows active subscribers for the selected list with their details, and includes working buttons to add, unsubscribe, and delete contacts.

### 5. Build campaign performance analytics

Enhance the dashboard with visual analytics using Retool's Chart component. For a campaign that's selected in the Table, create a query to fetch detailed click and open data.

For email client breakdown, use GET /campaigns/{{ select_campaign.value }}/emailclients.json — this returns which email clients recipients used to open the campaign (helpful for rendering optimization decisions).

For geographic data, use GET /campaigns/{{ select_campaign.value }}/opens.json with parameters:
- page: 1
- pagesize: 50
- orderfield: Date
- orderdirection: Desc

This returns individual open events with EmailAddress, ListID, Date, and IPAddress (can be used for approximate geographic distribution).

For a list growth chart, use GET /lists/{{ select_list.value }}/stats.json which returns TotalActiveSubscribers, TotalUnsubscribes, TotalDeleted, TotalBounced, and TotalUnconfirmed — use these as Stat components at the top of the subscriber panel.

Build a campaign comparison Chart that shows open rate and click rate as side-by-side bars for the 10 most recent campaigns. Use the getCampaigns query data (filtered to the selected client) as the Chart's data source with campaign name on the X-axis.

For agencies managing multiple clients and needing advanced multi-resource dashboards, RapidDev's team can help build cross-client reporting tools that aggregate Campaign Monitor data with CRM and sales data.

```
// JavaScript query to fetch summaries for multiple campaigns in parallel
const campaigns = getCampaigns.data || [];
const recentCampaigns = campaigns.slice(0, 10); // last 10 campaigns

const summaries = await Promise.all(
  recentCampaigns.map(async campaign => {
    const response = await query('getCampaignSummary', {
      additionalScope: { campaign_id: campaign.CampaignID }
    });
    return {
      ...campaign,
      ...response.data
    };
  })
);

return summaries;
```

**Expected result:** The analytics section shows campaign performance Charts comparing open and click rates across recent campaigns, plus list stats as summary metrics.

## Best practices

- Store your Campaign Monitor API key in Retool Configuration Variables (Settings → Configuration Variables) marked as secret rather than entering it directly in the resource Basic Auth username field.
- Always include the .json extension on all Campaign Monitor API endpoints — requests without the extension return 404 errors regardless of the Accept header.
- Use Campaign Monitor's client-level API keys when building dashboards scoped to a single client — account-level keys expose all client data, which may be inappropriate for client-facing tools.
- Fetch campaign summaries in parallel using a JavaScript query with Promise.all rather than sequentially — summary stats require individual API calls per campaign and sequential calls are slow.
- Cache the getClients and getLists queries for at least 5 minutes since agency client and list configurations change infrequently — this reduces unnecessary API calls on dashboard interactions.
- Use unique open rates (UniqueOpens / TotalRecipients) rather than total open rates for performance metrics — total opens count repeat views by the same subscriber.
- Implement pagination for subscriber lists using Campaign Monitor's page and pagesize parameters — large lists with thousands of subscribers must be paginated to avoid slow queries.
- For write operations (adding subscribers, updating fields), set queries to manual trigger only and include validation in the form that checks for valid email format before submission.

## Use cases

### Build a multi-client campaign performance dashboard

Create a Retool dashboard showing all Campaign Monitor clients and their most recent campaign performance metrics. Account managers can compare open rates, click rates, and unsubscribe rates across clients at a glance, quickly identifying which clients need campaign strategy attention and which are performing above industry benchmarks.

Prompt example:

```
Build a Retool multi-client email performance dashboard. Show all Campaign Monitor clients in a sidebar Select. For the selected client, display recent campaigns in a Table with campaign name, send date, subject line, recipients count, open rate, click rate, bounce rate, and unsubscribe rate. Add a Chart showing open rate trend over the last 10 campaigns. Include color-coded performance badges (green above 25% open rate, yellow 15-25%, red below 15%).
```

### Build a subscriber list management panel

Build a Retool tool for managing subscriber lists across client accounts. Display all lists for a selected client with subscriber counts and growth metrics. Enable operations teams to add subscribers, update contact details, and manage unsubscribes across lists without switching between Campaign Monitor client accounts.

Prompt example:

```
Build a Retool subscriber management panel showing all Campaign Monitor lists for a selected client. Display list name, total active subscribers, total unsubscribes, bounce count, and list created date. When a list is selected, show all subscribers in a Table with email, name, status, and subscription date. Add a Form to add new subscribers with email, name, and custom field values. Include an Unsubscribe button for selected subscribers.
```

### Build an email deliverability monitoring dashboard

Create a Retool analytics panel tracking deliverability metrics across campaigns for a client — bounce rates, spam complaint rates, and unsubscribe trends. This helps identify list hygiene issues before they affect sender reputation, giving agency account managers proactive visibility into deliverability health.

Prompt example:

```
Build a Retool email deliverability dashboard for Campaign Monitor. Show recent campaigns with hard bounce count, soft bounce count, spam complaint count, and unsubscribe count. Add a Chart showing bounce rate trend over the last 12 campaigns. Include a threshold indicator highlighting campaigns where bounce rate exceeds 2% or spam complaints exceed 0.1%.
```

## Troubleshooting

### GET /clients.json returns 401 Unauthorized

Cause: The API key is being sent incorrectly. Campaign Monitor requires the API key as the Basic Auth username, not as a Bearer token or custom header.

Solution: In the Retool resource configuration, select Basic Auth as the authentication type. Enter your Campaign Monitor API key as the Username and the letter 'x' as the Password. Do not use Bearer Token authentication — Campaign Monitor's API v3.3 does not accept Bearer tokens.

### API requests return 404 Not Found for valid endpoint paths

Cause: The .json extension is missing from the endpoint path, or the endpoint path doesn't match Campaign Monitor's URL structure.

Solution: Ensure every Campaign Monitor API endpoint ends with .json (e.g., /clients.json, /campaigns/{id}/summary.json). The base URL in the resource should be https://api.createsend.com/api/v3.3 without a trailing slash. Double-check the endpoint path against Campaign Monitor's API documentation at developer.campaignmonitor.com.

### Subscriber pagination shows the same first page despite incrementing the page number

Cause: Campaign Monitor uses page (1-indexed) and pagesize parameters — if pagination controls are sending 0-indexed page numbers, the first page is returned repeatedly.

Solution: Campaign Monitor pages are 1-indexed (first page = 1, not 0). Ensure your pagination formula is: {{ (table.pagination.currentPage) || 1 }} — not {{ table.pagination.currentPage - 1 }}. Retool's built-in Table pagination starts at 1 by default, so if using Retool's native pagination, the value should pass through directly.

### Campaign open rate or click rate appears incorrect or much lower than expected

Cause: The summary endpoint returns both total and unique counts — open rate should be calculated using UniqueOpens (not Opens) divided by TotalRecipients.

Solution: Use UniqueOpens for open rate calculation: (UniqueOpens / TotalRecipients) * 100. Campaign Monitor's total Opens count includes repeat opens by the same subscriber, which inflates the rate. Similarly, use UniqueClicks for click rate rather than Clicks.

```
// Correct rate calculation
const openRate = campaign.TotalRecipients > 0
  ? ((campaign.UniqueOpens / campaign.TotalRecipients) * 100).toFixed(1) + '%'
  : 'N/A';
```

## Frequently asked questions

### Does Retool have a native Campaign Monitor connector?

No, Retool does not have a dedicated native Campaign Monitor connector. You connect via a REST API Resource using Campaign Monitor's API key in Basic Auth format (key as username, 'x' as password). The connection takes about 15 minutes to configure and gives access to all Campaign Monitor API v3.3 endpoints.

### Can I manage multiple client accounts from a single Retool dashboard?

Yes. Campaign Monitor's account-level API key gives access to all clients under your agency account. The /clients.json endpoint returns all client IDs and names, which you can use to build a Select component that drives the rest of the dashboard. This is exactly the multi-client view that Campaign Monitor's native UI requires you to switch between accounts to see.

### Can I send campaigns from Retool through Campaign Monitor?

Campaign Monitor's API supports triggering sends for campaigns that have already been set up in Campaign Monitor (you can POST to /campaigns/{id}/send.json). Creating new campaigns from scratch via the API is complex as it requires HTML templates, segments, and list configuration. The typical workflow is to design campaigns in Campaign Monitor and use Retool to trigger sends based on business conditions or approval workflows.

### How does Campaign Monitor's API handle transactional emails?

Campaign Monitor's transactional email API is separate from the marketing API. Transactional emails use a different base URL (https://api.transactional.campaignmonitor.com/v1) and require a separate authentication setup. For transactional email integration with Retool, configure a second REST API Resource pointing to the transactional endpoint with appropriate smart email IDs.

### What are Campaign Monitor's API rate limits?

Campaign Monitor's API limits requests to 10 per second per API key. For dashboards that need to fetch campaign summaries for many campaigns simultaneously, use Promise.all in a JavaScript query but limit parallel requests to 10 at a time. If you exceed the rate limit, Campaign Monitor returns a 429 response — add error handling to retry after a short delay.

---

Source: https://www.rapidevelopers.com/retool-integrations/campaign-monitor
© RapidDev — https://www.rapidevelopers.com/retool-integrations/campaign-monitor
