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.
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.
Method comparison
| Method | Cost | Setup | Refresh | Two-way | Best for |
|---|---|---|---|---|---|
| Pipedrive CSV export | Free | 2 min | Manual | No | A one-off filtered deal export |
| Apps Script + REST API | Free | 25 to 40 min | Time-driven trigger | DIY | Custom fields and multiple entities |
| Zapier / Make | Free tier limited · paid for volume | 10 to 15 min | On deal change | DIY (second workflow) | Logging individual deal events |
| Brooked | Free tier · Pro $29/user/mo | ~3 min | Scheduled (hourly, daily, weekly) | Yes | Scheduled 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
Related Articles
- How to Connect HubSpot to Google Sheets
- HubSpot to Google Sheets: Why Your Data All Goes to One Cell (and How to Fix It)
- How to Sync HubSpot Deals and Pipeline Data to Google Sheets in Real Time
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 →

