Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

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

To integrate Pardot (Salesforce Marketing Cloud Account Engagement) with Lovable, create a Supabase Edge Function that authenticates with Salesforce OAuth2 and calls the Pardot API v5. You need your Pardot Business Unit ID, a Salesforce Connected App with OAuth credentials, and all secrets stored in Cloud Secrets. The Pardot API requires a Salesforce access token — you cannot authenticate with Pardot credentials alone.

What you'll learn

  • How to create a Salesforce Connected App for Pardot API access
  • How to implement Salesforce OAuth2 client credentials flow in a Deno Edge Function
  • How to use the Pardot Business Unit ID requirement in API requests
  • How to sync prospects (Pardot's term for leads) from Lovable forms to Pardot
  • How to build a B2B lead scoring dashboard showing Pardot scores and grades
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read75 minutesMarketingMarch 2026RapidDev Engineering Team
TL;DR

To integrate Pardot (Salesforce Marketing Cloud Account Engagement) with Lovable, create a Supabase Edge Function that authenticates with Salesforce OAuth2 and calls the Pardot API v5. You need your Pardot Business Unit ID, a Salesforce Connected App with OAuth credentials, and all secrets stored in Cloud Secrets. The Pardot API requires a Salesforce access token — you cannot authenticate with Pardot credentials alone.

Connect Lovable to Pardot for B2B Lead Scoring and Salesforce-Aligned Marketing Automation

Pardot (now officially named Salesforce Marketing Cloud Account Engagement) is Salesforce's native B2B marketing automation platform. Unlike standalone tools like Marketo or HubSpot, Pardot is designed from the ground up to work alongside Salesforce CRM — prospect records sync bidirectionally with Salesforce contacts and leads, scores and grades appear directly on Salesforce records, and campaign influence can be attributed across the full sales pipeline in Salesforce reports. For B2B organizations already running Salesforce, Pardot is the most natural choice for marketing automation because it eliminates the data synchronization headaches that plague third-party integrations.

Pardot's API v5 authentication has an important architectural constraint that distinguishes it from most other marketing automation platforms: you cannot authenticate with Pardot credentials alone. All API calls require a valid Salesforce OAuth2 access token, obtained by authenticating with a Salesforce Connected App. This Salesforce-first authentication model is a deliberate design choice that reflects Pardot's deep Salesforce integration — but it means the Edge Function must handle a two-step auth flow: first obtain a Salesforce token, then use that token to call Pardot endpoints while including the Pardot Business Unit ID.

Building a Lovable integration with Pardot enables powerful B2B marketing use cases: a prospect scoring dashboard showing which leads are most sales-ready based on Pardot's engagement scores and grades, a form handler that creates Pardot prospects with campaign attribution, or a Salesforce-aligned reporting tool that shows how marketing activities convert to pipeline.

Integration method

Edge Function Integration

Pardot API v5 authentication is Salesforce-first: you authenticate with Salesforce OAuth2 to get an access token, then include both the access token and your Pardot Business Unit ID in all Pardot API requests. A Supabase Edge Function handles this two-step auth flow using a Salesforce Connected App's client credentials stored in Cloud Secrets.

Prerequisites

  • A Lovable project with Lovable Cloud enabled
  • A Salesforce org with Pardot (Marketing Cloud Account Engagement) provisioned
  • Salesforce admin access to create a Connected App
  • Your Pardot Business Unit ID (found in Pardot Settings → Account Settings → My Account)
  • Understanding that Pardot API v5 requires Salesforce OAuth tokens — Pardot credentials alone are insufficient

Step-by-step guide

1

Create a Salesforce Connected App for Pardot API access

Log in to Salesforce Setup (click the gear icon → Setup). In the left sidebar, navigate to Apps → App Manager. Click New Connected App. Fill in the Connected App Name (e.g., 'Lovable Pardot Integration'), API Name (auto-filled), and Contact Email. Under OAuth Settings, check Enable OAuth Settings. In the Callback URL field, enter https://login.salesforce.com/services/oauth2/callback (a placeholder — you will use client credentials, not user-based OAuth). In Selected OAuth Scopes, add: 'Manage Pardot services (pardot_api)', 'Full access (full)', and 'Perform requests at any time (refresh_token, offline_access)'. Check Enable Client Credentials Flow. Save the Connected App. After saving, click Manage Consumer Details to see the Consumer Key (Client ID) and Consumer Secret (Client Secret). Also note: go to the Connected App's Manage page and click Edit Policies. Set OAuth Policies → IP Relaxation to 'Relax IP restrictions' if your Edge Function IPs are not whitelisted. Set Permitted Users to 'All users may self-authorize'. Finally, find your Pardot Business Unit ID in Pardot (from the Pardot account URL or in Pardot Settings → My Account — it looks like 0Uv000000xxxxxxxxx).

Pro tip: After creating the Connected App, wait 2–10 minutes before using it — Salesforce needs time to propagate the new Connected App's permissions across their infrastructure.

Expected result: You have a Salesforce Connected App with Consumer Key and Consumer Secret, and you have noted your Pardot Business Unit ID.

2

Find your Pardot Business Unit ID

The Pardot Business Unit ID is required for every Pardot API v5 request. It is passed as a header named 'Pardot-Business-Unit-Id'. To find it, log into Pardot (via Salesforce App Launcher → Account Engagement). In Pardot, go to Settings (gear icon) → Account Settings → My Account. Look for the Account ID or Business Unit ID field — it is a long string beginning with '0Uv'. Alternatively, you can find it in the URL when logged into Pardot — the Pardot Account ID appears in the URL. If you cannot find it in the Pardot UI, you can also retrieve it via the Salesforce API by querying the Pardot Business Unit object, or ask your Salesforce admin. The Business Unit ID is specific to your Pardot instance and does not change. If your organization has multiple Pardot business units (enterprise feature), make sure you are using the correct one.

Pro tip: The Pardot Business Unit ID always starts with '0Uv'. If the ID you find starts with a different prefix, double-check that you are looking at the Account Engagement (Pardot) Business Unit ID and not a different Salesforce object ID.

Expected result: You have your Pardot Business Unit ID (format: 0Uv000000xxxxxxxxx) ready to store in Cloud Secrets.

3

Store all credentials in Cloud Secrets

In your Lovable project, open the Cloud tab by clicking the plus (+) icon next to the preview. Navigate to Secrets and add four secrets: SALESFORCE_CLIENT_ID (the Consumer Key from your Connected App), SALESFORCE_CLIENT_SECRET (the Consumer Secret from your Connected App), PARDOT_BUSINESS_UNIT_ID (your Pardot Business Unit ID starting with 0Uv), and SALESFORCE_USERNAME plus SALESFORCE_PASSWORD if using password flow (for client credentials flow, you only need Client ID and Secret plus a username/password for the user the Connected App will act as). For the client credentials OAuth flow, also add SALESFORCE_INSTANCE_URL (your Salesforce instance URL like https://mycompany.my.salesforce.com). Click Save after each secret. Never put these in Lovable's chat or in code — the Salesforce Client Secret in particular grants access to your entire Salesforce org's data.

Pro tip: For the client credentials OAuth flow (username/password grant), also store SALESFORCE_USERNAME and SALESFORCE_PASSWORD. The password may need a security token appended (SALESFORCE_PASSWORD = yourpassword + yoursecuritytoken) if your Salesforce org requires it.

Expected result: All required secrets (SALESFORCE_CLIENT_ID, SALESFORCE_CLIENT_SECRET, PARDOT_BUSINESS_UNIT_ID, SALESFORCE_USERNAME, SALESFORCE_PASSWORD, SALESFORCE_INSTANCE_URL) are stored in Cloud Secrets.

4

Create the Pardot OAuth2 proxy Edge Function

Build the Edge Function that handles the two-step authentication flow and proxies Pardot API calls. Step 1: obtain a Salesforce OAuth2 access token using the username-password grant (POST to https://login.salesforce.com/services/oauth2/token with grant_type=password, username, password, client_id, client_secret). Step 2: use the access token to call Pardot API v5 endpoints, including the Pardot-Business-Unit-Id header. Cache the Salesforce token in a Supabase table with its expiry time to avoid re-authenticating on every request. Accept POST requests with a JSON body specifying the HTTP method, the Pardot API endpoint path (like /api/prospect/version/5/do/query), and an optional request body.

Lovable Prompt

Create a Supabase Edge Function at supabase/functions/pardot-proxy/index.ts that: (1) authenticates with Salesforce using username-password OAuth2 grant from SALESFORCE_CLIENT_ID, SALESFORCE_CLIENT_SECRET, SALESFORCE_USERNAME, SALESFORCE_PASSWORD secrets, (2) caches the access token in a Supabase table, (3) accepts POST requests with method, endpoint, and body fields, and (4) calls the Pardot API v5 at the Salesforce instance URL with the access token and PARDOT_BUSINESS_UNIT_ID header. Return results with CORS headers.

Paste this in Lovable chat

supabase/functions/pardot-proxy/index.ts
1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
2import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
3
4const corsHeaders = {
5 'Access-Control-Allow-Origin': '*',
6 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
7}
8
9async function getSalesforceToken(clientId: string, clientSecret: string, username: string, password: string, supabase: any): Promise<{ token: string, instanceUrl: string }> {
10 const { data: cached } = await supabase
11 .from('pardot_token_cache')
12 .select('access_token, instance_url, expires_at')
13 .gt('expires_at', new Date(Date.now() + 300000).toISOString())
14 .single()
15
16 if (cached) return { token: cached.access_token, instanceUrl: cached.instance_url }
17
18 const params = new URLSearchParams({
19 grant_type: 'password',
20 client_id: clientId,
21 client_secret: clientSecret,
22 username,
23 password,
24 })
25
26 const resp = await fetch('https://login.salesforce.com/services/oauth2/token', {
27 method: 'POST',
28 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
29 body: params.toString(),
30 })
31
32 const data = await resp.json()
33 if (!data.access_token) throw new Error(`Salesforce auth failed: ${JSON.stringify(data)}`)
34
35 const expiresAt = new Date(Date.now() + 7200000).toISOString() // 2 hour cache
36 await supabase.from('pardot_token_cache').upsert({
37 id: 1,
38 access_token: data.access_token,
39 instance_url: data.instance_url,
40 expires_at: expiresAt,
41 }, { onConflict: 'id' })
42
43 return { token: data.access_token, instanceUrl: data.instance_url }
44}
45
46serve(async (req) => {
47 if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders })
48
49 try {
50 const supabase = createClient(Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!)
51 const businessUnitId = Deno.env.get('PARDOT_BUSINESS_UNIT_ID')!
52
53 const { token, instanceUrl } = await getSalesforceToken(
54 Deno.env.get('SALESFORCE_CLIENT_ID')!,
55 Deno.env.get('SALESFORCE_CLIENT_SECRET')!,
56 Deno.env.get('SALESFORCE_USERNAME')!,
57 Deno.env.get('SALESFORCE_PASSWORD')!,
58 supabase,
59 )
60
61 const { method, endpoint, body: requestBody } = await req.json()
62
63 const pardotUrl = `${instanceUrl}/services/apexrest/pardot${endpoint}`
64 // Use the v5 API path format
65 const pardotV5Url = `${instanceUrl}${endpoint.startsWith('/') ? endpoint : '/' + endpoint}`
66
67 const response = await fetch(pardotV5Url, {
68 method: method || 'GET',
69 headers: {
70 'Authorization': `Bearer ${token}`,
71 'Pardot-Business-Unit-Id': businessUnitId,
72 'Content-Type': 'application/json',
73 },
74 body: requestBody ? JSON.stringify(requestBody) : undefined,
75 })
76
77 const data = await response.json()
78 return new Response(JSON.stringify(data),
79 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } })
80 } catch (error) {
81 return new Response(JSON.stringify({ error: error.message }),
82 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } })
83 }
84})

