Skip to main content
RapidDev - Software Development Agency
v0-integrationsNext.js API Route

How to Integrate Insightly with V0

To integrate Insightly with V0 by Vercel, create a Next.js API route at app/api/insightly/route.ts that calls the Insightly REST API using a Base64-encoded API key in the Authorization header. V0 generates custom CRM dashboards showing contacts, opportunities, and projects fetched from your API route. Insightly's SMB-friendly CRM is ideal for small businesses wanting a custom branded sales dashboard.

What you'll learn

  • How to find your Insightly API key and configure Basic Auth for the Insightly REST API
  • How to create a Next.js API route that fetches contacts, opportunities, and pipeline stages
  • How to prompt V0 to generate a custom sales pipeline and contact directory dashboard
  • How to filter and search Insightly records by status, owner, and custom fields
  • How to display opportunity values and pipeline stage progression in your V0 app
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read25 minutesMarketingApril 2026RapidDev Engineering Team
TL;DR

To integrate Insightly with V0 by Vercel, create a Next.js API route at app/api/insightly/route.ts that calls the Insightly REST API using a Base64-encoded API key in the Authorization header. V0 generates custom CRM dashboards showing contacts, opportunities, and projects fetched from your API route. Insightly's SMB-friendly CRM is ideal for small businesses wanting a custom branded sales dashboard.

Building Custom Insightly CRM Dashboards with V0

Insightly is popular with small and mid-size businesses because it combines CRM functionality with lightweight project management — contacts become clients, opportunities become projects, all within one platform. The built-in Insightly interface works well for data entry and day-to-day work, but many businesses want custom dashboards that surface the metrics that matter most to them: pipeline value by stage, top opportunities by close date, or contact activity summaries.

The integration creates a Next.js API route that authenticates with Insightly using your API key encoded in Basic Auth format. V0 generates the front-end components — pipeline kanban boards, contact directories, opportunity tables, or executive summaries — that fetch data from the secure API route. Your Insightly API key never reaches the browser, which is important because it grants full read and write access to your CRM data.

Insightly's API uses a slightly unusual authentication pattern: rather than a Bearer token, it uses HTTP Basic Auth where the API key is the username and the password is empty. The key must be Base64 encoded before adding to the Authorization header. This is a one-time setup in your API route and does not require any additional npm packages.

Integration method

Next.js API Route

V0 generates custom CRM dashboard components that display Insightly contacts, opportunities, and pipeline data. A Next.js API route on Vercel proxies requests to the Insightly REST API, keeping your API key server-side. Components call /api/insightly/contacts rather than Insightly directly, preventing credential exposure and enabling CORS-free data access.

Prerequisites

  • A V0 account with a Next.js project at v0.dev
  • An Insightly account at insightly.com with contacts and opportunities
  • An Insightly API key from your Insightly user settings
  • Basic understanding of Base64 encoding (your API route handles this automatically)
  • A Vercel account with your V0 project connected via GitHub

Step-by-step guide

1

Find Your Insightly API Key

Insightly's API key is found in your user profile settings. It is a unique key tied to your user account and grants the same access permissions as your Insightly user role. Log into your Insightly account at app.insightly.com. Click on your profile avatar or name in the top-right corner of the interface. Select 'User Settings' from the dropdown menu. In your User Settings page, scroll down to find the 'API Key' section. Your API key is displayed there as a long alphanumeric string. Click the copy icon or select the key text and copy it. Insightly uses HTTP Basic Authentication with the API key as the username and an empty string as the password. Before using the key in your API route, you need to Base64-encode the string 'YOUR_API_KEY:' (with the colon but without quotes, and with an empty string after the colon). The resulting Base64 string is what goes in the Authorization header as 'Basic {base64string}'. You can test your credentials quickly using curl: curl -H 'Authorization: Basic {base64}' https://api.insightly.com/v3.1/contacts. If it returns a JSON array, your authentication is working. Insightly's API base URL depends on your account's data region. North American accounts use https://api.insightly.com. European accounts may use a different subdomain. Check your account region in Insightly's documentation or contact Insightly support if standard API calls return 404. Note that Insightly API access is included on all paid plans. Free plan accounts may have limited or no API access.

