# How to Integrate Retool with Pipedrive

- Tool: Retool
- Difficulty: Beginner
- Time required: 20 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Pipedrive by creating a REST API Resource with Pipedrive's API token authentication. Query deals, persons, organizations, and activities to build a visual sales pipeline dashboard with stage management, deal velocity tracking, and activity monitoring — giving your sales team a customized CRM operations panel beyond what Pipedrive's native views provide.

## Build a Pipedrive Sales Pipeline Dashboard in Retool

Pipedrive's native UI is excellent for individual sales reps managing their own deals, but sales managers and operations teams regularly need views that Pipedrive's built-in reports don't provide: cross-pipeline deal velocity, activity completion rates by rep, deals stalled in specific stages beyond their expected cycle time, and combined views of multiple pipelines. These operational insights typically require exporting data or building complex Pipedrive filters that don't save well between sessions.

Retool gives your sales ops team a configurable dashboard with direct Pipedrive API access. You can build a pipeline overview that shows all deals across stages with their value, age, and assigned owner in a single sortable Table, add action buttons to move deals between stages or log activities without leaving the dashboard, and create Charts that show pipeline health metrics like stage conversion rates and average deal age.

Pipedrive's API uses simple token-based authentication with a personal API token appended to every request as a query parameter. This makes it one of the fastest integrations to set up in Retool — no OAuth flow required. Retool's server-side proxy ensures the token never reaches the browser.

## Before you start

- A Pipedrive account with API access (available on all Pipedrive plans)
- A Pipedrive personal API token (Settings → Personal preferences → API → Your personal API token)
- A Retool account with permission to create Resources
- Familiarity with Retool's query editor and Table component
- Optional: knowledge of your Pipedrive pipeline IDs and stage IDs for filtering queries

## Step-by-step guide

### 1. Retrieve your Pipedrive API token and configure the Resource

Start by locating your Pipedrive personal API token. Log in to your Pipedrive account and navigate to Settings (your profile icon in the top right) → Personal preferences → API. Your personal API token is displayed on this page — copy it.

Before creating the resource, store your API token securely in Retool. Go to your Retool instance's Settings tab (in the left sidebar) → Configuration Variables → Create Variable. Name it PIPEDRIVE_API_TOKEN and mark it as Secret. Paste your API token as the value and save.

Now navigate to the Resources tab in Retool and click Add Resource. Select REST API from the resource type list. Name the resource 'Pipedrive API'. In the Base URL field, enter https://api.pipedrive.com. This is the base URL for Pipedrive's v1 API — you'll add /v1/ to each query path.

Pipedrive authenticates via an API token passed as a query parameter named api_token. In the Default URL Parameters section, add: Key = api_token, Value = {{ retoolContext.configVars.PIPEDRIVE_API_TOKEN }}.

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

Click Save Changes. Test the resource by creating a quick query with path /v1/pipelines — you should receive a list of your Pipedrive pipelines.

**Expected result:** The Pipedrive API REST resource is saved with the API token configured as a default URL parameter. A test query to /v1/pipelines returns the list of pipelines in your Pipedrive account.

### 2. Query pipelines, stages, and deals data

Create the foundational queries for your pipeline dashboard. First, create getPipelines with Method GET and path /v1/pipelines to retrieve all pipelines with their IDs and names. Add a Dropdown component named dropdown_pipeline and bind its options to {{ getPipelines.data.data.map(p => ({ label: p.name, value: p.id })) }}.

Create getStages with Method GET and path /v1/stages and URL parameter: Key = pipeline_id, Value = {{ dropdown_pipeline.value }}. This returns all stages in the selected pipeline with their IDs, names, and order positions.

Create getDeals with Method GET and path /v1/deals. Add URL parameters: Key = pipeline_id, Value = {{ dropdown_pipeline.value }}, Key = stage_id, Value = {{ dropdown_stage.value || '' }}, Key = status, Value = open, Key = limit, Value = 100, Key = start, Value = {{ (pagination.pageNumber - 1) * 100 || 0 }}. The deals endpoint returns deal objects including the deal's stage ID, owner, value, expected close date, and activity counts.

For each deal, Pipedrive also returns person_id and org_id references. To show person and organization names alongside deals, either fetch them separately or use the include_fields parameter to get basic contact information inline.

Create a JavaScript transformer to flatten and enrich the deals response with calculated fields like days_in_stage and days_until_close.

