Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with LeadSquared

Integrate LeadSquared with Bolt.new using their REST API with access key and secret key authentication in custom request headers. Capture leads from Bolt forms via API route, fetch lead details and activity history, and build a lead management dashboard. LeadSquared uses a unique x-LSQ-AccessKey and x-LSQ-SecretKey header authentication pattern — store both keys server-side. Webhook-based automation triggers require a deployed Netlify URL.

What you'll learn

  • How to authenticate with LeadSquared's custom header authentication scheme from a Next.js API route
  • How to capture leads from Bolt.new forms into LeadSquared with source tracking
  • How to fetch lead details and activity history using the LeadSquared API
  • How to build a lead management dashboard with scoring visualization
  • How to configure LeadSquared webhook notifications on a deployed Netlify URL
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate18 min read25 minutesMarketingApril 2026RapidDev Engineering Team
TL;DR

Integrate LeadSquared with Bolt.new using their REST API with access key and secret key authentication in custom request headers. Capture leads from Bolt forms via API route, fetch lead details and activity history, and build a lead management dashboard. LeadSquared uses a unique x-LSQ-AccessKey and x-LSQ-SecretKey header authentication pattern — store both keys server-side. Webhook-based automation triggers require a deployed Netlify URL.

Connect Bolt.new Forms and Dashboards to LeadSquared CRM

LeadSquared is one of the leading CRM platforms in India and Southeast Asia, with particularly strong adoption in education, healthcare, financial services, and field sales industries. Unlike Salesforce or HubSpot (which require significant configuration for high-volume lead operations), LeadSquared is purpose-designed for the specific workflows of sales teams handling thousands of leads per day — structured calling queues, automated lead distribution, field sales apps with offline capability, and role-based access control for large sales hierarchies.

For Bolt.new developers working with clients or companies in these markets, integrating lead capture and management features with LeadSquared is a natural requirement. The API supports all the operations you would need: creating leads (called 'Prospects' in some LeadSquared versions), logging sales activities against contacts, updating lead quality scores, retrieving lead details, and querying leads by various criteria.

LeadSquared's authentication model uses custom HTTP headers — x-LSQ-AccessKey and x-LSQ-SecretKey — rather than OAuth or Bearer tokens. Both keys appear in every API request header. Since these headers are included in every call to `api.leadsquared.com`, they must stay server-side in your Next.js API routes. A client-side fetch to LeadSquared would expose both keys in browser developer tools.

Integration method

Bolt Chat + API Route

LeadSquared's REST API uses a custom header authentication scheme with x-LSQ-AccessKey and x-LSQ-SecretKey values that must be included in every request. All API calls from Bolt must go through a Next.js API route with these keys stored in server-side environment variables — never in client code. The API supports lead creation, activity logging, custom field management, and lead scoring. Webhook notifications for automation events require a deployed Netlify URL.

Prerequisites

  • A LeadSquared account at leadsquared.com — API access requires a paid LeadSquared subscription
  • LeadSquared API credentials: go to My Profile → API Settings to find your Access Key and Secret Key
  • The LeadSquared API host URL for your account region (e.g., api.leadsquared.com for India, api-us.leadsquared.com for US)
  • A Bolt.new account with a new Next.js project open
  • A Netlify account for deployment if you plan to use LeadSquared webhook notifications

Step-by-step guide

1

Get LeadSquared API credentials and understand the authentication pattern

LeadSquared uses a custom header-based authentication scheme that is different from most modern APIs. Rather than OAuth tokens or Bearer authentication, every API request must include two custom headers: `x-LSQ-AccessKey` containing your Access Key, and `x-LSQ-SecretKey` containing your Secret Key. Both are required for every request — missing either one results in a 401 error. To find your credentials: in LeadSquared, click your account name or profile icon in the top-right corner → My Profile → API Settings (also sometimes found under Settings → CRM Settings → API Settings depending on your LeadSquared version). You will see your Access Key and Secret Key displayed. Copy both — they are long alphanumeric strings. LeadSquared has multiple regional API endpoints. The standard India endpoint is `api.leadsquared.com`. For US-hosted accounts, the endpoint is `api-us.leadsquared.com`. Check your account settings or LeadSquared documentation to confirm the correct endpoint for your account region. Using the wrong regional endpoint results in authentication failures even with correct credentials. Store both keys in your .env.local as LEADSQUARED_ACCESS_KEY and LEADSQUARED_SECRET_KEY. Also add LEADSQUARED_API_HOST (e.g., `api.leadsquared.com`) to make the regional endpoint configurable without changing code. These are server-side credentials — never add NEXT_PUBLIC_ prefix. Anyone with both keys can make full API calls to your LeadSquared account.