Pro tip: To Base64-encode your Insightly API key in Node.js (which your API route uses), run: Buffer.from('YOUR_API_KEY:').toString('base64'). Store the raw API key in the environment variable and do the encoding in your route code.

Expected result: You have your Insightly API key (a long alphanumeric string). You understand the Basic Auth pattern and are ready to add the key to Vercel environment variables.

2

Add Insightly API Key to Vercel

Store your Insightly API key in Vercel's environment variables. Your API route will Base64-encode it at runtime, so you store the raw key value rather than the encoded string. Open your Vercel Dashboard, navigate to your project, click 'Settings', and select 'Environment Variables'. Add: INSIGHTLY_API_KEY: Your raw Insightly API key. This is a secret — set it for Production, Preview, and Development environments. Do not add a NEXT_PUBLIC_ prefix. Save the variable and trigger a redeployment. For local development, add the same variable to your .env.local file. Optionally, if your account uses the European data region, also add INSIGHTLY_API_BASE_URL=https://api.na1.insightly.com or the appropriate regional URL for your account.

.env.local
1# .env.local local development only, excluded from Git
2INSIGHTLY_API_KEY=your_insightly_api_key_here
3# Optional: if your account uses EU region
4# INSIGHTLY_API_BASE_URL=https://api.eu1.insightly.com

Pro tip: Insightly API keys are permanent and do not expire. If you suspect your key has been compromised, generate a new one from User Settings → API Key section and update your Vercel environment variable immediately.

Expected result: Vercel Dashboard shows INSIGHTLY_API_KEY saved as an environment variable across all deployment environments.

3

Create the Insightly API Routes

Create Next.js API routes for contacts and opportunities. The key detail for Insightly is the Basic Auth header format — your route must Base64-encode the API key with a trailing colon before sending it. Create app/api/insightly/contacts/route.ts. The contacts endpoint is GET https://api.insightly.com/v3.1/contacts. It supports query parameters including top (page size, max 500), skip (for pagination), and $filter (OData filter expression) and $orderby for sorting. Insightly returns contacts with nested arrays for email addresses and phone numbers (EMAIL_ADDRESSES array containing objects with EMAIL_ADDRESS and EMAIL_TYPE, and PHONE_NUMBERS array containing objects with PHONE_NUMBER and PHONE_TYPE). Your route should flatten these for easier component consumption. The opportunities endpoint is GET https://api.insightly.com/v3.1/opportunities with similar pagination support. Filter by STATE='open' using OData syntax: $filter=STATE eq 'open'. Each opportunity includes OPPORTUNITY_VALUE, PROBABILITY, CLOSE_DATE, STAGE_ORDER_NUMBER, and PIPELINE_ID along with basic metadata. Insightly also has a pipeline stages endpoint (GET /v3.1/OpportunityCategories) and a pipelines endpoint (GET /v3.1/Pipelines) to get the stages within each pipeline. Fetch these once to map stage order numbers to human-readable stage names.

V0 Prompt

Create a Next.js API route at app/api/insightly/contacts/route.ts. Use INSIGHTLY_API_KEY from environment variables. Create the Basic Auth header by Base64-encoding '{key}:' (key + colon). Fetch from https://api.insightly.com/v3.1/contacts with top=200. Return contacts with CONTACT_ID, FIRST_NAME, LAST_NAME, ORGANISATION_NAME, TITLE, primary email from EMAIL_ADDRESSES array, primary phone from PHONE_NUMBERS array, and DATE_UPDATED_UTC. Sort by LAST_NAME. Handle errors.

Paste this in V0 chat

