# How to Integrate Retool with Pardot (Salesforce Marketing Cloud Account Engagement)

- Tool: Retool
- Difficulty: Advanced
- Time required: 40 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Pardot (Salesforce Marketing Cloud Account Engagement) by creating a REST API Resource using Salesforce OAuth 2.0 with a Connected App. Use Pardot's v5 API to build marketing-sales alignment dashboards that combine prospect engagement data, email campaign performance, lead scoring, and Salesforce opportunity data — giving marketing ops teams direct visibility into pipeline contribution without switching between Pardot and CRM.

## Build a Pardot Marketing Ops Dashboard in Retool

Pardot is deeply embedded in the Salesforce ecosystem — its data is most valuable when viewed alongside Salesforce CRM records. Marketing teams routinely need to answer questions like: which prospects are engaged but not yet assigned to a rep, which email campaigns are driving the most MQLs, and which Pardot scores correlate with closed-won opportunities. Pardot's native UI provides this visibility but is designed for campaign builders, not for ops teams who need fast data access and custom views.

Retool solves this by giving your marketing operations team a configurable internal tool that queries Pardot's v5 API directly. You can build a prospect management dashboard that shows engagement scores, list memberships, and email open history side by side — with action buttons to reassign a prospect, add them to a nurture list, or push them to Salesforce. When combined with Salesforce's native Retool connector in the same app, you get a unified revenue operations view that neither system's UI provides natively.

Pardot API v5 uses Salesforce's OAuth 2.0 infrastructure for authentication, which means your credentials are secure and respect Salesforce org-level permissions. All requests pass through Retool's server-side proxy, so your Pardot Business Unit ID and access tokens never reach the browser.

## Before you start

- A Salesforce org with Pardot (Marketing Cloud Account Engagement) enabled and a Pardot Business Unit configured
- A Salesforce Connected App with OAuth 2.0 enabled, Consumer Key and Consumer Secret available (Setup → App Manager → New Connected App)
- The Pardot Business Unit ID from Pardot Settings → Business Unit Setup → Business Unit ID
- A Retool account with permission to create Resources and access to the Resources tab
- A Salesforce user account with Pardot API access enabled in their profile permissions

## Step-by-step guide

### 1. Create a Salesforce Connected App for Pardot API access

Before configuring Retool, you need a Salesforce Connected App to obtain OAuth credentials. Log in to Salesforce Setup (⚙️ gear icon → Setup → App Manager → New Connected App). Fill in the app name (e.g., 'Retool Pardot Integration'), contact email, and enable OAuth Settings. Check 'Enable OAuth Settings', set the callback URL to https://retool.com/oauth/consumer (for Retool Cloud, or your Retool instance URL /oauth/consumer for self-hosted). In Selected OAuth Scopes, add: 'Access and manage your data (api)', 'Perform requests on your behalf at any time (refresh_token)', and 'pardot_api'. Save the Connected App — note that it takes 2-10 minutes to activate.

After activation, navigate back to your Connected App and click 'Manage Consumer Details' to reveal the Consumer Key (Client ID) and Consumer Secret (Client Secret). Store these securely — you'll need them for the Retool resource.

Also retrieve your Pardot Business Unit ID: in Pardot, navigate to Settings → Account Settings → Business Unit Setup. The Business Unit ID is a 18-character string starting with '0Uv'. Store this value as a Retool configuration variable — go to Retool Settings → Configuration Variables, create PARDOT_BUSINESS_UNIT_ID (mark as Secret), and PARDOT_CLIENT_ID, PARDOT_CLIENT_SECRET.

**Expected result:** A Salesforce Connected App is created and activated with the pardot_api scope. Consumer Key, Consumer Secret, and Pardot Business Unit ID are stored as Retool configuration variables.

### 2. Configure the Pardot REST API Resource in Retool

Navigate to the Resources tab in your Retool instance and click Add Resource. Select REST API from the resource type list. Name the resource 'Pardot API'.

