Pipedrive API v2 migration guide
Migration Guide
This document outlines the differences between Pipedrive API v1 and v2 of endpoints which are available on v2. Where available, please use API v2 for the best performance and developer experience.
General API Changes
- All v2 endpoints now have significantly stricter input validation to improve data quality and prevent ambiguity.
- Any boolean value fields which returned or accepted
1
or0
now only return and accepttrue
andfalse
respectively. - Numeric fields no longer coerce string input to number and instead throw a validation error.
- Any boolean value fields which returned or accepted
- Related objects have been removed from API responses to prevent too eager fetching of unnecessary data. Use subsequent API calls to fetch them if you still need them.
- All timestamps in the v2 API are now in RFC 3339 format (e.g.
2024-01-01T00:00:00Z
) unless specified otherwise to ensure clarity regarding timezones. - Support for field selectors has been removed.
- V1 endpoints, which were using HTTP PUT method have been switched to use HTTP PATCH method in v2 for compliance with REST best practices.
- Only
/api/v2/...
prefix is supported. Previously both/api/v1/...
and/v1/...
could be used.
Custom Fields
Entity custom fields have been moved to a separate custom_fields
object with clearer syntax.
Previously custom fields were on the root level of the entity object and had separate keys for their subfields. For example, a currency custom field in API v1 was presented as
"d4de1c1518b4531717c676029a45911c340390a6": 2300,
"d4de1c1518b4531717c676029a45911c340390a6_currency": "EUR"
The same field is now presented in API v2 as
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": {
"value": 2300,
"currency": "EUR"
},
...
}
See subsections below for the exact changes for each custom field type.
Text, Large Text and Autocomplete Custom Fields Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "my text value"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": "my text value",
...
}
Numeric Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": 500
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": 500,
...
}
Currency Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": 500,
"d4de1c1518b4531717c676029a45911c340390a6_currency": "USD"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": {
"value": 500,
"currency": "USD"
},
...
}
Address Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "530 Fifth Avenue, New York, NY, USA",
"d4de1c1518b4531717c676029a45911c340390a6_route": "5th Avenue",
"d4de1c1518b4531717c676029a45911c340390a6_subpremise": null, // no longer included, was always null
"d4de1c1518b4531717c676029a45911c340390a6_country": "United States",
"d4de1c1518b4531717c676029a45911c340390a6_locality": "New York",
"d4de1c1518b4531717c676029a45911c340390a6_postal_code": "10036",
"d4de1c1518b4531717c676029a45911c340390a6_sublocality": "Manhattan",
"d4de1c1518b4531717c676029a45911c340390a6_street_number": "530",
"d4de1c1518b4531717c676029a45911c340390a6_admin_area_level_1": "New York",
"d4de1c1518b4531717c676029a45911c340390a6_admin_area_level_2": "New York County"
"d4de1c1518b4531717c676029a45911c340390a6_formatted_address": "530 5th Ave, New York, NY 10036, USA",
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": {
"route": "5th Avenue",
"value": "530 Fifth Avenue, New York, NY, USA",
"country": "United States",
"locality": "New York",
"postal_code": "10036",
"sublocality": "Manhattan",
"street_number": "530",
"admin_area_level_1": "New York",
"admin_area_level_2": "New York County",
"formatted_address": "530 5th Ave, New York, NY 10036, USA"
},
...
}
Single Option Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "123" // ID of the selected option. Can be mapped to user presented value via field endpoints.
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": 123, // option ID is now a number
...
}
Multiple Option Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "123,456" // concatenated IDs of the selected option. Can be mapped to user presented value via field endpoints.
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": [123, 456], // option IDs are now in an array as numeric values.
...
}
User, Person, Organization Custom Fields Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": 1234 // ID of the user/person/org
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": 1234, // ID of the user/person/org
...
}
Date Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "2024-01-01"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": "2024-01-01",
...
}
Date Range Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "2024-01-01"
"d4de1c1518b4531717c676029a45911c340390a6_until": "2024-02-01"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": {
"value": "2024-01-01",
"until": "2024-02-01"
},
...
}
Time Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "09:00:00"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": "09:00:00",
...
}
Time Range Custom Field Format Changes
API v1
"d4de1c1518b4531717c676029a45911c340390a6": "09:00:00"
"d4de1c1518b4531717c676029a45911c340390a6_until": "11:00:00"
API v2
"custom_fields": {
...,
"d4de1c1518b4531717c676029a45911c340390a6": {
"value": "09:00:00",
"until": "11:00:00"
},
...
}
Pagination
Offset based pagination (start
& limit
) has been replaced with cursor based pagination (cursor
& limit
), which makes iterating over large collections significantly faster. See Pagination for more information.
Sorting
Endpoints, which support sorting, now have 2 optional parameters (sort_by
and sort_direction
) instead of 1 (sort
).
- sort_by
accepted values: id
, add_time
, update_time
plus a few additional fields depending on the entity. Defaults to id
.
- sort_direction
accepted values: asc
, desc
. Defaults to asc
.
A maximum of 1 field to sort by can be provided.
Products API
Products Object
Changes Summary
Please note that this section does not include the changes already covered in General API Changes section.
first_char
andfiles_count
fields are no longer includedvisible_to
field type has changed from string to integer. Old possible values were"1"
,"3"
,"5"
,"7"
. New possible values are1
,3
,5
,7
.selectable
field has been renamed tois_linkable
for clarity. When set totrue
, the product is linkable to deals.active_flag
field has been replaced withis_deleted
. It is the negation of the old value. When an entity hasis_deleted
set to true, the entity is considered soft deleted and will be fully deleted after 30 days of last activity.product_variations
has been removed to a separate Product Variations API described below.
Old v1 Product Object Example
{
"id": 3,
"name": "Name",
"code": "Code",
"description": "Description",
"unit": "Unit",
"tax": 20,
"category": "262",
"active_flag": true, // replaced with is_deleted flag. NB: is_deleted is the negated value of the old active_flag.
"selectable": true, // replaced with is_linkable flag
"first_char": "n", // no longer included
"visible_to": "7", // is now an integer
"owner_id": { // Replaced with only the numeric id of the owner user
"id": 6192726,
"name": "Owner Name",
"email": "[email protected]",
"has_pic": 1,
"pic_hash": "08bcf87d30a6662032680b65bfa1b509",
"active_flag": true,
"value": 6192726
},
"files_count": null, // no longer included
"add_time": "2021-01-11 17:30:10",
"update_time": "2024-01-09 09:31:15",
"prices": [
{
"id": 5, // no longer included
"product_id": 3,
"price": 54,
"currency": "EUR",
"cost": 0,
"overhead_cost": 0,
"price_formatted": "54 €" // no longer included
}
],
"product_variations": [], // moved to a separate product variations API
"53c2f18db6a1655d6af8bba77d9679565f975fd8": "Text Custom Field", // wrapped in custom_fields object
"d4de1c1518b4531717c676029a45911c340390a6": 2300, // wrapped in custom_fields object
"d4de1c1518b4531717c676029a45911c340390a6_currency": "EUR" // wrapped in custom_fields object
}
New v2 Product Object Example
{
"id": 3,
"name": "Name",
"tax": 20,
"add_time": "2021-01-11T17:30:10Z",
"update_time": "2024-01-09T09:31:15Z",
"description": "Description",
"code": "Code",
"unit": "Unit",
"owner_id": 6192726, // is no longer a user object, just the id
"category": "262",
"visible_to": 7, // is now an integer
"is_deleted": false, // Replaces old 'active_flag' field. NB: is_deleted is the negated value of the old active_flag.
"is_linkable": true, // Replaces old 'selectable' field
"prices": [
{
"product_id": 3,
"price": 54,
"currency": "EUR",
"cost": 0,
"direct_cost": 0
}
],
"custom_fields": { // custom fields are no longer flat root level fields
"53c2f18db6a1655d6af8bba77d9679565f975fd8": "Text Custom Field",
"d4de1c1518b4531717c676029a45911c340390a6": {
"value": 2300,
"currency": "EUR"
}
}
}
GET /api/v1/products/:id to GET /api/v2/products/:id
Please note that this section does not include the changes already covered in General API Changes section.
Returned product object has changed, see Products Object for details.
GET /api/v1/products to GET /api/v2/products
Please note that this section does not include the changes already covered in General API Changes section.
Returned product object has changed, see Products Object for details.
- sorting is only supported by
id
,add_time
,update_time
orname
- optional parameter
user_id
has been renamed toowner_id
. It allows filtering products by specific owner user. get_summary
andfirst_char
parameters have been removed
POST /api/v1/products to POST /api/v2/products
Please note that this section does not include the changes already covered in General API Changes section.
Only the name
field is required. Everything else is optional and expected in the format described in Products Object section.
- It is no longer possible to create an already deleted entity with POST.
PUT /api/v1/products to PATCH /api/v2/products
Please note that this section does not include the changes already covered in General API Changes section.
Any fields changed are expected to be in the format described in Products Object section.
- It is no longer possible to use PATCH (former PUT) requests to delete an entity. Use corresponding DELETE endpoint instead.
- When updating
prices
, the whole existing array will be replaced with the passed array.
DELETE /api/v1/products to DELETE /api/v2/products
No changes other than version change in the URL.
Deal Products API
Deal Products Object
Changes Summary
Please note that this section does not include the changes already covered in General API Changes section.
product
,order_nr
,quantity_formatted
andsum_formatted
fields are no longer included.active_flag
has been removed as it was alwaystrue
.comments
field can not benull
anymore. If it is not set, it will be an empty string""
.
Old v1 Deal Product Object Example
{
"id": 1,
"deal_id": 1,
"product_id": 1,
"product_variation_id": null,
"name": "Name",
"order_nr": 1, // no longer included
"item_price": 10,
"quantity": 3,
"duration": 1,
"duration_unit": null,
"sum": 30,
"tax": 0,
"tax_method": "inclusive",
"currency": "EUR",
"active_flag": true, // removed, was always true
"enabled_flag": true, // renamed to is_enabled
"add_time": "2020-11-12 12:10:45",
"last_edit": "2022-11-12 12:10:45", // renamed to update_time
"comments": null, // can not be null anymore. If not set, is an empty string instead.
"quantity_formatted": "3", // no longer included
"sum_formatted": "30 €", // no longer included
"discount": 0,
"discount_type": "percentage",
"product": null // no longer included
}
New v2 Deal Product Object Example
{
"id": 1,
"deal_id": 1,
"product_id": 1,
"product_variation_id": null,
"name": "Name",
"item_price": 10,
"quantity": 3,
"sum": 30,
"tax": 0,
"tax_method": "inclusive",
"currency": "EUR",
"is_enabled": true, // renamed from enabled_flag
"add_time": "2020-11-12T12:10:45Z",
"update_time": "2022-11-12T12:10:45Z", // renamed from last_edit
"comments": "", // can not be null anymore
"discount": 0,
"discount_type": "percentage"
}
GET /api/v1/deals/:id/products to GET /api/v2/deals/:id/products or GET /api/v2/deals/products?deal_ids=..,..
Please note that this section does not include the changes already covered in General API Changes section.
Returned product object has changed, see Deal Products Object for details.
- New alternative endpoint is available to fetch multiple deals' products at once:
GET /api/v2/deals/products
. You can fetch up to 100 deals products at once by providing a comma separated list of deal IDs indeal_ids
querystring parameter.
POST /api/v1/deals/:id/products to POST /api/v2/deals/:id/products
Please note that this section does not include the changes already covered in General API Changes section.
Keys are expected in the format described in Deal Products Object section.
- It is no longer possible to create an already deleted entity with POST.
PUT /api/v1/deals/:id/products to PATCH /api/v2/deals/:id/products
Any fields changed are expected to be in the format described in Deal Products Object section.
- It is no longer possible to use PATCH (former PUT) requests to delete an entity. Use the corresponding DELETE endpoint instead.
DELETE /api/v1/deals/:id/products to DELETE /api/v2/deals/:id/products
No changes other than version change in the URL.
Product Variations API
Product Variation Object
Changes Summary
Please note that this section does not include the changes already covered in General API Changes section.
Previously product variations were returned as part of the main products API. They have now been moved to a separate API with the following endpoints:
GET /v2/products/:id/variations
POST /v2/products/:id/variations
PATCH /v2/products/:id/variations/:id
DELETE /v2/products/:id/variations/:id
The prices
object no longer includes the following fields: id
, product_id
, comment
and price_formatted
.
Old v1 Product Variation Object Example (within old v1/products API)
{
"id": 1,
"name": "Variation 1",
"product_id": 1,
"prices": [
{
"id": 1, // no longer included
"product_id": 1, // no longer included within price object, use root level field instead
"product_variation_id": 1,
"price": 10,
"currency": "EUR",
"cost": 20,
"comment": "", // no longer included
"price_formatted": "10 €" // no longer included
}
]
}
New v2 Product Variation Object Example
{
"id": 1,
"name": "Variation 1",
"product_id": 1,
"prices": [
{
"product_variation_id": 1,
"price": 10,
"currency": "EUR",
"cost": 20
}
]
}
Search API
GET /api/v1/deals/search to GET /api/v2/deals/search
GET /api/v1/persons/search to GET /api/v2/persons/search
GET /api/v1/organizations/search to GET /api/v2/organizations/search
GET /api/v1/leads/search to GET /api/v2/leads/search
GET /api/v1/products/search to GET /api/v2/products/search
GET /api/v1/itemSearch to GET /api/v2/itemSearch
Only change is a switch to cursor based pagination (cursor
and limit
instead of start
and limit
). See Pagination for more information.
GET /api/v1/itemSearch/field to GET /api/v2/itemSearch/field
- The endpoint now uses cursor based pagination. See Pagination for more information.
field_key
parameter has been renamed tofield
.field_type
parameter has been renamed toentity_type
.entity_type
accepted values have been simplified to justdeal
,lead
,person
,organization
,product
,project
from previousdealField
,leadField
etc.return_item_ids
parameter has been removed, the response always includes item ids now.exact_match
boolean parameter has been replaced with a stringmatch
parameter. Accepted values areexact
- fastest. Matches only if the field value is exactly the same as theterm
.beginning
- fast. Matches fields by beginning, e.g. findsmy field value
withmy fie
middle
- slowest. Old default behaviour. Matches fields by any substring, e.g. findsmy field value
withld va
. We recommend using other types of matching where possible for best experience.
Pipelines API
Pipeline Object
Changes Summary
Please note that this section does not include the changes already covered in General API Changes section.
url_title
field is no longer included.selected
field has been renamed tois_selected
for clarity. When set totrue
, the product is linkable to deals.active_flag
field has been replaced withis_deleted
. It is the negation of the old value. When an entity hasis_deleted
set to true, the entity is considered soft deleted and will be fully deleted after 30 days of last activity.order_nr
is now read-only. When creating a new pipeline, it is placed at the end of existing Pipelines list. If user wants, they can reorder pipelines in the UI.
Old v1 Pipeline Object Example
{
"id": 1,
"name": "Sales Pipeline",
"url_title": "Sales-Pipeline", // removed
"order_nr": 1,
"active": true, // replaced with is_deleted. NB: Negation of the old value.
"deal_probability": false, // replaced with is_deal_probability_enabled
"add_time": "2018-09-03 17:05:08",
"update_time": "2018-09-04 12:46:03",
"selected": true // renamed to is_selected
}
New v2 Pipeline Object Example
{
"id": 1,
"name": "Sales Pipeline",
"order_nr": 1,
"is_deleted": false, // replaces "active". NB: Negation of the old value.
"is_deal_probability_enabled": false, // replaces "deal_probability"
"add_time": "2018-09-03T17:05:08Z",
"update_time": "2018-09-04T12:46:03Z",
"is_selected": true // renamed from "selected"
}
GET /api/v1/pipelines/:id to GET /api/v2/pipelines/:id
Please note that this section does not include the changes already covered in General API Changes section.
Returned pipeline object has changed, see Pipeline Object for details.
GET /api/v1/pipelines to GET /api/v2/pipelines
Please note that this section does not include the changes already covered in General API Changes section.
Returned pipeline object has changed, see Pipeline Object for details.
POST /api/v1/pipelines to POST /api/v2/pipelines
Please note that this section does not include the changes already covered in General API Changes section.
Only the name
field is required. Everything else is optional and expected in the format described in Pipeline Object section.
- It is no longer possible to create an already deleted entity with POST.
PUT /api/v1/pipelines to PATCH /api/v2/pipelines
Please note that this section does not include the changes already covered in General API Changes section.
Any fields changed are expected to be in the format described in Pipeline Object section.
- It is no longer possible to use PATCH (former PUT) requests to delete an entity. Use corresponding DELETE endpoint instead.
DELETE /api/v1/pipelines to DELETE /api/v2/pipelines
No changes other than version change in the URL.
Stages API
Stage Object
Changes Summary
Please note that this section does not include the changes already covered in General API Changes section.
pipeline_name
andpipeline_deal_probability
fields have been removed. Query the pipeline object if you need these.rotten_flag
has been replaced withis_deal_rot_enabled
flag.rotten_days
has been replaced withdays_to_rotten
for clarity.active_flag
field has been replaced withis_deleted
. It is the negation of the old value.
Old v1 Stage Object Example
{
"id": 1,
"order_nr": 1,
"name": "Lead In",
"active_flag": true, // replaced with is_deleted. NB: Negation of the old value.
"deal_probability": 100,
"pipeline_id": 1,
"pipeline_name": "Sales Pipeline", // removed, query pipeline API instead
"pipeline_deal_probability": false, // removed, query pipeline API instead
"rotten_flag": false, // replaced with is_deal_rot_enabled
"rotten_days": null, // replaced with days_to_rotten
"add_time": "2018-09-04 06:24:59",
"update_time": null
}
New v2 Stage Object Example
{
"id": 1,
"order_nr": 1,
"name": "Lead In",
"is_deleted": false, // replaces "active_flag". NB: Negation of the old value.
"deal_probability": 100,
"pipeline_id": 1,
"is_deal_rot_enabled": false, // replaces "rotten_flag"
"days_to_rotten": null, // replaces "rotten_days"
"add_time": "2018-09-04T06:24:59Z",
"update_time": null
}
GET /api/v1/stages/:id to GET /api/v2/stages/:id
Please note that this section does not include the changes already covered in General API Changes section.
Returned stage object has changed, see Stage Object for details.
GET /api/v1/stages to GET /api/v2/stages
Please note that this section does not include the changes already covered in General API Changes section.
Returned stage object has changed, see Stage Object for details.
POST /api/v1/stages to POST /api/v2/stages
Please note that this section does not include the changes already covered in General API Changes section.
Only the name
field is required. Everything else is optional and expected in the format described in Stage Object section.
- It is no longer possible to create an already deleted entity with POST.
PUT /api/v1/stages to PATCH /api/v2/stages
Please note that this section does not include the changes already covered in General API Changes section.
Any fields changed are expected to be in the format described in Stage Object section.
- It is no longer possible to use PATCH (former PUT) requests to delete an entity. Use corresponding DELETE endpoint instead.
DELETE /api/v1/stages to DELETE /api/v2/stages
No changes other than version change in the URL.
Updated 5 days ago