app/api/insightly/contacts/route.ts
1import { NextRequest, NextResponse } from 'next/server';
2
3interface InsightlyEmailAddress {
4 EMAIL_ADDRESS: string;
5 EMAIL_TYPE: string;
6}
7
8interface InsightlyPhoneNumber {
9 PHONE_NUMBER: string;
10 PHONE_TYPE: string;
11}
12
13interface InsightlyContact {
14 CONTACT_ID: number;
15 FIRST_NAME: string;
16 LAST_NAME: string;
17 ORGANISATION_NAME: string | null;
18 TITLE: string | null;
19 EMAIL_ADDRESSES: InsightlyEmailAddress[];
20 PHONE_NUMBERS: InsightlyPhoneNumber[];
21 DATE_UPDATED_UTC: string;
22}
23
24function getInsightlyAuthHeader(apiKey: string): string {
25 // Insightly Basic Auth: Base64-encode 'apiKey:' (key + colon, empty password)
26 return 'Basic ' + Buffer.from(`${apiKey}:`).toString('base64');
27}
28
29export async function GET(request: NextRequest) {
30 const apiKey = process.env.INSIGHTLY_API_KEY;
31 const apiBase =
32 process.env.INSIGHTLY_API_BASE_URL || 'https://api.insightly.com';
33
34 if (!apiKey) {
35 return NextResponse.json(
36 { error: 'Insightly configuration missing' },
37 { status: 500 }
38 );
39 }
40
41 const { searchParams } = new URL(request.url);
42 const search = searchParams.get('search') || '';
43
44 const contactsUrl = new URL(`${apiBase}/v3.1/contacts`);
45 contactsUrl.searchParams.set('top', '200');
46 contactsUrl.searchParams.set('$orderby', 'LAST_NAME asc');
47 if (search) {
48 contactsUrl.searchParams.set(
49 '$filter',
50 `LAST_NAME eq '${search}' or FIRST_NAME eq '${search}'`
51 );
52 }
53
54 try {
55 const response = await fetch(contactsUrl.toString(), {
56 headers: {
57 Authorization: getInsightlyAuthHeader(apiKey),
58 'Content-Type': 'application/json',
59 },
60 next: { revalidate: 120 },
61 });
62
63 if (!response.ok) {
64 const error = await response.text();
65 console.error('Insightly API error:', error);
66 return NextResponse.json(
67 { error: `Insightly returned ${response.status}` },
68 { status: response.status }
69 );
70 }
71
72 const contacts: InsightlyContact[] = await response.json();
73
74 const transformed = contacts.map((c) => ({
75 id: c.CONTACT_ID,
76 firstName: c.FIRST_NAME || '',
77 lastName: c.LAST_NAME || '',
78 fullName: `${c.FIRST_NAME || ''} ${c.LAST_NAME || ''}`.trim(),
79 company: c.ORGANISATION_NAME || '',
80 title: c.TITLE || '',
81 email:
82 c.EMAIL_ADDRESSES?.find((e) => e.EMAIL_TYPE === 'WORK')?.EMAIL_ADDRESS ||
83 c.EMAIL_ADDRESSES?.[0]?.EMAIL_ADDRESS ||
84 '',
85 phone:
86 c.PHONE_NUMBERS?.find((p) => p.PHONE_TYPE === 'WORK')?.PHONE_NUMBER ||
87 c.PHONE_NUMBERS?.[0]?.PHONE_NUMBER ||
88 '',
89 updatedAt: c.DATE_UPDATED_UTC,
90 }));
91
92 return NextResponse.json({ contacts: transformed, total: transformed.length });
93 } catch (error) {
94 console.error('Insightly contacts fetch failed:', error);
95 return NextResponse.json(
96 { error: 'Failed to fetch contacts' },
97 { status: 500 }
98 );
99 }
100}