Bolt.new Prompt

Set up LeadSquared API integration. Create .env.local with LEADSQUARED_ACCESS_KEY=your-access-key, LEADSQUARED_SECRET_KEY=your-secret-key, LEADSQUARED_API_HOST=api.leadsquared.com. Create lib/leadsquared.ts with a base apiRequest function that accepts path (string), method ('GET'|'POST'), and body (optional object). The function builds the URL as https://{LEADSQUARED_API_HOST}/{path}, adds Content-Type and x-LSQ-AccessKey and x-LSQ-SecretKey headers. Add TypeScript interfaces for LeadSquaredLead (FirstName, LastName, EmailAddress, Phone, Source, ProspectStage, ProspectScore, mx_Custom_1 example custom field). Export createLead, getLeads, getLeadByEmail, and updateLead helper functions.

Paste this in Bolt.new chat

lib/leadsquared.ts
1// lib/leadsquared.ts
2export interface LeadSquaredLead {
3 ProspectID?: string;
4 FirstName: string;
5 LastName: string;
6 EmailAddress: string;
7 Phone?: string;
8 Mobile?: string;
9 Company?: string;
10 Source?: string;
11 Description?: string;
12 ProspectStage?: string;
13 ProspectScore?: number;
14 OwnerIdEmail?: string;
15 [key: string]: string | number | undefined;
16}
17
18export interface LeadSquaredActivity {
19 RelatedProspectId: string;
20 ActivityEvent: number; // 200-999 range for custom events, standard = 1-199
21 ActivityNote?: string;
22 ActivityDateTime?: string;
23}
24
25interface ApiOptions {
26 method?: 'GET' | 'POST';
27 body?: unknown;
28 queryParams?: Record<string, string | number>;
29}
30
31async function apiRequest<T>(path: string, options: ApiOptions = {}): Promise<T> {
32 const accessKey = process.env.LEADSQUARED_ACCESS_KEY;
33 const secretKey = process.env.LEADSQUARED_SECRET_KEY;
34 const apiHost = process.env.LEADSQUARED_API_HOST || 'api.leadsquared.com';
35
36 if (!accessKey || !secretKey) {
37 throw new Error('LeadSquared credentials not configured');
38 }
39
40 const url = new URL(`https://${apiHost}/${path}`);
41 if (options.queryParams) {
42 for (const [key, value] of Object.entries(options.queryParams)) {
43 url.searchParams.set(key, String(value));
44 }
45 }
46
47 const response = await fetch(url.toString(), {
48 method: options.method || 'GET',
49 headers: {
50 'Content-Type': 'application/json',
51 'x-LSQ-AccessKey': accessKey,
52 'x-LSQ-SecretKey': secretKey,
53 },
54 ...(options.body ? { body: JSON.stringify(options.body) } : {}),
55 });
56
57 const text = await response.text();
58 if (!response.ok) {
59 throw new Error(`LeadSquared API error ${response.status}: ${text}`);
60 }
61
62 if (!text) return null as T;
63
64 try {
65 return JSON.parse(text) as T;
66 } catch {
67 return text as unknown as T;
68 }
69}
70
71export async function createLead(leadData: Partial<LeadSquaredLead>): Promise<{ Message: string; ProspectID?: string }> {
72 return apiRequest('v2/LeadManagement.svc/Lead.Create', {
73 method: 'POST',
74 body: leadData,
75 });
76}
77
78export async function getLeads(
79 page = 1,
80 size = 50,
81 searchBy?: string
82): Promise<LeadSquaredLead[]> {
83 const params: Record<string, string | number> = { Page: page, Size: size };
84 if (searchBy) params.SearchText = searchBy;
85
86 const result = await apiRequest<{ ProspectList: LeadSquaredLead[] }>(
87 'v2/LeadManagement.svc/Leads.GetAll',
88 { queryParams: params }
89 );
90 return result?.ProspectList || [];
91}
92
93export async function getLeadByEmail(email: string): Promise<LeadSquaredLead | null> {
94 const leads = await apiRequest<LeadSquaredLead[]>(
95 'v2/LeadManagement.svc/Lead.GetByEmailAddress',
96 { queryParams: { emailaddress: email } }
97 );
98 return Array.isArray(leads) ? leads[0] : null;
99}
100
101export async function updateLead(
102 prospectId: string,
103 fields: Partial<LeadSquaredLead>
104): Promise<void> {
105 await apiRequest('v2/LeadManagement.svc/Lead.Update', {
106 method: 'POST',
107 body: { ProspectID: prospectId, ...fields },
108 });
109}

