Pricing

How to Connect Pipedrive to Google Sheets

PipedriveSaved SearchDateDocumentAmount07/01INV-40214,280.0007/02INV-40221,860.5007/05INV-40239,140.0007/08INV-40242,375.2507/09INV-40256,902.7507/12INV-40263,118.40BrookedABCDateDocumentAmount123456707/01INV-40214,280.0007/02INV-40221,860.5007/05INV-40239,140.0007/08INV-40242,375.2507/09INV-40256,902.7507/12INV-40263,118.40Google SheetsPipedrive report
JW
James Whitfield

Sync Pipedrive deals to Google Sheets, including the 40-character hashed keys your custom fields arrive under and the option IDs that hide dropdown labels.

Pipedrive's API is pleasant to work with except for one thing that makes a raw export nearly unreadable: custom fields come back keyed by 40-character hashes rather than names, and their dropdown values come back as numeric option IDs. A deal export therefore arrives full of columns like dcf558aac1ae4e8c… containing values like 47. This guide covers resolving both, plus pagination and the v1 to v2 migration.

The two-minute option: CSV export

In Pipedrive, open Deals in list view, apply a filter, select the columns you want, and use … → Export filter results. The export uses your chosen columns with their proper names, so custom fields arrive readable, which is exactly the work the API leaves to you. Import into Sheets via File → Import.

Pipedrive to Google Sheets for free (Apps Script + REST API)

Find your API token under Settings → Personal preferences → API. It goes on the query string as api_token. Your company domain is the first part of your Pipedrive URL.

The pattern that makes this usable: fetch dealFields once to build two maps, hash to field name and option ID to option label, then translate every deal as you write it.