In the Base URL field, enter https://pi.pardot.com. This is Pardot's API v5 base URL. Pardot API v5 endpoints follow the path pattern /api/v5/{object}/{id}.

For Authentication, select OAuth 2.0 from the dropdown. Configure the OAuth fields as follows: Grant Type = Authorization Code, Client ID = {{ retoolContext.configVars.PARDOT_CLIENT_ID }}, Client Secret = {{ retoolContext.configVars.PARDOT_CLIENT_SECRET }}, Authorization URL = https://login.salesforce.com/services/oauth2/authorize, Access Token URL = https://login.salesforce.com/services/oauth2/token, Scope = api pardot_api refresh_token, Access Token Lifespan = 3600 seconds.

In the Default Headers section, add the required Pardot Business Unit header: Key = Pardot-Business-Unit-Id, Value = {{ retoolContext.configVars.PARDOT_BUSINESS_UNIT_ID }}. This header is mandatory on every Pardot API v5 request — without it, the API returns 403 errors.

Also add: Key = Content-Type, Value = application/json.

Click Save Changes, then click 'Connect OAuth account' to complete the OAuth flow. You'll be redirected to Salesforce's login page to authorize the Connected App. After authorization, Retool stores the access token and refresh token for subsequent requests.

**Expected result:** A Pardot API REST resource is saved with OAuth 2.0 authentication and the Pardot-Business-Unit-Id header. The OAuth connection test succeeds and the resource is ready for queries.

### 3. Query prospects and build the prospect search panel

Create your first query to search for Pardot prospects. In your Retool app, open the Code panel and click the + icon to add a query. Name it searchProspects, select the Pardot API resource, set Method to GET, and set the path to /api/v5/objects/prospects.

Pardot v5 uses filter-based querying through URL parameters. Add the following URL parameters to filter prospects:
- Key: fields, Value: id,email,firstName,lastName,score,grade,campaignId,crmLeadFid,crmContactFid,createdAt,updatedAt,lastActivityAt
- Key: filterById, Value: (leave blank for listing, or use specific IDs)

For email search, create a separate query named searchProspectByEmail with path /api/v5/objects/prospects and URL parameter: Key = filterByFields[email], Value = {{ textInput_email.value }}.

For fetching a prospect's activity history, create getProspectActivities with path /api/v5/objects/prospect-activities and URL parameter: Key = filterByProspectId, Value = {{ table_prospects.selectedRow.id }}.

Add a JavaScript transformer to flatten the nested Pardot response structure for display in a Retool Table component. Bind the Table's data property to {{ searchProspects.data.data?.values }}.

```
// JavaScript transformer — flatten Pardot prospect response
const prospects = data?.data?.values || [];

return prospects.map(prospect => {
  return {
    id: prospect.id,
    email: prospect.email || 'N/A',
    name: `${prospect.firstName || ''} ${prospect.lastName || ''}`.trim() || 'Unknown',
    score: prospect.score ?? 0,
    grade: prospect.grade || 'N/A',
    campaign_id: prospect.campaignId || 'None',
    in_salesforce: prospect.crmLeadFid || prospect.crmContactFid
      ? 'Yes'
      : 'No',
    last_activity: prospect.lastActivityAt
      ? new Date(prospect.lastActivityAt).toLocaleDateString('en-US', {
          year: 'numeric', month: 'short', day: 'numeric'
        })
      : 'Never',
    created: prospect.createdAt
      ? new Date(prospect.createdAt).toLocaleDateString()
      : 'N/A'
  };
});
```

**Expected result:** The searchProspects query returns a list of Pardot prospects with score, grade, and CRM status. The transformer formats the nested response into table rows, and the Retool Table shows all prospect fields cleanly.

### 4. Build campaign and email performance queries

Create queries to retrieve Pardot email campaign performance data. Create a query named getCampaigns with Method GET and path /api/v5/objects/campaigns. Add URL parameters: Key = fields, Value = id,name,cost,createdAt. This returns all campaigns in your Pardot account.