Pro tip: LeadSquared API paths use a service-based naming convention: v2/LeadManagement.svc/Lead.Create, v2/LeadManagement.svc/Lead.GetByEmailAddress, etc. The service name (LeadManagement.svc) and method name (Lead.Create) are case-sensitive. Check LeadSquared's API documentation for your version to confirm exact endpoint paths.

Expected result: A lib/leadsquared.ts helper with typed functions for lead management and authentication headers configured, ready for use in API routes.

2

Build the lead capture API route with source tracking

The lead capture API route creates a new lead in LeadSquared from a Bolt.new form submission. Source tracking is particularly important in LeadSquared integrations because the platform's lead scoring and distribution rules often depend on lead source — a lead from a pricing page might go to the enterprise sales team, while a lead from a help article goes to a success manager. LeadSquared's API for creating leads accepts a flat object with field names that must match LeadSquared's configured field names exactly. Standard fields use PascalCase: FirstName, LastName, EmailAddress, Phone, Mobile, Company, Source, Description. Custom fields added by your LeadSquared administrator have names starting with `mx_` followed by the custom field name (e.g., `mx_Course_Interested_In` for an education platform). The create-or-update pattern prevents duplicate lead records when the same email submits a form multiple times. Use `getLeadByEmail` to check for an existing record. If found, update the existing lead with any new information and log an activity. If not found, create a new lead. This is especially important in lead generation contexts where prospects submit multiple inquiry forms. For lead quality, consider adding a scoring hint at creation time. LeadSquared has automated scoring rules, but you can also pass initial quality signals: if the form asks for budget range or company size, these can be mapped to a custom field that feeds into LeadSquared's scoring formulas.

Bolt.new Prompt

Create a lead capture API route at app/api/leadsquared/capture/route.ts using lib/leadsquared.ts. Accept POST with: firstName (required), lastName (required), email (required, validate format), phone (optional), company (optional), source (optional, defaults to 'Web Form'), message (optional), customFields (optional Record<string,string>). Check for existing lead by email. If exists, update with new data. If new, create with LeadSquared field names (FirstName, LastName, EmailAddress, Phone, Company, Source, Description). Map customFields to mx_ prefixed keys. Return 201 for new leads, 200 for updates. Create an InquiryForm React component with name, email, phone, company, and message fields, plus Zod validation and success/error states.

Paste this in Bolt.new chat

app/api/leadsquared/capture/route.ts
1// app/api/leadsquared/capture/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { createLead, updateLead, getLeadByEmail } from '@/lib/leadsquared';
4
5const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
6
7export async function POST(request: NextRequest) {
8 const body = await request.json();
9 const { firstName, lastName, email, phone, company, source, message, customFields } = body;
10
11 if (!firstName?.trim()) return NextResponse.json({ error: 'First name required' }, { status: 400 });
12 if (!lastName?.trim()) return NextResponse.json({ error: 'Last name required' }, { status: 400 });
13 if (!email || !emailRegex.test(email)) {
14 return NextResponse.json({ error: 'Valid email required' }, { status: 400 });
15 }
16
17 const leadData: Record<string, string> = {
18 FirstName: firstName.trim(),
19 LastName: lastName.trim(),
20 EmailAddress: email.toLowerCase().trim(),
21 Source: source || 'Web Form',
22 };
23
24 if (phone) leadData.Phone = phone.trim();
25 if (company) leadData.Company = company.trim();
26 if (message) leadData.Description = message.trim();
27
28 // Map custom fields with mx_ prefix
29 if (customFields && typeof customFields === 'object') {
30 for (const [key, value] of Object.entries(customFields)) {
31 if (typeof value === 'string') {
32 leadData[`mx_${key}`] = value;
33 }
34 }
35 }
36
37 try {
38 const existing = await getLeadByEmail(email);
39
40 if (existing?.ProspectID) {
41 await updateLead(existing.ProspectID, leadData);
42 return NextResponse.json({ success: true, action: 'updated', prospectId: existing.ProspectID });
43 } else {
44 const result = await createLead(leadData);
45 return NextResponse.json({ success: true, action: 'created', prospectId: result?.ProspectID }, { status: 201 });
46 }
47 } catch (error) {
48 console.error('LeadSquared capture error:', error);
49 return NextResponse.json({ error: 'Failed to save lead' }, { status: 500 });
50 }
51}