Pro tip: The Insightly Basic Auth requires the format 'apiKey:' (with trailing colon and empty password). Forgetting the colon will cause authentication failures even with a valid API key.

Expected result: Calling /api/insightly/contacts returns a JSON array of contacts with flattened email and phone fields, sorted alphabetically by last name.

4

Generate CRM Dashboard Components with V0

With the Insightly API routes returning data, prompt V0 to generate the CRM dashboard components. Sales dashboards need clear visual hierarchy — pipeline value should be prominent, stage groupings should be obvious, and overdue or high-priority items should stand out. First, review the JSON output of your /api/insightly/contacts and /api/insightly/opportunities routes to confirm the field names and data structure. Reference these exact field names in your V0 prompts. For a pipeline dashboard, describe the column layout (one column per pipeline stage), the card content (opportunity name, value, expected close date, owner), and the color coding scheme (green for on-track, yellow for closing soon, red for overdue). Tell V0 the stage names used in your Insightly pipeline. For a contact directory, describe the table columns, sort behavior, and search functionality. Ask V0 to add pagination if your contact list exceeds 50-100 entries, since rendering hundreds of rows at once slows the browser. Ask V0 to add summary metric cards at the top of the dashboard: total pipeline value, number of open opportunities, opportunities closing this month, and win rate. These high-level numbers are usually what executives and managers look at first.

V0 Prompt

Create a CRM dashboard with two tabs: 'Pipeline' and 'Contacts'. Pipeline tab: fetch from /api/insightly/opportunities. Show summary cards: total pipeline value (sum of all OPPORTUNITY_VALUE), open count, and opportunities closing within 30 days. Below, show a table with columns: Opportunity Name, Value ($XX,XXX), Owner, Stage, Close Date, Status badge (green 'On Track' if close date > today, red 'Overdue' if past). Contacts tab: fetch from /api/insightly/contacts. Show a searchable table with Name, Company, Title, Email, and Phone. Search filters both name and company client-side.

Paste this in V0 chat

Pro tip: Insightly opportunity values are stored as plain numbers without currency formatting. Format them as '$XX,XXX' using Intl.NumberFormat in your React component rather than in the API route.

Expected result: V0 generates a CRM dashboard with a pipeline table showing opportunity values and stages, and a contact directory with search. Summary metric cards display total pipeline value and opportunity counts.

5

Add an Opportunities API Route

Create the opportunities API route to complete the CRM dashboard. Opportunities in Insightly represent deals in your sales pipeline, each with a value, close date, stage, and probability. Create app/api/insightly/opportunities/route.ts. The opportunities endpoint is GET https://api.insightly.com/v3.1/opportunities. Useful query parameters include $filter=STATE eq 'open' to show only open deals, $top for page size, and $orderby=CLOSE_DATE asc for sorting by close date. Each Insightly opportunity includes OPPORTUNITY_ID, OPPORTUNITY_NAME, OPPORTUNITY_VALUE, OPPORTUNITY_STATE (open/won/lost), CLOSE_DATE, PROBABILITY, RESPONSIBLE_USER_ID, and PIPELINE_ID. The STAGE_ORDER_NUMBER field indicates the position within the pipeline (0 = first stage, higher numbers = later stages). For a complete pipeline view, you also want the stage name rather than just the order number. Fetch pipeline stages from GET /v3.1/Pipelines/{pipelineId}/Stages to get a mapping of stage order numbers to stage names. You can either cache this mapping in your API route or fetch it on each request since pipeline structures rarely change. For agencies and sales teams who want to build more complex Insightly integrations — such as syncing opportunity wins to trigger onboarding workflows, automatically creating Insightly contacts from form submissions, or building a two-way sync with another CRM — RapidDev can help design the full integration architecture.

V0 Prompt