For email statistics, Pardot v5 exposes list email performance through the list-emails endpoint. Create getListEmails with path /api/v5/objects/list-emails and URL parameter: Key = fields, Value = id,name,subject,sentAt,scheduledAt,stats.

The stats field contains nested performance data. Create a transformer named formatEmailStats to extract open rates and click rates:

Bind a Retool Table named table_campaigns to {{ getCampaigns.data.data.values }}. When a campaign row is selected, trigger a filtered getListEmails query that shows all emails in that campaign using the campaignId filter parameter.

Add a Chart component below the table. Set its data property to a transformer that maps email performance data to x/y coordinates for a bar chart showing open rate vs. click rate per email. Select Bar as the chart type, bind X-axis to email name, and add two data series: Open Rate and Click Rate.

For RapidDev-style comprehensive marketing ops panels that combine Pardot email data with Salesforce opportunity attribution, consider using Retool's multi-resource architecture with both the Pardot API resource and Salesforce's native connector in the same app.

```
// JavaScript transformer — format list email stats for chart
const emails = data?.data?.values || [];

return emails.map(email => {
  const stats = email.stats || {};
  const sent = stats.sent || 0;
  const opens = stats.opens || 0;
  const clicks = stats.clicks || 0;

  return {
    name: email.name || email.subject || 'Unnamed',
    subject: email.subject || 'N/A',
    sent: sent,
    open_rate: sent > 0
      ? `${((opens / sent) * 100).toFixed(1)}%`
      : '0%',
    click_rate: sent > 0
      ? `${((clicks / sent) * 100).toFixed(1)}%`
      : '0%',
    open_rate_num: sent > 0 ? parseFloat(((opens / sent) * 100).toFixed(1)) : 0,
    click_rate_num: sent > 0 ? parseFloat(((clicks / sent) * 100).toFixed(1)) : 0,
    sent_date: email.sentAt
      ? new Date(email.sentAt).toLocaleDateString()
      : 'Not sent'
  };
});
```

**Expected result:** The campaigns table populates with all Pardot campaigns. Selecting a campaign triggers the email list query. The Chart component renders a bar chart comparing open rates and click rates across emails in the selected campaign.

### 5. Combine Pardot data with Salesforce opportunities for pipeline attribution

The most powerful Retool-Pardot dashboard combines marketing engagement data from Pardot with revenue outcomes from Salesforce. Add Salesforce as a second resource using Retool's native Salesforce connector (Resources tab → Add Resource → Salesforce → OAuth 2.0).

Create a Salesforce query named getSFOpportunities using SOQL:

Bind a second Table component named table_opportunities to {{ getSFOpportunities.data }}. Configure the table columns to show opportunity name, stage, amount, close date, and lead source.

Create a JavaScript query named matchProspectToOpportunity that cross-references the selected prospect's Pardot ID with Salesforce opportunities by matching the CRM lead or contact ID:

Add a Stat component showing total pipeline value attributed to Pardot-sourced prospects (filter opportunities where LeadSource = 'Marketing Automation' or a custom Pardot campaign source field).

This combined view gives your revenue operations team the marketing-to-pipeline attribution story that neither Pardot's UI nor Salesforce's native reports easily provide.

```
// SOQL query for Salesforce native connector
// Resource: Salesforce | Action: SOQL Query
SELECT
  Id,
  Name,
  StageName,
  Amount,
  CloseDate,
  LeadSource,
  Account.Name,
  Owner.Name
FROM Opportunity
WHERE
  LeadSource = 'Marketing Automation'
  AND CreatedDate >= {{ dateRange.start }}
  AND CreatedDate <= {{ dateRange.end }}
ORDER BY CreatedDate DESC
LIMIT 200
```

**Expected result:** The combined dashboard shows Pardot prospect engagement alongside Salesforce opportunity data. The pipeline attribution panel correctly filters Salesforce opportunities originating from Pardot campaigns and displays total attributed pipeline value.