Pro tip: Ask your LeadSquared administrator for the exact custom field names (mx_ prefixed) used in your account. Custom field names are set by the account administrator and vary across accounts — the custom field for 'Course of Interest' in one account might be mx_Course_Interest in another. You can also fetch all field definitions via LeadSquared's LeadManagement.svc/GetLeadFieldDefinitions endpoint.

Expected result: A lead capture API route that creates or updates LeadSquared leads from Bolt form submissions, with custom field support and source tracking.

3

Build a lead list and activity dashboard

A lead management dashboard lets sales teams view and act on their LeadSquared pipeline without leaving your Bolt.new app. This is valuable for teams that want a simplified view of their leads — filtered by their assignment, sorted by score, or focused on a specific lead stage — alongside other app data. LeadSquared's `Leads.GetAll` endpoint supports pagination via `Page` and `Size` parameters, and returns leads in descending order of creation date by default. For a dashboard, you typically want to display the most recent leads or highest-scoring leads first. The API also supports search via a `SearchText` parameter that searches across name, email, and phone. The activity log is one of LeadSquared's most distinctive features. Every interaction — call made, email sent, meeting held, form submitted — is recorded as an Activity linked to a lead's ProspectID. Fetching activity history with `ProspectActivity.GetByProspectId` gives you a timeline of every touchpoint for a specific lead. This is valuable for building a lead detail view that shows the complete engagement history. For the scoring visualization, LeadSquared stores a numeric `ProspectScore` on each lead that is updated by the platform's scoring engine as the lead takes actions and matches scoring criteria. Displaying this score alongside other lead data helps sales managers prioritize follow-up — a dashboard sorted by score with color-coded temperature indicators (hot/warm/cold) is one of the most frequently requested LeadSquared dashboard features.

Bolt.new Prompt

Create a lead management dashboard. Build two API routes: GET /api/leadsquared/leads that accepts page and size query params and calls getLeads from lib/leadsquared.ts, returning the list with pagination info, and GET /api/leadsquared/leads/:id/activities that fetches activity history for a specific lead from ProspectActivity.GetByProspectId. Create a LeadDashboard React component with: a search input that filters leads by name/email, a leads table with columns for name, email, company, source, score (color-coded badge), stage, and last activity date, and a drawer/modal showing full lead details and activity timeline when a row is clicked.

Paste this in Bolt.new chat

app/api/leadsquared/leads/route.ts
1// app/api/leadsquared/leads/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { getLeads } from '@/lib/leadsquared';
4
5export async function GET(request: NextRequest) {
6 const { searchParams } = new URL(request.url);
7 const page = parseInt(searchParams.get('page') || '1', 10);
8 const size = parseInt(searchParams.get('size') || '25', 10);
9 const search = searchParams.get('q') || undefined;
10
11 try {
12 const leads = await getLeads(page, Math.min(size, 100), search);
13 return NextResponse.json({ leads, page, size });
14 } catch (error) {
15 return NextResponse.json(
16 { error: (error as Error).message },
17 { status: 500 }
18 );
19 }
20}
21
22// app/api/leadsquared/leads/[id]/activities/route.ts
23// (create as a separate file)
24import { NextRequest, NextResponse } from 'next/server';
25
26async function getLeadActivities(prospectId: string) {
27 const accessKey = process.env.LEADSQUARED_ACCESS_KEY!;
28 const secretKey = process.env.LEADSQUARED_SECRET_KEY!;
29 const apiHost = process.env.LEADSQUARED_API_HOST || 'api.leadsquared.com';
30
31 const url = `https://${apiHost}/v2/ProspectActivity.svc/ProspectActivity.GetByProspectId?prospectId=${prospectId}&pageIndex=1&pageSize=20`;
32
33 const response = await fetch(url, {
34 headers: {
35 'x-LSQ-AccessKey': accessKey,
36 'x-LSQ-SecretKey': secretKey,
37 },
38 });
39
40 if (!response.ok) throw new Error(`LeadSquared API error: ${response.status}`);
41 return response.json();
42}
43
44export async function GET(
45 request: NextRequest,
46 { params }: { params: { id: string } }
47) {
48 try {
49 const activities = await getLeadActivities(params.id);
50 return NextResponse.json(activities);
51 } catch (error) {
52 return NextResponse.json(
53 { error: (error as Error).message },
54 { status: 500 }
55 );
56 }
57}