Code.gs
function importPipedriveDeals() {  const DOMAIN = "yourcompany";  const TOKEN  = "YOUR_API_TOKEN";  const root = "https://" + DOMAIN + ".pipedrive.com/api/v1";   // Custom fields are keyed by 40-char hashes. Build hash → name, and  // optionId → label for dropdown fields, before touching any deals.  const fieldNames = {}, optionLabels = {};  const fields = JSON.parse(    UrlFetchApp.fetch(root + "/dealFields?api_token=" + TOKEN).getContentText()  ).data;   fields.forEach((f) => {    fieldNames[f.key] = f.name;    (f.options || []).forEach((o) => { optionLabels[String(o.id)] = o.label; });  });   // Only the hashed custom fields need translating; standard keys are readable.  const customKeys = fields.filter((f) => f.key.length === 40).map((f) => f.key);   const rows = [];  let start = 0;   while (true) {    const url = root + "/deals?api_token=" + TOKEN      + "&limit=100&start=" + start;     const body = JSON.parse(      UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText()    );    if (!body.success) throw new Error(JSON.stringify(body));    if (!body.data) break;     body.data.forEach((d) => {      const custom = customKeys.map((k) => {        const v = d[k];        if (v === null || v === undefined || v === "") return "";        // Dropdowns return option IDs, possibly comma separated.        return String(v).split(",")          .map((part) => optionLabels[part.trim()] || part.trim())          .join(", ");      });       rows.push([        d.title,        d.status,        d.stage_id,        d.value,        d.currency,        d.owner_name || (d.user_id && d.user_id.name) || "",        d.org_name || "",        d.add_time,        d.won_time || d.lost_time || "",        ...custom,      ]);    });     // Trust the pagination flag, not the page size: filters can return    // short pages while more results remain.    const p = body.additional_data && body.additional_data.pagination;    if (!p || !p.more_items_in_collection) break;    start = p.next_start;  }   const header = ["Title","Status","Stage","Value","Currency","Owner",                  "Organization","Created","Closed",                  ...customKeys.map((k) => fieldNames[k] || k)];   const ss = SpreadsheetApp.getActiveSpreadsheet();  const sheet = ss.getSheetByName("Deals") || ss.insertSheet("Deals");  sheet.clearContents();  sheet.getRange(1, 1, 1, header.length).setValues([header]);  if (rows.length) {    sheet.getRange(2, 1, rows.length, header.length).setValues(rows);  }}

The pagination detail matters more than it looks: checking whether a page came back shorter than the limit is unreliable in Pipedrive, because filtered collections can return short pages with more results behind them. Always read additional_data.pagination.more_items_in_collection.

Limits: Pipedrive rate limits per token, and Apps Script stops at six minutes. Stage and pipeline names need their own lookups from the stages and pipelines endpoints, since deals reference them by ID just as they do custom field options.

The Brooked method

Brooked resolves the hashed custom field keys to their names, translates dropdown option IDs to labels, and looks up stage, pipeline and owner names, so deals arrive as a readable table. Deals, people, organizations and activities can all import into one spreadsheet on a single schedule.

Step 1: Install Brooked

Install Brooked from the Google Workspace Marketplace. Free tier includes 100 imports per month, no credit card required.

Step 2: Connect Pipedrive

Choose Pipedrive in Brooked and authorise, or paste an API token from Settings → Personal preferences → API. Pick deals, people, organizations or activities, optionally filter by pipeline or date, and import.

Step 3: Schedule the refresh

Set the import to re-run hourly or daily so pipeline reports and forecasts reflect current stages rather than whatever they were when the sheet was built.

BrookedBrooked AI, Pipedrive
Live
Ask anything about your Pipedrive data…

Method comparison

MethodCostSetupRefreshTwo-wayBest for
Pipedrive CSV exportFree2 minManualNoA one-off filtered deal export
Apps Script + REST APIFree25 to 40 minTime-driven triggerDIYCustom fields and multiple entities
Zapier / MakeFree tier limited · paid for volume10 to 15 minOn deal changeDIY (second workflow)Logging individual deal events
BrookedFree tier · Pro $29/user/mo~3 minScheduled (hourly, daily, weekly)YesScheduled pipeline reporting

Common use cases

  • Pipeline forecasting: weighted value by stage and close date in a sheet finance trusts
  • Win/loss analysis: conversion rates between stages and where deals stall
  • Rep performance: deals created, won and lost per owner over time
  • Revenue reconciliation: join won deals against invoices or Stripe data in the same sheet
  • Data hygiene: find deals missing owners, close dates or required custom fields

Troubleshooting common issues

Frequently asked questions

Why are my Pipedrive custom fields named like 3f9d6b6e4e8c4f849ba5?

Pipedrive identifies custom fields by a 40-character hash rather than their name, so a deal returns keys like dcf558aac1ae4e8c4f849ba5e3ee4b6b3f9d6b6e instead of Contract Value. Call the dealFields endpoint once to build a hash-to-name map and translate your headers. The hashes are per account, so a script written against one Pipedrive will not work against another.

Why do dropdown custom fields show numbers?

Single and multiple option fields return the option's numeric ID, not its label. The same dealFields response that gives you names also contains an options array per field, with id and label pairs. Build a second map from those to resolve values, and note multiple-option fields return a comma-separated string of IDs.

Can I export Pipedrive to Google Sheets for free?

Yes. Pipedrive exports any filtered list view to CSV or Excel from the list view, free on all plans, which handles a one-off. The Apps Script method here uses a free API token and a free time-driven trigger for data that refreshes. Brooked's free tier covers 100 imports a month.

Should I use API v1 or v2?

Pipedrive has been moving to API v2, which uses cursor pagination and is faster on large collections, while v1 remains widely documented and uses start and limit offsets. Build new work on v2 where the endpoint exists, since v1 endpoints are being progressively deprecated, but check availability per resource as the migration is not uniform.

How do I know when to stop paginating?

On v1, the response's additional_data.pagination object contains more_items_in_collection as a boolean and next_start as the offset to use next. Do not rely on a short page to signal the end, because filters can produce pages smaller than the limit while more results remain. On v2, follow the cursor until none is returned.

Can I update deals in Pipedrive from Google Sheets?

Yes for editable fields, and Brooked supports write-back, so bulk updates to stage, owner, value or custom fields are possible from a sheet. Computed values reject writes, including weighted value and rotten flags, which Pipedrive derives from the deal's stage probability and inactivity settings.

Connect Pipedrive to Google Sheets today.

Free tier: 100 imports per month, no credit card required. Or see the full Pipedrive integration details.

Install Brooked free →

Also in CRM

More CRM guides

CRM

How to Connect HubSpot to Google Sheets

5 ways to sync HubSpot with Google Sheets: official add-on vs Workflows vs Apps Script vs Brooked. Two-way sync, scheduled refresh, no Operations Hub.

JW
James Whitfield
Read
CRM

How to Connect Salesforce to Google Sheets

Every realistic way to get Salesforce data into Google Sheets in 2026, manual report exports, Data Loader, Zapier, Apps Script with SOQL, and a no-code connector, plus the API-edition gotcha that blocks most setups.

BT
Brooked Team
Read

Get your spreadsheet hours back

Brooked sets up in seconds. Your team is querying live data before lunch.

Get started free