Create a Next.js API route at app/api/insightly/opportunities/route.ts that fetches open opportunities from Insightly. Use INSIGHTLY_API_KEY with Basic Auth (Base64-encoded 'key:'). Fetch from https://api.insightly.com/v3.1/opportunities with filter STATE eq 'open'. Return opportunities with id, name, value, closeDate (ISO string), probability, ownerName, stageOrder, and state. Sort by closeDate ascending. Handle errors.

Paste this in V0 chat

app/api/insightly/opportunities/route.ts
1import { NextResponse } from 'next/server';
2
3interface InsightlyOpportunity {
4 OPPORTUNITY_ID: number;
5 OPPORTUNITY_NAME: string;
6 OPPORTUNITY_VALUE: number | null;
7 OPPORTUNITY_STATE: string;
8 CLOSE_DATE: string | null;
9 PROBABILITY: number | null;
10 RESPONSIBLE_USER_ID: number | null;
11 STAGE_ORDER_NUMBER: number;
12 PIPELINE_ID: number | null;
13 OWNER_USER_ID: number;
14 RESPONSIBLE_USER_NAME?: string;
15}
16
17export async function GET() {
18 const apiKey = process.env.INSIGHTLY_API_KEY;
19 const apiBase =
20 process.env.INSIGHTLY_API_BASE_URL || 'https://api.insightly.com';
21
22 if (!apiKey) {
23 return NextResponse.json(
24 { error: 'Insightly configuration missing' },
25 { status: 500 }
26 );
27 }
28
29 const authHeader =
30 'Basic ' + Buffer.from(`${apiKey}:`).toString('base64');
31
32 const oppsUrl = new URL(`${apiBase}/v3.1/opportunities`);
33 oppsUrl.searchParams.set('$filter', "OPPORTUNITY_STATE eq 'Open'");
34 oppsUrl.searchParams.set('$top', '200');
35 oppsUrl.searchParams.set('$orderby', 'CLOSE_DATE asc');
36
37 try {
38 const response = await fetch(oppsUrl.toString(), {
39 headers: {
40 Authorization: authHeader,
41 'Content-Type': 'application/json',
42 },
43 next: { revalidate: 120 },
44 });
45
46 if (!response.ok) {
47 const error = await response.text();
48 console.error('Insightly opportunities error:', error);
49 return NextResponse.json(
50 { error: `Insightly returned ${response.status}` },
51 { status: response.status }
52 );
53 }
54
55 const opportunities: InsightlyOpportunity[] = await response.json();
56
57 const transformed = opportunities.map((o) => ({
58 id: o.OPPORTUNITY_ID,
59 name: o.OPPORTUNITY_NAME,
60 value: o.OPPORTUNITY_VALUE ?? 0,
61 state: o.OPPORTUNITY_STATE.toLowerCase(),
62 closeDate: o.CLOSE_DATE,
63 isOverdue: o.CLOSE_DATE
64 ? new Date(o.CLOSE_DATE) < new Date()
65 : false,
66 probability: o.PROBABILITY ?? 0,
67 stageOrder: o.STAGE_ORDER_NUMBER,
68 pipelineId: o.PIPELINE_ID,
69 }));
70
71 const totalValue = transformed.reduce((sum, o) => sum + o.value, 0);
72
73 return NextResponse.json({
74 opportunities: transformed,
75 total: transformed.length,
76 totalValue,
77 });
78 } catch (error) {
79 console.error('Insightly opportunities fetch failed:', error);
80 return NextResponse.json(
81 { error: 'Failed to fetch opportunities' },
82 { status: 500 }
83 );
84 }
85}

Pro tip: Insightly filter values for STATE are case-sensitive — use 'Open' (capital O) not 'open'. Check the Insightly API documentation for your version to confirm exact enum values.

Expected result: Calling /api/insightly/opportunities returns open opportunities with values, close dates, and isOverdue flags. The totalValue field sums the entire pipeline value for display in summary cards.

Common use cases

Custom Sales Pipeline Dashboard