Pro tip: Create the pardot_token_cache table with columns: id (int, primary key, default 1), access_token (text), instance_url (text), expires_at (timestamptz). The single-row pattern works because you typically only have one Salesforce org to authenticate against.

Expected result: The pardot-proxy Edge Function authenticates with Salesforce, caches the token, and can proxy Pardot API v5 requests. Test by calling it with endpoint='/services/pardot/version/5/prospect/query?fields=email,score,grade&limit=5'.

5

Build the B2B lead scoring dashboard

Build the Pardot prospect scoring dashboard in Lovable. Use the Edge Function to fetch prospects with their scores and grades. The Pardot API v5 uses RESTful endpoints — to query prospects, call GET /services/pardot/version/5/prospect/query with parameters for fields, filters, limit, and offset. The score field is a numeric value from Pardot's behavioral scoring. The grade field is a letter grade (A, B, C, D, E, or F) from Pardot's explicit profiling model. Display these in a dashboard with color-coded indicators: A and B grades in green, C in yellow, D and F in red. Include filters for score range, grade, assigned sales rep, and date range. Allow clicking into individual prospects to see their full activity history from Pardot.

Lovable Prompt

Create a Pardot B2B lead scoring dashboard that calls our pardot-proxy Edge Function with endpoint='/services/pardot/version/5/prospect/query' to fetch prospects. Display a table with prospect name, company, email, score (as a progress bar 0-200), grade (A-F with color coding), assigned_to, and last activity date. Add filters for minimum score, grade, and assigned rep. Include a 'View Activities' button that fetches the prospect's activity list.