## Best practices

- Store all Pardot credentials (Client ID, Client Secret, Business Unit ID) as Secret configuration variables in Retool Settings — never paste them directly into resource fields or query bodies.
- Use a dedicated Salesforce Connected App for Retool with minimum required scopes (api, pardot_api, refresh_token) rather than reusing an existing Connected App with broader permissions.
- Enable 'Share OAuth 2.0 credentials between users' in the Pardot resource only if all Retool users should share the same Pardot access level — leave per-user authentication for tools where individual audit trails matter.
- Add the Pardot-Business-Unit-Id header at the resource level (not per-query) so all queries automatically include it — this prevents 403 errors from missing headers on individual queries.
- Use Retool Workflows with a schedule trigger to pre-aggregate Pardot email statistics (open rates, click rates) into a Retool Database table — this avoids hitting Pardot's API rate limits on high-traffic dashboards.
- When combining Pardot and Salesforce data in the same Retool app, use Retool's native Salesforce connector for Salesforce queries rather than a generic REST resource — the native connector handles SOQL, field picklists, and pagination automatically.
- Limit the fields requested in each Pardot API query using the fields URL parameter — Pardot v5 returns all prospect fields by default, which significantly increases response payload size and transformer processing time.
- Add confirmation modals before any write operations in Pardot (adding prospects to lists, updating scores) to prevent accidental bulk changes that could affect active nurture campaigns.

## Use cases

### Build a prospect engagement and lead scoring dashboard

Create a Retool app where marketing ops can search for prospects by email or company, view their Pardot score and grade, see their complete engagement history (email opens, form submissions, page visits), and check their Salesforce assignment status. Add action buttons to manually boost scores, add prospects to lists, or trigger Salesforce sync.

Prompt example:

```
Build a prospect lookup panel with an email search input, a profile section showing Pardot score, grade, and campaign membership, an engagement timeline table showing recent activities, and buttons to add the prospect to a specific list or push to Salesforce CRM.
```

### Campaign performance and email analytics dashboard

Build a Retool dashboard that lists all active Pardot email campaigns with their send counts, open rates, click rates, and resulting MQL counts. Add a date filter and a Chart component showing email performance trends over the last 90 days. Connect to Salesforce to show which campaigns are generating actual pipeline.

Prompt example:

```
Create a campaign analytics panel that fetches all email campaigns from Pardot's campaign endpoint, displays open_rate and click_rate in a sortable Table, and shows a bar chart comparing campaign-attributed opportunities from Salesforce data joined in the same Retool app.
```

### Marketing-sales alignment and MQL handoff tracker

Build an operational panel that shows all prospects who have crossed the MQL threshold (score above a configurable threshold) and are awaiting sales assignment. Display their engagement history, assigned list memberships, and Salesforce owner. Include a bulk-assign button so revenue ops can assign batches of MQLs to sales reps directly from Retool.

Prompt example:

```
Build an MQL queue dashboard that queries Pardot prospects filtered by score_gte=100 and crm_lead_fid IS NULL (not yet synced to Salesforce), shows engagement details for each prospect, and provides a form to assign them to a Salesforce user with a note.
```

## Troubleshooting

### 401 Unauthorized or 'Session has expired or is invalid' error on all Pardot API requests

Cause: The Salesforce OAuth access token has expired. Pardot API v5 access tokens expire after 2 hours by default, and Retool must refresh them using the refresh token stored during the initial OAuth flow.

Solution: In the Pardot API resource settings, verify that 'Automatically refresh OAuth token' is enabled and the Access Token URL is correctly set to https://login.salesforce.com/services/oauth2/token. If the error persists, click 'Reconnect OAuth account' in the resource settings to re-initiate the OAuth flow and generate fresh tokens. Ensure the Connected App has the 'refresh_token' scope included.

### 403 Forbidden with 'PARDOT_BUSINESS_UNIT_ID header is required' message

