# How to Integrate Lovable with SharpSpring

- Tool: Lovable
- Difficulty: Intermediate
- Time required: 45 minutes
- Last updated: March 2026

## TL;DR

To integrate SharpSpring (now Constant Contact Lead Gen & CRM) with Lovable, create a Supabase Edge Function that authenticates with the SharpSpring Open API using your Account ID and Secret Key. The Edge Function makes JSON-RPC calls to sync leads, update opportunities, and manage email campaigns. SharpSpring's agency-focused white-label model and CRM integration make it popular for digital agencies building client reporting dashboards.

## Connect Lovable to SharpSpring for Agency Lead Tracking and CRM Integration

SharpSpring, recently acquired by and rebranded under Constant Contact as 'Lead Gen & CRM', is a marketing automation platform specifically designed for digital marketing agencies. Its white-label capabilities allow agencies to rebrand the entire platform for their clients, and its agency pricing model (flat fee for unlimited contacts, rather than per-contact pricing) makes it more economical than HubSpot or Marketo for agencies managing dozens of client accounts.

Building a Lovable integration with SharpSpring opens up several valuable use cases for agency teams and their clients: a custom lead dashboard that pulls SharpSpring pipeline data into a white-labeled client reporting interface, a Lovable app that syncs form submissions directly to SharpSpring leads bypassing SharpSpring's native forms, or an internal tool that updates opportunity stages in SharpSpring based on events in other business systems.

SharpSpring's Open API uses JSON-RPC 2.0 — a slightly different pattern than REST. Each API call is a POST request to a single endpoint with a JSON body specifying the method name and parameters. Authentication uses your Account ID and a Secret Key, both passed as query parameters in the API URL. This means the credentials must never appear in frontend code and must always be handled server-side through a Supabase Edge Function.

## Before you start

- A Lovable project with Lovable Cloud enabled
- A SharpSpring account with API access (available on all plans)
- Your SharpSpring Account ID and Secret Key from Admin → API Settings in SharpSpring
- Basic familiarity with JSON-RPC concepts (method name + params in a POST body)

## Step-by-step guide

### 1. Get your SharpSpring API credentials

Log in to SharpSpring and navigate to the Admin section. Find API Settings (typically under Admin → API Settings or Account Settings → API). On this page, you will see your Account ID (a numeric string, e.g. '12345678') and your Secret Key (a long alphanumeric string). These two values together authenticate all SharpSpring API requests. Copy both values. Note that SharpSpring's API endpoint is https://api.sharpspring.com/pubapi/v1/ — the Account ID and Secret Key are passed as query parameters in the URL (accountID and secretKey), not in the request headers. This is different from most modern APIs, but it means the credentials are even more critical to keep server-side — they would be visible in the browser's network tab if called from frontend code. If you are working in a SharpSpring white-label account provided by your agency, ask your account manager for the API credentials — they may need to enable API access for your account.

**Expected result:** You have your SharpSpring Account ID and Secret Key ready to store in Cloud Secrets.

### 2. Store credentials in Cloud Secrets

In your Lovable project, open the Cloud tab by clicking the plus (+) icon next to the preview panel. Navigate to the Secrets section and add two new secrets. First, add SHARPSPRING_ACCOUNT_ID with your SharpSpring Account ID as the value. Second, add SHARPSPRING_SECRET_KEY with your Secret Key. Click Save after each entry. These values will be available in Edge Functions via Deno.env.get('SHARPSPRING_ACCOUNT_ID') and Deno.env.get('SHARPSPRING_SECRET_KEY'). The Edge Function will append these to the SharpSpring API URL as query parameters — this is the required authentication method for SharpSpring's API and is safe because it happens server-side in the Edge Function, never in the browser.

**Expected result:** SHARPSPRING_ACCOUNT_ID and SHARPSPRING_SECRET_KEY both appear in Cloud Secrets with values masked.

### 3. Create the SharpSpring JSON-RPC proxy Edge Function

Build the Edge Function that wraps SharpSpring's JSON-RPC API. The function accepts a POST request with a JSON body specifying the method and params to call. It constructs the SharpSpring API URL with credentials as query parameters, creates the JSON-RPC 2.0 envelope with the specified method and params, sends the POST request to SharpSpring, and returns the result. Common SharpSpring API methods include getLeads (fetch leads with filter parameters), createLead (create a new lead), updateLead (update an existing lead), getOpportunities (fetch opportunities), updateOpportunity (update opportunity stage), and createActivity (log an activity against a lead). The JSON-RPC envelope format is straightforward: a JSON object with method, params (the SharpSpring method parameters), id (a unique request ID), and jsonrpc version.