A startup's sales team wants a custom dashboard showing all active opportunities organized by pipeline stage, with color-coded deal values and expected close dates. V0 generates a kanban-style pipeline board that fetches opportunities from Insightly and groups them by opportunity state (pipeline stage).

V0 Prompt

Build a sales pipeline board that fetches opportunities from /api/insightly/opportunities. The response has opportunities array with OPPORTUNITY_NAME, OPPORTUNITY_VALUE (number), CLOSE_DATE (ISO string), STAGE_ORDER_NUMBER (0-10), RESPONSIBLE_USER_NAME, and STATE ('open', 'won', 'lost'). Display as columns by stage: Prospecting, Qualification, Proposal, Negotiation, Closed Won. Each card shows opportunity name, value formatted as '$XX,XXX', responsible user name, and close date formatted as 'Mar 31'. Won deals show a green badge, overdue close dates (past) show a red date. Only show open opportunities by default.

Copy this prompt to try it in V0

Contact Directory with Search

A business development team wants a searchable contact directory showing all Insightly contacts with their company, title, email, and relationship tags. V0 generates a contact directory page with alphabetical sorting, search by name or company, and a detail drawer that shows full contact information.

V0 Prompt

Create a contact directory that fetches from /api/insightly/contacts. Each contact has FIRST_NAME, LAST_NAME, ORGANISATION_NAME, TITLE, EMAIL_ADDRESS (from EMAIL_ADDRESSES array, first item), PHONE_NUMBER (from PHONE_NUMBERS array, first item). Display as a sortable table with columns: Name (linked to detail), Company, Title, Email, Phone. Add a search input filtering by name or company client-side. Show 'No contacts found' for empty results. Sort alphabetically by LAST_NAME by default.

Copy this prompt to try it in V0

Weekly Opportunities Report

A sales manager wants an automated weekly report email that summarizes newly created opportunities, opportunities closing this week, and recently won deals. V0 generates a report preview page with these three sections that can be screenshotted or printed for weekly team meetings.

V0 Prompt

Build a weekly opportunities report with three sections: 'New This Week' (created in the last 7 days), 'Closing This Week' (CLOSE_DATE within next 7 days), and 'Recently Won' (STATE=won, updated in last 7 days). Each section fetches from /api/insightly/opportunities with appropriate filters. Show each opportunity as a row with name, value ($XX,XXX), owner, and date. Show section totals. Add a print button.

Copy this prompt to try it in V0

Troubleshooting

API returns 401 Unauthorized

Cause: Insightly uses Basic Auth with the API key as username and an empty password. A common mistake is encoding 'key' without the trailing colon, or using Bearer token format instead of Basic auth.

Solution: Ensure your Base64 encoding includes the trailing colon: Buffer.from('YOUR_API_KEY:').toString('base64'). The colon separates the username (API key) from the password (empty string) in HTTP Basic Auth. Also verify INSIGHTLY_API_KEY is correctly set in Vercel and that you redeployed after saving it.

typescript
1// Correct Insightly Basic Auth encoding
2const authHeader = 'Basic ' + Buffer.from(`${process.env.INSIGHTLY_API_KEY}:`).toString('base64');
3// Note the colon after the key — empty password

API returns 404 for all endpoints

Cause: Insightly has regional API endpoints. North American accounts use api.insightly.com, but European accounts use a different regional URL. Using the wrong regional endpoint returns 404 even with correct credentials.

Solution: Check your Insightly account's data region in Settings → Account → Data Region. If your account is in the EU region, set INSIGHTLY_API_BASE_URL to the correct regional endpoint (e.g., https://api.eu1.insightly.com) and use this env var as your API base URL.

typescript
1const apiBase = process.env.INSIGHTLY_API_BASE_URL || 'https://api.insightly.com';
2// Set INSIGHTLY_API_BASE_URL=https://api.eu1.insightly.com for EU accounts

OData filter returns 400 Bad Request