Cause: The Pardot-Business-Unit-Id header is missing from the resource's default headers, or the Business Unit ID value is incorrect. This header is mandatory for every Pardot API v5 request.

Solution: Go to the Pardot API resource settings in the Resources tab. In the Default Headers section, confirm the header key is exactly 'Pardot-Business-Unit-Id' (case-sensitive) and the value matches your Business Unit ID from Pardot Settings → Account Settings → Business Unit Setup. The ID is an 18-character alphanumeric string starting with '0Uv'. Save and re-test the resource.

### Prospect search returns empty results even though prospects exist in Pardot

Cause: Pardot API v5 filter parameter names require exact syntax. The filterByFields[] parameter format must include the field name in brackets, and email addresses are case-sensitive in some Pardot configurations.

Solution: Verify the URL parameter format for email filtering: the key must be filterByFields[email] (with the field name in square brackets) and the value should be the exact email address. Also confirm the prospects are in the correct Business Unit — if your Pardot org has multiple Business Units, the API only returns prospects belonging to the Business Unit specified in your header.

```
// URL parameter configuration for prospect email search
// Key: filterByFields[email]
// Value:
{{ textInput_email.value.toLowerCase().trim() }}
```

### OAuth connection fails during setup with 'redirect_uri_mismatch' error

Cause: The callback URL configured in the Salesforce Connected App does not match Retool's OAuth consumer URL. Salesforce enforces exact URL matching for OAuth redirect URIs.

Solution: In Salesforce Setup → App Manager, open your Connected App and click Edit. In the Callback URL field, enter exactly https://login.retool.com/oauth/consumer for Retool Cloud. For self-hosted Retool, use https://your-retool-domain.com/oauth/consumer. Save the Connected App and wait 2-10 minutes for Salesforce to apply the changes before retrying the OAuth connection in Retool.

## Frequently asked questions

### Does Pardot have a native connector in Retool?

No, Pardot does not have a dedicated native connector in Retool. Salesforce (the CRM) has a native connector, but Pardot's marketing automation data requires a separate REST API Resource configured with Salesforce OAuth 2.0 and the Pardot API v5 base URL. You must create a Salesforce Connected App with the pardot_api scope to authenticate.

### Why does Pardot API v5 use Salesforce OAuth instead of its own API key?

Pardot was rebranded to Salesforce Marketing Cloud Account Engagement and its API v5 was redesigned to use Salesforce's authentication infrastructure. This means user permissions, IP restrictions, and access control are managed at the Salesforce org level rather than Pardot-specific API keys. Pardot v3 and v4 used a separate Pardot API key, but v5 (the current recommended version) requires Salesforce OAuth exclusively.

### Can I use Retool to write data back to Pardot — for example, update prospect scores or add to lists?

Yes, Pardot API v5 supports write operations using PATCH (for updates) and POST (for creating associations). To update a prospect's score, configure a query with Method = PATCH, path = /api/v5/objects/prospects/{id}, and a JSON body with the score field. To add a prospect to a list, use POST to /api/v5/objects/list-memberships. Make sure your Connected App and Salesforce user have the appropriate Pardot write permissions.

### What is the Pardot API rate limit, and how do I handle it in Retool?

Pardot API v5 allows 25,000 API calls per day per Salesforce org. For dashboards with many simultaneous users, this limit can be a concern. Mitigate it by caching frequently accessed data (campaign lists, email statistics) in a Retool Database table using a scheduled Workflow that refreshes once per hour, and querying the cache rather than calling Pardot directly on every page load.

### How do I build a dashboard that shows which Pardot campaigns are generating Salesforce pipeline?

Add both the Pardot API resource and Salesforce's native Retool connector to the same app. Use Pardot's campaign endpoint to get campaign IDs and names, then query Salesforce using SOQL to find Opportunities where the Campaign field matches Pardot campaign IDs. Join the two datasets in a JavaScript transformer using the campaign ID as the key, then display pipeline value per campaign in a Retool Chart component.

---

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