```
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}

serve(async (req) => {
  if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders })

  try {
    const accountId = Deno.env.get('SHARPSPRING_ACCOUNT_ID')
    const secretKey = Deno.env.get('SHARPSPRING_SECRET_KEY')

    if (!accountId || !secretKey) {
      return new Response(
        JSON.stringify({ error: 'SharpSpring credentials not configured' }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const { method, params } = await req.json()

    if (!method) {
      return new Response(
        JSON.stringify({ error: 'method is required' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const apiUrl = `https://api.sharpspring.com/pubapi/v1/?accountID=${accountId}&secretKey=${secretKey}`

    const requestId = crypto.randomUUID()
    const rpcBody = {
      method,
      params: params || {},
      id: requestId,
      jsonrpc: '1.2',
    }

    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(rpcBody),
    })

    const data = await response.json()

    // SharpSpring returns errors in result.error field
    if (data.error) {
      return new Response(
        JSON.stringify({ error: 'SharpSpring API error', details: data.error }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    return new Response(
      JSON.stringify(data.result || data),
      { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }
})
```

**Expected result:** The sharpspring-proxy Edge Function is deployed. Test by calling it with method='getLeads' and params={where: {}, limit: 5, offset: 0} — it should return your first 5 SharpSpring leads.

### 4. Build the lead management dashboard

With the Edge Function working, build a lead tracking dashboard in Lovable. The most valuable first screen for agencies is a pipeline view: leads categorized by stage, with counts and recent activity. Call the getLeads method to fetch leads with their status and source fields, and getOpportunities to fetch open opportunities with their stage and value. Display a summary of new leads this week, a pipeline stage breakdown as a horizontal bar or funnel chart, and a sortable table of recent leads with columns for name, email, company, lead source, status, and creation date. Add the ability to click a lead to see their full details and update their status via an updateLead call. For agencies managing multiple client accounts, add a client account selector that switches which SharpSpring account credentials are used — this requires storing multiple credential sets and routing to the appropriate secret.

**Expected result:** A working CRM dashboard displaying SharpSpring leads with filtering, status updates, and pipeline visibility. Lead status changes made in the Lovable dashboard reflect immediately in SharpSpring.

## Best practices

- Store Account ID and Secret Key as separate Cloud Secrets rather than combining them — this makes individual rotation easier
- Generate a unique request ID for each JSON-RPC call using crypto.randomUUID() — SharpSpring uses this for idempotency and debugging
- Use SharpSpring's limit and offset parameters for pagination — never assume you will get all records in one call for accounts with large lead databases
- Cache getLeads and getOpportunities responses in Supabase with a short TTL (5–15 minutes) for dashboards that display summary data that does not need to be real-time
- When syncing leads from Lovable forms, check if a lead with the same email already exists (use getLeads with email in where clause) before creating a new one to avoid duplicates
- Test all API calls in SharpSpring's sandbox environment if available — SharpSpring offers a sandbox for development testing that does not affect production data
- Always check the data.error field in SharpSpring JSON-RPC responses — a successful HTTP 200 response can still contain a SharpSpring-level error in the result
- For agency multi-client setups, use a Supabase table to store client-specific SharpSpring credentials and route requests based on the authenticated user's client association

## Use cases

### White-label client lead reporting dashboard

Build a Lovable dashboard for agency clients that shows their lead pipeline from SharpSpring: new leads this month, leads by source, open opportunities by stage, and recent activity. The client sees branded reporting without needing SharpSpring access.

Prompt example:

```
Create a client lead dashboard that calls our sharpspring-proxy Edge Function to fetch leads from the last 30 days, grouped by lead source. Show metric cards for total leads, qualified leads, and open opportunities. Display a pipeline kanban board with opportunities grouped by stage. Use our agency's brand colors.
```

### Form-to-SharpSpring lead capture without native forms

Use a custom Lovable form for lead capture on client websites, submitting data directly to SharpSpring via your Edge Function. This gives full control over form design while keeping SharpSpring as the backend CRM — eliminating dependency on SharpSpring's form embed code.

Prompt example:

```
Create a contact form in Lovable that, when submitted, calls our sharpspring-proxy Edge Function to create a lead in SharpSpring with the form fields: first name, last name, email, company, phone, and a custom field for how they heard about us. Show a success message and redirect to a thank-you page after submission.
```

### App event to opportunity stage updater

When a prospect completes a key action in your Lovable app (books a demo, completes a trial, signs a proposal), automatically update their SharpSpring opportunity stage to reflect this progression. This keeps the CRM in sync with real-world deal progression without manual data entry.

Prompt example:

```
When a user completes our demo booking flow in the Lovable app, call our sharpspring-proxy Edge Function to find their SharpSpring lead by email and update their opportunity stage to 'Demo Scheduled'. Log an activity note with the demo date and time. Silently handle this in the background without interrupting the user flow.
```

## Troubleshooting

### SharpSpring API returns an error saying the session is invalid or credentials are wrong

Cause: The Account ID or Secret Key is incorrect, has extra whitespace, or the API access has been disabled for the account.

Solution: Log in to SharpSpring Admin → API Settings and re-copy the Account ID and Secret Key. Re-enter them in Cloud → Secrets. Verify there are no spaces or line breaks. Also confirm API access is enabled for the account — in some SharpSpring plans or white-label setups, API access requires explicit enablement.

### Calls to getLeads return empty results even though leads exist in SharpSpring

Cause: SharpSpring's getLeads requires specific where clause parameters to filter leads. An empty where object may not return results on some SharpSpring versions.

Solution: Try adding a date filter to the where clause: where: {updateTimestamp: {op: 'BETWEEN', values: ['2024-01-01', '2030-01-01']}}. SharpSpring's filtering uses an op/values pattern for comparisons.

```
// Add date range filter to where clause
const params = {
  where: {
    updateTimestamp: {
      op: 'BETWEEN',
      values: ['2020-01-01', '2030-01-01']
    }
  },
  limit: 100,
  offset: 0
}
```

### createLead returns success but the lead is not visible in SharpSpring

Cause: Required fields are missing. SharpSpring requires at minimum an email address and first name for lead creation. Without these, the lead may be created in an incomplete state that does not surface in the default lead view.

Solution: Ensure the lead object in your createLead params includes at minimum emailAddress and firstName fields. SharpSpring field names use camelCase format (emailAddress, firstName, lastName, companyName).

```
// Minimum required fields for createLead
const leadParams = {
  objects: [{
    emailAddress: email,
    firstName: first_name,
    lastName: last_name || '',
    companyName: company || '',
  }]
}
```

## Frequently asked questions

### Is SharpSpring now part of Constant Contact?

Yes. Constant Contact acquired SharpSpring in 2022 and rebranded it as 'Constant Contact Lead Gen & CRM'. The SharpSpring platform continues to operate under both the SharpSpring and Constant Contact Lead Gen & CRM names. The API, functionality, and agency model remain largely the same. The domain sharpspring.com still works, and the API endpoint at api.sharpspring.com is unchanged.

### Does SharpSpring have per-contact pricing like HubSpot or Marketo?

SharpSpring's pricing model is one of its key differentiators from HubSpot and Marketo — it charges a flat monthly fee based on the number of user seats rather than the number of contacts. This makes it significantly more cost-effective for agencies managing clients with large contact databases. A typical agency plan covers unlimited contacts for a set of users.

### What is JSON-RPC and how is it different from REST?

JSON-RPC is a remote procedure call protocol that uses JSON as the data format. Instead of different URL endpoints for different operations (the REST pattern), JSON-RPC uses a single endpoint for all calls and specifies the operation in the request body as a 'method' field. SharpSpring uses JSON-RPC 1.2, where each request body includes: method (the operation name), params (the operation parameters), id (a unique request identifier), and jsonrpc ('1.2'). The response follows the same structure with result or error fields.

### Can I use SharpSpring's tracking code in a Lovable app?

Yes. SharpSpring provides a JavaScript tracking code similar to Marketo's Munchkin that tracks visitor behavior. You can add it to your Lovable app's index.html to track anonymous visitor activity, and SharpSpring will associate this activity with known leads when they are identified via form submission or email click. Add the tracking code in the <head> section of index.html using Lovable's project settings.

### How does SharpSpring handle duplicate leads?

SharpSpring uses email address as the primary deduplication key. If you call createLead with an email that already exists, SharpSpring creates a duplicate lead rather than updating the existing one. To avoid duplicates, always check for an existing lead with getLeads filtering by emailAddress before creating a new one, or use an updateLead call if the lead already exists.

---

Source: https://www.rapidevelopers.com/lovable-integration/sharpspring
© RapidDev — https://www.rapidevelopers.com/lovable-integration/sharpspring