Pro tip: LeadSquared's ProspectScore ranges from 0-100. Define temperature thresholds appropriate for your account's scoring setup — the default hot/warm/cold split at 80/50/0 may not match how your LeadSquared scoring is configured. Check with your LeadSquared admin for the score thresholds that map to your sales team's terminology.

Expected result: A lead list API route with search and pagination, plus an activities API route, ready for a dashboard React component.

4

Deploy to Netlify and configure LeadSquared webhooks

LeadSquared API calls work in Bolt.new's WebContainer during development — the outbound HTTP requests to `api.leadsquared.com` with custom headers are supported in the browser-based runtime. You can test lead creation, fetching, and activity logging in the Bolt preview before deploying. Deployment to Netlify is required for production use and for any LeadSquared webhook features. LeadSquared can send webhook notifications to your app when specific lead events occur — lead stage changes, activity additions, quality score updates — through their Workflow Builder or API Webhooks settings. To deploy: click Deploy in Bolt.new, connect Netlify via OAuth, and wait for the build. In the Netlify dashboard → Site Configuration → Environment Variables, add: LEADSQUARED_ACCESS_KEY, LEADSQUARED_SECRET_KEY, and LEADSQUARED_API_HOST. Trigger a redeploy. For LeadSquared webhooks: the configuration depends on your LeadSquared version. In some versions, go to Settings → CRM Settings → Webhooks. In others, webhooks are configured within the Automation Workflow builder as a 'Call Webhook' action. Enter your Netlify URL as the webhook endpoint. LeadSquared typically sends form-encoded or JSON POST requests with lead and activity data. This is a fundamental WebContainer constraint — Bolt.new runs in a browser tab and cannot receive incoming HTTP requests. LeadSquared webhooks need a publicly accessible server endpoint, which only exists after deploying to Netlify or Bolt Cloud.

Bolt.new Prompt

Create a LeadSquared webhook handler at app/api/leadsquared/webhook/route.ts. Accept POST with application/json or application/x-www-form-urlencoded content type. Parse the payload to extract lead ProspectID, event type, and changed fields. Log the event. For stage change events, update a Supabase lead_sync table if it exists. Return 200 for all events. Add netlify.toml with Next.js build configuration and a comment that webhook delivery requires a deployed public URL.

Paste this in Bolt.new chat

app/api/leadsquared/webhook/route.ts
1// app/api/leadsquared/webhook/route.ts
2// NOTE: LeadSquared webhooks require a publicly accessible URL.
3// Deploy to Netlify first, then configure in LeadSquared Settings → Webhooks.
4import { NextRequest, NextResponse } from 'next/server';
5
6export async function POST(request: NextRequest) {
7 const contentType = request.headers.get('content-type') || '';
8
9 let payload: Record<string, unknown>;
10
11 try {
12 if (contentType.includes('application/x-www-form-urlencoded')) {
13 const text = await request.text();
14 const params = new URLSearchParams(text);
15 payload = Object.fromEntries(params.entries());
16 } else {
17 payload = await request.json();
18 }
19 } catch {
20 return NextResponse.json({ error: 'Invalid payload' }, { status: 400 });
21 }
22
23 const eventType = payload.event_type as string || payload.EventType as string || 'unknown';
24 const prospectId = payload.ProspectID as string || payload.prospect_id as string;
25 const email = payload.EmailAddress as string || payload.email as string;
26
27 console.log(`LeadSquared webhook: ${eventType}`, { prospectId, email });
28
29 switch (eventType) {
30 case 'LeadStageChanged':
31 case 'lead.stage_changed':
32 console.log(`Lead ${email} stage changed to: ${payload.ProspectStage || payload.new_stage}`);
33 // TODO: Update lead stage in Supabase if syncing lead data
34 break;
35
36 case 'ActivityAdded':
37 case 'lead.activity_added':
38 console.log(`Activity added for lead: ${email}`);
39 break;
40
41 case 'LeadCreated':
42 case 'lead.created':
43 console.log(`New LeadSquared lead created: ${email}`);
44 break;
45
46 default:
47 console.log(`Unhandled LeadSquared webhook: ${eventType}`);
48 }
49
50 return NextResponse.json({ received: true });
51}