```
// JavaScript transformer — flatten Pipedrive deals for table display
const deals = data?.data || [];
const now = new Date();

return deals.map(deal => {
  const expectedClose = deal.expected_close_date
    ? new Date(deal.expected_close_date)
    : null;
  const stageChanged = deal.stage_change_time
    ? new Date(deal.stage_change_time)
    : new Date(deal.add_time);
  const daysInStage = Math.floor((now - stageChanged) / (1000 * 60 * 60 * 24));
  const daysUntilClose = expectedClose
    ? Math.floor((expectedClose - now) / (1000 * 60 * 60 * 24))
    : null;

  return {
    id: deal.id,
    title: deal.title,
    stage: deal.stage_id,
    stage_name: deal.stage_id ? `Stage ${deal.stage_id}` : 'Unknown',
    owner: deal.owner_name || deal.user_id?.name || 'Unassigned',
    value: deal.value
      ? `$${deal.value.toLocaleString('en-US', { minimumFractionDigits: 0 })}`
      : '$0',
    currency: deal.currency,
    person: deal.person_name || deal.person_id?.name || 'N/A',
    organization: deal.org_name || deal.org_id?.name || 'N/A',
    expected_close: deal.expected_close_date || 'Not set',
    days_until_close: daysUntilClose !== null
      ? (daysUntilClose < 0 ? `${Math.abs(daysUntilClose)}d overdue` : `${daysUntilClose}d`)
      : 'No date',
    days_in_stage: daysInStage,
    activities_count: deal.activities_count || 0,
    status: deal.status
  };
});
```

**Expected result:** The deals table populates with all open deals in the selected pipeline, showing deal name, owner, value, expected close date, days in stage, and organization. The pipeline and stage dropdowns filter the results correctly.

### 3. Build deal update and stage transition actions

Add write operations to make your Pipedrive dashboard actionable, not just a read-only view. Create a query named updateDealStage with Method PATCH and path /v1/deals/{{ table_deals.selectedRow.id }}. Set the request body to JSON: { "stage_id": {{ dropdown_newStage.value }} }.

Add a Dropdown component named dropdown_newStage with options bound to {{ getStages.data.data.map(s => ({ label: s.name, value: s.id })) }}. Add a Button named btnMoveStage with an event handler that triggers updateDealStage. On success, trigger getDeals to refresh the table and show a success notification.

Create a query named addNote with Method POST and path /v1/notes. Set the JSON body to: { "content": "{{ textArea_note.value }}", "deal_id": {{ table_deals.selectedRow.id }} }. Add a Text Area component and a Save Note button to let users add notes to deals directly from the dashboard.

Create addActivity with Method POST and path /v1/activities. Set the body: { "subject": "{{ textInput_activitySubject.value }}", "type": "{{ select_activityType.value }}", "due_date": "{{ datePicker_dueDate.value }}", "deal_id": {{ table_deals.selectedRow.id }}, "user_id": {{ select_assignee.value }} }.

Add a modal (Modal component) that opens when a user clicks 'Log Activity', containing the activity form fields. Trigger addActivity on form submit, then close the modal and refresh the deals table on success.

```
// PATCH body for moving a deal to a new stage
// Used in updateDealStage query (JSON body)
{
  "stage_id": {{ dropdown_newStage.value }},
  "status": "open"
}
```

**Expected result:** Selecting a deal and choosing a new stage from the dropdown, then clicking 'Move Stage', successfully updates the deal in Pipedrive and refreshes the table. Note and activity creation forms also work, with the new records visible in Pipedrive immediately after saving.

### 4. Build pipeline analytics and reporting queries

Create queries for pipeline performance reporting. Query Pipedrive's pipeline statistics endpoint: create getPipelineStats with Method GET and path /v1/pipelines/{{ dropdown_pipeline.value }}/deals/summary. This endpoint returns aggregate totals including total_count, total_value, and total_count_by_stage.

Create getDealsTimeline with Method GET and path /v1/deals/timeline. Add URL parameters: Key = start_date, Value = {{ dateRange.start.toISOString().split('T')[0] }}, Key = interval, Value = month, Key = amount, Value = 6, Key = field_key, Value = close_time, Key = pipeline_id, Value = {{ dropdown_pipeline.value }}. This returns a monthly breakdown of deals closed over the past 6 months — perfect for a Chart component.

Add Stat components to your dashboard header showing total pipeline value (sum of all open deal values), average deal size, and win rate calculated from Pipedrive's statistics data.

Create a Chart component for deal count by stage. Bind its data to a transformer that maps pipeline stage data to bar chart format, with stage name on the X-axis and deal count + total value on Y-axes.

For RapidDev-style comprehensive sales operations dashboards that combine Pipedrive pipeline data with marketing attribution from HubSpot or Google Ads, Retool's multi-resource architecture allows you to join data sources in JavaScript queries for a complete revenue operations view.