Cause: Insightly OData filters use specific syntax rules. String values must be wrapped in single quotes, not double quotes. Using spaces around eq without the correct OData format also causes parse errors.

Solution: Use single quotes around string filter values: $filter=OPPORTUNITY_STATE eq 'Open'. Verify the exact field name (uppercase) and value (case-sensitive string like 'Open' not 'open'). Test filters using the Insightly API Explorer in their developer documentation before adding to your route.

typescript
1// Correct OData filter syntax for Insightly
2oppsUrl.searchParams.set('$filter', "OPPORTUNITY_STATE eq 'Open'");
3// Wrong: $filter=state eq 'open'
4// Wrong: $filter=OPPORTUNITY_STATE eq "Open"

Best practices

  • Base64-encode the API key at runtime in your API route rather than storing the encoded string in environment variables — store the raw key and encode it in code.
  • Set your Insightly API base URL in an environment variable (INSIGHTLY_API_BASE_URL) to support regional endpoints without changing code.
  • Use OData $filter parameters to limit results server-side (e.g., open opportunities only) rather than fetching all records and filtering in JavaScript — this reduces payload size significantly for large CRMs.
  • Cache contact and opportunity lists for 2 minutes (next: { revalidate: 120 }) since CRM data changes frequently enough that longer caching could show stale pipeline data.
  • Flatten nested contact fields (EMAIL_ADDRESSES and PHONE_NUMBERS arrays) in your API route to make V0 components simpler — return primary email and phone as direct string fields.
  • Always include null checks for OPPORTUNITY_VALUE and CLOSE_DATE — Insightly allows creating opportunities without these fields, and null values cause JavaScript calculation errors.
  • For client portals showing only one company's data, filter contacts by ORGANISATION_ID rather than returning all contacts and filtering client-side to minimize data transfer.

Alternatives

Frequently asked questions

Does Insightly's API work on the free plan?

Insightly's free plan (up to 2 users) includes limited API access. Paid plans (Plus, Professional, Enterprise) include full API access with higher rate limits. If you are on the free plan and experiencing API errors, upgrading to a paid plan should resolve access restrictions.

Can I create contacts and opportunities via the Insightly API?

Yes. Use POST https://api.insightly.com/v3.1/contacts with a JSON body to create contacts, and POST /v3.1/opportunities to create opportunities. The same Basic Auth header applies. This enables form-to-CRM workflows where V0 contact forms create Insightly records automatically.

How do I get a list of my pipeline stages for the kanban board?

Fetch pipelines with GET /v3.1/Pipelines to get your pipeline IDs and names. Then fetch stages for a specific pipeline with GET /v3.1/Pipelines/{pipelineId}/Stages. Each stage has STAGE_ID, STAGE_NAME, and STAGE_ORDER. Map the STAGE_ORDER_NUMBER from opportunities to these stage names for your kanban column labels.

What is the Insightly API rate limit?

Insightly's API rate limit varies by plan. The Plus plan allows 10 requests per second, Professional allows higher limits, and Enterprise has the highest limits. For a dashboard accessed by a few users at a time, these limits are rarely hit with Next.js fetch caching (next: { revalidate: 120 }) reducing the frequency of API calls.

Can I use Insightly webhooks to push real-time updates to my V0 app?

Insightly supports webhooks for events like contact creation, opportunity stage changes, and task completion. Create a POST handler at app/api/insightly/webhook/route.ts on your Vercel deployment. In Insightly Settings → Webhooks, add your deployed URL as the webhook endpoint. The webhook can trigger cache invalidation or database updates to keep your dashboard current.

How do I display contact custom fields from Insightly?

Insightly contacts have a CUSTOMFIELDS array in the API response, where each item has FIELD_NAME and FIELD_VALUE. Include these in your API route response by mapping the CUSTOMFIELDS array. Custom field names match what you defined in your Insightly account settings under System Settings → Custom Fields.

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.