Pro tip: LeadSquared's webhook payload format can vary between accounts and versions — some send JSON, some send form-encoded data. The webhook handler above handles both formats. If you are not sure which format your LeadSquared account uses, log the raw request body first and inspect the output after configuring the webhook.

Expected result: A deployed Netlify app with LeadSquared lead capture working in production and a webhook handler receiving lead event notifications.

Common use cases

Inquiry Form to LeadSquared CRM

Capture inquiries from a landing page form (education enrollment, financial product interest, service consultation request) and create a corresponding lead record in LeadSquared immediately. The lead enters the sales queue for the assigned team to follow up, with the source (which landing page) tracked in the lead record.

Bolt.new Prompt

Create an inquiry capture form that sends leads to LeadSquared. Build an API route at app/api/leadsquared/leads/route.ts using LEADSQUARED_ACCESS_KEY and LEADSQUARED_SECRET_KEY env vars. Accept POST with firstName, lastName, email, phone, source, and message. Map these to LeadSquared field names (FirstName, LastName, EmailAddress, Phone, Source, Description). POST to https://api.leadsquared.com/v2/LeadManagement.svc/Lead.Create with x-LSQ-AccessKey and x-LSQ-SecretKey headers. Create an InquiryForm React component with these fields plus validation and success/error handling.

Copy this prompt to try it in Bolt.new

Lead Activity Logging Dashboard

Build an internal tool that fetches a sales rep's assigned leads and logs call activities (call made, email sent, meeting booked) back to LeadSquared. Useful for teams that want to log activities from a custom interface without navigating the full LeadSquared CRM UI.

Bolt.new Prompt

Build a lead activity logger. Create API routes: GET /api/leadsquared/leads that fetches assigned leads using LeadSquared's Lead.GetAll API method with pagination, and POST /api/leadsquared/activity that accepts leadId, activityType ('Call' | 'Email' | 'Meeting'), and notes, then logs the activity using LeadSquared's ProspectActivity.Create endpoint. Create a LeadActivityDashboard React component with a searchable lead list on the left and an activity log form on the right, showing recent activities for the selected lead.

Copy this prompt to try it in Bolt.new

Lead Score Visualization

Display a visual lead scoring dashboard that shows leads sorted by their LeadSquared quality score, with color-coded indicators for score ranges. Helps sales managers quickly identify which leads are hottest and should be prioritized for follow-up.

Bolt.new Prompt

Create a lead scoring dashboard. Fetch leads from LeadSquared using GET /api/leadsquared/leads and include the ProspectScore field. Group leads into buckets: Hot (score 80-100), Warm (score 50-79), Cold (score 0-49). Create a LeadScoreDashboard React component showing three columns, one per temperature bucket, with lead cards showing name, company, score, and last activity date. Add a donut chart using Recharts showing the distribution across buckets. Refresh data every 5 minutes automatically.

Copy this prompt to try it in Bolt.new

Troubleshooting

LeadSquared API returns 401 with 'Incorrect Keys' message

Cause: Either the x-LSQ-AccessKey or x-LSQ-SecretKey header is missing, contains the wrong value, or the API host URL is for the wrong region. LeadSquared accounts in different regions (India vs US) use different API host domains.

Solution: Verify both LEADSQUARED_ACCESS_KEY and LEADSQUARED_SECRET_KEY in your .env.local match exactly what is shown in LeadSquared under My Profile → API Settings. Check that LEADSQUARED_API_HOST is set to the correct regional endpoint — api.leadsquared.com for India, api-us.leadsquared.com for US accounts. Both headers must be present in every request.

typescript
1headers: {
2 'Content-Type': 'application/json',
3 'x-LSQ-AccessKey': process.env.LEADSQUARED_ACCESS_KEY!,
4 'x-LSQ-SecretKey': process.env.LEADSQUARED_SECRET_KEY!,
5}

Lead creation returns success but lead does not appear in LeadSquared

Cause: LeadSquared has lead deduplication rules and stage filters. New leads may be automatically deduplicated (merged with an existing record with the same email) or placed in a stage that is not visible in your default pipeline view.

Solution: In LeadSquared, go to All Leads (not just the current pipeline view) and search by email address to find the created record. Check your LeadSquared deduplication settings under Settings → Duplicate Management. If the API returns a ProspectID in the response, use that ID to fetch the lead directly via Lead.GetById to confirm it exists.