Paste this in Lovable chat

Pro tip: Pardot API v5 returns prospects in pages of up to 200 records. Use the offset parameter for pagination if your database has more prospects than the page size.

Expected result: A working B2B lead scoring dashboard showing Pardot prospects with their behavioral scores and fit grades, with filtering and drill-down to individual prospect activity history.

Common use cases

B2B lead scoring dashboard for sales teams

Display Pardot prospect scores and grades for leads assigned to each sales rep. A prospect with a high Pardot score (behavioral engagement) and a high grade (fit with ideal customer profile) is the highest priority for outreach. This dashboard surfaces these signals without requiring sales reps to log into Pardot.

Lovable Prompt

Create a B2B lead scoring dashboard that calls our pardot-proxy Edge Function to fetch prospects with score above 50. Show a table with prospect name, company, email, Pardot score, Pardot grade, last activity, and Salesforce owner. Sort by score descending. Add a high-priority badge for prospects with score > 100 and grade A or B.

Copy this prompt to try it in Lovable

Gated content with Pardot prospect creation and campaign attribution

Build a gated resource download flow in Lovable. When a visitor fills out the form, create them as a Pardot prospect via your Edge Function, associate them with the relevant Pardot campaign, and send a Pardot completion action to email the resource. This integrates seamlessly with Pardot's lead nurturing workflows.