```
// JavaScript transformer — format pipeline summary for stats display
const summary = data?.data || {};
const stages = summary.weighted_values_total || {};
const values = summary.values_total || {};

// Calculate total pipeline value across all stages
const totalValue = Object.values(values).reduce((sum, stageData) => {
  return sum + (parseFloat(stageData?.value || 0));
}, 0);

const totalCount = Object.values(values).reduce((sum, stageData) => {
  return sum + (parseInt(stageData?.count || 0));
}, 0);

return {
  total_value: `$${totalValue.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`,
  total_count: totalCount,
  avg_deal_size: totalCount > 0
    ? `$${(totalValue / totalCount).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
    : '$0.00',
  currency: summary.currency || 'USD'
};
```

**Expected result:** The pipeline stats section shows total pipeline value, deal count, and average deal size for the selected pipeline. The stage breakdown chart visualizes deal distribution, and the timeline chart shows monthly deal close trends for the past 6 months.

## Best practices

- Store the Pipedrive API token as a Secret configuration variable in Retool and reference it via {{ retoolContext.configVars.PIPEDRIVE_API_TOKEN }} in the resource's default URL parameters — never paste the token directly into individual query configurations.
- Create a dedicated Pipedrive user account for Retool integrations rather than using a specific team member's personal token — this prevents the dashboard from breaking when that person leaves or changes their password.
- Implement pagination for all deals queries by checking additional_data.pagination.more_items_in_collection in the API response and providing Load More functionality for pipelines with more than 500 active deals.
- Calculate deal health indicators like 'days_in_stage' and 'days_until_close' in JavaScript transformers rather than storing them in Pipedrive — these are derived values that should always reflect current real-time calculations.
- Add conditional row coloring to the deals table to highlight at-risk deals: red for deals past their expected close date, yellow for deals with no activity in 7+ days, and green for deals moving through stages on schedule.
- Use Retool's event handlers to chain queries efficiently — when a pipeline is selected, trigger getStages, and when stages load, trigger getDeals. This ensures dropdowns are populated before dependent queries execute.
- Add confirmation modals before any bulk operations (bulk stage changes, bulk assignment updates) to prevent accidental mass updates that would be difficult to undo in Pipedrive.
- Cache the pipeline and stage lists (which rarely change) using Retool's query cache with a 30-minute TTL to reduce API calls during active dashboard sessions.

## Use cases

### Build a cross-pipeline deal management dashboard

Create a Retool app that shows all active deals across all Pipedrive pipelines in a single Table, with columns for deal name, stage, owner, value, expected close date, and days in current stage. Add filters for pipeline, owner, and stage. Include a bulk action to move selected deals to the next stage or assign them to a different rep.

Prompt example:

```
Build a deal management table that fetches all open deals from Pipedrive's deals endpoint, shows deal name, stage, owner name, value, expected close date, and a calculated 'days in stage' field, with a pipeline dropdown filter, an owner filter, and a 'Move to Next Stage' button that updates the selected deal's stage_id via PATCH.
```

### Sales pipeline health and velocity tracking dashboard

Build a pipeline analytics dashboard that shows stage conversion rates, average deal age per stage, total pipeline value by stage, and weekly new deal volume. Add a Chart component showing deal inflow vs. deal closure over the past 30 days to surface pipeline health trends that Pipedrive's native reports don't easily surface.

Prompt example:

```
Create a pipeline metrics dashboard with Stat components showing total open pipeline value, average deal age, and win rate for the current quarter, plus a bar chart showing deal count and value per pipeline stage, and a line chart showing weekly new deals added vs. deals closed in the last 90 days.
```

### Activity and follow-up monitoring panel for sales managers

Build a sales activity dashboard where managers can see overdue activities by rep, deals with no activity in the past 7 days, and upcoming activities for the week. Display this alongside a rep performance table showing each salesperson's deal count, pipeline value, and activity completion rate for the current month.

Prompt example:

```
Build an activity monitoring panel that queries Pipedrive's activities endpoint for overdue activities (past due date), groups them by assigned user in a Table with deal name and activity type, and shows a second Table of deals with last_activity_date older than 7 days alongside the assigned rep's name and total pipeline value.
```

## Troubleshooting

### All Pipedrive API requests return 401 Unauthorized errors

Cause: The API token in the Retool resource configuration is incorrect, expired, or the resource's default URL parameter for api_token is not being appended to requests correctly.

Solution: Verify your API token in Pipedrive Settings → Personal preferences → API. Confirm the Retool resource's Default URL Parameters section has Key = api_token and Value = {{ retoolContext.configVars.PIPEDRIVE_API_TOKEN }}. Test by creating a simple query to /v1/pipelines and checking the full request URL in Retool's network preview — the api_token parameter should appear in the URL.

### Deal queries return only 20-50 deals even though hundreds exist in Pipedrive

Cause: Pipedrive's API defaults to returning 100 deals per page and requires explicit pagination. Without a start parameter, subsequent pages are never fetched, resulting in incomplete data.

Solution: Add pagination URL parameters to your getDeals query: Key = limit with value 500 (max allowed), and Key = start with value {{ (pagination.pageNumber - 1) * 500 || 0 }}. Add a Pagination component to the Table and configure it to update the start offset. For large datasets, also check additional_data.pagination.more_items_in_collection in the API response to know when you've loaded all deals.

```
// URL parameters for Pipedrive deal pagination
// Key: limit → Value: 500
// Key: start → Value:
{{ (table_deals.pagination.offset) || 0 }}
```

### Deal person and organization names appear as IDs or 'N/A' instead of actual names

Cause: Pipedrive's deals endpoint returns person_id and org_id as nested objects only when the data is freshly fetched. Cached or paginated responses may return only the ID number without the nested name property.

Solution: Access the name from the nested object structure: use deal.person_id?.name and deal.org_id?.name in your transformer. Alternatively, include the full person and organization details by adding URL parameter: Key = fields, Value = deal.person_id,deal.org_id to request the full nested objects. For the most reliable approach, make a separate query to /v1/persons/{id} when you need complete person details for a selected deal.

```
// Safe access for person and org names in transformer
person: deal.person_id?.name || deal.person_name || 'No contact',
organization: deal.org_id?.name || deal.org_name || 'No organization',
```

### PATCH request to update deal stage succeeds (200 response) but the deal doesn't move in Pipedrive

Cause: The stage_id being sent in the PATCH body doesn't belong to the pipeline that the deal is currently in. Pipedrive requires stage changes to be within the same pipeline — you cannot move a deal to a stage from a different pipeline in a single request.

Solution: Verify that the stage IDs in your dropdown_newStage options come from the same pipeline as the selected deal. Filter the stages dropdown to only show stages from the deal's pipeline: bind dropdown_newStage options to {{ getStages.data.data.filter(s => s.pipeline_id === table_deals.selectedRow.pipeline_id).map(s => ({ label: s.name, value: s.id })) }}.

## Frequently asked questions

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

No, Pipedrive does not have a native connector in Retool. You configure it as a REST API Resource using Pipedrive's personal API token as a default URL parameter. The setup is straightforward and requires no OAuth flow — just copy your API token from Pipedrive Settings → Personal preferences → API and configure the resource in a few minutes.

### Can I build a Kanban-style pipeline view in Retool for Pipedrive deals?

Retool doesn't have a native Kanban board component, but you can approximate one using multiple Table components side by side (one per stage) or using a custom component with a Kanban library. The most practical approach is using a single Table with a Stage column and conditional row colors, combined with a 'Move Stage' action button. For a true drag-and-drop Kanban, consider using Retool's custom component feature with a React Kanban library.

### How do I sync deal data from my own database with Pipedrive using Retool?

Add your database as a second resource in the same Retool app alongside the Pipedrive API resource. Create a JavaScript query that first fetches records from your database, then for each record, checks whether a matching Pipedrive deal exists (by searching deals with a custom field matching your internal ID), and either creates a new deal or updates the existing one using POST or PATCH requests to Pipedrive's deals endpoint. For recurring sync, use a Retool Workflow with a scheduled trigger.

### What is the Pipedrive API rate limit, and how do I avoid hitting it?

Pipedrive's API rate limit is 80 requests per 2 seconds for most plans, with a daily limit that varies by plan tier. For Retool dashboards with multiple queries loading simultaneously, stagger query execution using On Success event handlers rather than running everything in parallel on page load. For high-frequency polling or bulk operations, use Retool Workflows with throttled loop blocks that include delays between iterations.

### Can I use Pipedrive webhooks with Retool to get real-time deal updates?

Yes, you can configure Pipedrive webhooks to trigger a Retool Workflow via a Webhook trigger. In Pipedrive Settings → Tools & apps → Webhooks, create a webhook for deal updates that points to your Retool Workflow's webhook URL. The Workflow can then process the event (e.g., when a deal moves to 'Won', trigger a notification or update your internal database). This enables near-real-time data sync without constant polling.

---

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