Custom field values are not saving when creating leads

Cause: Custom field names must exactly match the LeadSquared field system names (starting with mx_), and the field must exist in your LeadSquared account configuration. Sending a field name that does not exist in LeadSquared is silently ignored.

Solution: Check your LeadSquared account's custom fields in Settings → Custom Fields (or Settings → Lead Fields depending on your version). The API field name is the 'Schema Name' shown in that settings page — it begins with mx_ followed by the field identifier. If the field does not appear in Settings, it needs to be created by your LeadSquared administrator before it can receive data via API.

LeadSquared webhooks are not firing during Bolt.new development

Cause: LeadSquared sends webhook POST requests to a publicly accessible URL. Bolt.new's WebContainer runs in a browser tab and cannot receive incoming HTTP connections. The preview URL is not a stable public endpoint.

Solution: Deploy your app to Netlify and configure the webhook in LeadSquared using your Netlify URL. This is a fundamental WebContainer limitation. Alternatively, for testing purposes, you can use a tool like ngrok to temporarily expose a local port — but the recommended approach is to deploy to Netlify early and test with the deployed URL.

Best practices

  • Always send both x-LSQ-AccessKey and x-LSQ-SecretKey headers in every LeadSquared API request — either missing results in a 401 error regardless of the other credential being correct
  • Store the API host as LEADSQUARED_API_HOST environment variable rather than hardcoding the URL — LeadSquared has regional endpoints and the correct host varies by account
  • Verify custom field system names (mx_FieldName format) against your LeadSquared account settings before writing code — sending incorrect field names is silently ignored, not an error
  • Implement the create-or-update pattern for lead capture to prevent duplicates — always check for an existing lead by email before creating a new one
  • Log the raw API response during development to understand the exact response structure from your LeadSquared account version — field names and response formats can vary between LeadSquared versions
  • Add source tracking to every lead capture call — LeadSquared's routing and scoring rules often depend on lead source, and this data is harder to reconstruct after the fact
  • Test LeadSquared API calls in the Bolt.new WebContainer preview before deploying — outbound API calls with custom headers work in the preview
  • Deploy to Netlify before configuring LeadSquared webhooks — webhooks require a publicly accessible URL that the WebContainer cannot provide

Alternatives

Frequently asked questions

Can LeadSquared API calls work in Bolt.new's WebContainer during development?

Yes. LeadSquared API calls are standard outbound HTTP requests with custom headers — these work in Bolt's WebContainer preview. You can build and test lead creation, fetching, and activity logging in the Bolt preview. The only feature requiring deployment is LeadSquared webhook delivery, which needs a publicly accessible URL to send POST requests to your endpoint.

Why does LeadSquared use x-LSQ- headers instead of standard Bearer token authentication?

LeadSquared's API predates widespread adoption of OAuth and Bearer token authentication standards. Their custom header scheme (x-LSQ-AccessKey and x-LSQ-SecretKey) is functionally equivalent to API key authentication — it identifies your account and authenticates the request. Both headers must appear in every API call. The authentication is HTTP header-based, so it works the same way from any HTTP client.

What regions does LeadSquared's API support and how do I know which endpoint to use?

LeadSquared operates regional data centers with separate API endpoints. The India endpoint is api.leadsquared.com and the US endpoint is api-us.leadsquared.com. Your account region is determined during account setup. Check your LeadSquared dashboard URL — if it is app.leadsquared.com, use api.leadsquared.com. If the URL contains 'us', use the US endpoint. You can also check Settings → API Settings where the base API URL is sometimes displayed.

How do I find the correct field names for LeadSquared custom fields?

In LeadSquared, go to Settings → Custom Fields (or Settings → Lead Fields). Each field shows its 'Schema Name' or 'API Name', which is the field name to use in API calls — it starts with mx_ followed by the field identifier. Alternatively, fetch an existing lead record via the API and inspect the JSON response to see all field names with their current values for your account.

Is LeadSquared suitable for non-Indian or Southeast Asian markets?

Yes, though LeadSquared's design prioritizes high-velocity sales scenarios common in Indian and Southeast Asian markets (education admissions, financial services, healthcare). Global companies in industries with similar sales patterns — field sales teams, high lead volume, mobile-first sales reps — also use LeadSquared successfully. The platform is available in multiple languages and currencies for global deployments.

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.