Lovable Prompt

Create a gated whitepaper download page. When a user submits the form (first name, last name, email, company, job title), call our pardot-proxy Edge Function to create or update them as a Pardot prospect and associate them with campaign ID 12345. On success, show the download button. Include proper error handling if the Pardot API call fails.

Copy this prompt to try it in Lovable

Pardot campaign performance reporting

Pull Pardot campaign performance metrics (sent emails, open rates, click rates, prospect conversions) into a Lovable dashboard. Marketing managers can see all campaign performance in one view without navigating Pardot's built-in reporting.

Lovable Prompt

Build a campaign performance dashboard that calls our pardot-proxy Edge Function to fetch all active Pardot email campaigns with their open rate, click rate, and unsubscribe rate statistics. Display them in a table sorted by send date descending. Show a summary card with total emails sent this quarter and average open rate.

Copy this prompt to try it in Lovable

Troubleshooting

Salesforce OAuth returns 'invalid_client' or 'invalid_grant' errors

Cause: The Connected App Client ID or Client Secret is incorrect, or the username/password combination is wrong. For password flow, the password may need a security token appended.

Solution: Verify the Connected App credentials in Salesforce Setup → Apps → App Manager → your Connected App → Manage Consumer Details. For username/password grant, the password value should be passwordSecurityToken (with no separator). Find your security token in Salesforce Settings → Reset My Security Token, or disable the IP restriction requirement in Connected App policies.

typescript
1// Password for username-password grant = password + security_token
2// e.g., if password is 'mypassword' and security token is 'abc123'
3// SALESFORCE_PASSWORD = 'mypasswordabc123'

Pardot API returns 'Invalid Business Unit' or business unit header errors

Cause: The PARDOT_BUSINESS_UNIT_ID does not match any business unit in the Salesforce org, or the header name is incorrect.

Solution: Verify the Business Unit ID starts with '0Uv'. Verify the header name is exactly 'Pardot-Business-Unit-Id' (case-sensitive). You can find all Business Unit IDs in Salesforce by querying: SELECT Id, Name FROM ConnectedAccount WHERE Type = 'PardotBU' in Salesforce Developer Console.

typescript
1// Correct header name (case-sensitive)
2'Pardot-Business-Unit-Id': businessUnitId

Pardot API returns 'You must enable API usage for this user' error

Cause: The Salesforce user account used for authentication does not have Pardot API access enabled, or the user does not have a Pardot user record.

Solution: In Pardot Settings → User Management, verify that the user associated with your API credentials has an active Pardot user record with API access enabled. The user's Pardot role must allow API usage. Create a dedicated Pardot API-only user with a Marketing role and API access enabled.

Salesforce token expires and Pardot API starts returning 401 errors

Cause: The cached Salesforce access token has expired. The username-password grant issues tokens with a 2-hour validity by default.

Solution: Ensure the token cache TTL in your Edge Function is set to slightly less than 2 hours (e.g., 1.5 hours = 5,400,000 ms). If tokens expire more frequently, your Salesforce org may have session settings that limit token lifetime — check Salesforce Setup → Session Settings for session timeout configuration.

typescript
1// Set cache expiry to 90 minutes to be safe
2const expiresAt = new Date(Date.now() + 5400000).toISOString()

Best practices

  • Use a dedicated Salesforce user account for the API connection — never use a personal admin account, as password changes would break the integration
  • Cache the Salesforce OAuth access token in Supabase with an expiry 30 minutes shorter than the actual token lifetime as a safety buffer
  • Always include error handling for the case where Salesforce returns an expired token mid-session — clear the cache and re-authenticate automatically
  • The Pardot Business Unit ID never changes — store it as a Cloud Secret and reference it consistently rather than hardcoding it anywhere
  • Use Pardot's activity logging endpoints to create custom activities rather than relying solely on Munchkin-style tracking for better scoring accuracy
  • Respect Pardot's API rate limits (typically 1,000 requests per minute) — implement caching for frequently-accessed prospect data
  • For high-volume lead sync, consider using Pardot's batch prospect upsert endpoint rather than creating prospects one at a time
  • RapidDev's team can help configure complex Pardot/Salesforce authentication setups, particularly for organizations with IP whitelisting or stricter OAuth policies

Alternatives

Frequently asked questions

What is the difference between Pardot and Salesforce Marketing Cloud?

Pardot (Marketing Cloud Account Engagement) is Salesforce's B2B marketing automation platform, designed for long sales cycles, lead nurturing, and CRM alignment. Salesforce Marketing Cloud is a separate product focused on B2C marketing at scale — email, SMS, social, advertising, and customer journeys for large consumer-facing brands. They are different products that Salesforce sells to different customer segments and should not be confused.

Why does Pardot API require Salesforce OAuth and not Pardot credentials?

Pardot was acquired by Salesforce in 2013 and has been progressively integrated into the Salesforce platform. In 2021, Salesforce deprecated Pardot's legacy authentication method and made Salesforce OAuth the only supported authentication for Pardot API v5. This reflects the product's direction as a native Salesforce application rather than a standalone tool — all Pardot data is now stored in Salesforce objects, so Salesforce authentication is architecturally required.

What is a Pardot Business Unit ID and where do I find it?

A Pardot Business Unit ID identifies your specific Pardot instance within Salesforce. It is required for all Pardot API v5 requests as the 'Pardot-Business-Unit-Id' header. Find it in Pardot Settings → Account Settings (look for 'Business Unit ID' or 'Account ID' — it starts with '0Uv'). If your Salesforce org has multiple Pardot Business Units (an enterprise feature), make sure you use the correct one for your integration.

Can I sync Pardot prospects to Supabase for custom reporting?

Yes. Set up a scheduled Supabase Edge Function (using Supabase's cron job feature) that runs daily, queries the Pardot API for updated prospects, and upserts them into a Supabase table. This creates a local copy of Pardot prospect data for fast querying and custom reporting without hitting Pardot's API rate limits on every dashboard view.

What is Pardot's score and grade and how do they differ?

Pardot uses two complementary lead qualification signals. Score is a behavioral measure: it increases when a prospect visits pages, opens emails, clicks links, or downloads content. Higher scores indicate more engagement. Grade is a fit measure: Pardot's automation compares prospect profile data (job title, company size, industry) against your ideal customer profile definition and assigns a letter grade from A to F. A high score with a high grade (A or B) indicates a prospect who is both engaged and a good fit — the ideal combination for sales outreach.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.