Pipedrive API with Python: How to write to contact records
Tags: python, database, startup, tutorial
Published: 2021-06-10 19:11:29

Chances are you and your team have felt frustrated at some point because you’re missing sales you could have made if data were better utilized. You took the effort to implement Pipedrive as a sales CRM but some other system also generates valuable data that is not fed to Pipedrive, too. 

On top of that, that data point doesn't fit neatly into Pipedrive's default fields. There is, for example, no default field for trial end date available to include in your contact records (even though this could help you reach out to potential customers in your sales pipeline with an offer at just the right time). Luckily, you can create a custom field and write data to it using the Pipedrive API and significantly improve your sales process functionality.

## Getting set up with the Pipedrive API  
We'll use Python to connect to the Pipedrive API to make our trial end date data available where we need it to be. To connect to the Pipedrive API, you will need to gather two things from within the web app. First, you’ll need your API access token, which you can find [here](https://app.pipedrive.com/settings/api). If you have access to multiple companies, make sure that you are within the right environment. Second, you will need the company domain, which you can find in the address bar (e.g. https://this-is-your-domain.pipedrive.com.)

You’ll also have to install the [Python requests library](https://pypi.org/project/requests/) if you haven't done that previously. You can do so by launching your terminal or command prompt and entering the command below.
```
pip install requests
pip3 install requests # Use this if the first one doesn't work for you.
```

We recommend running all code in a [Jupyter Notebook](https://jupyter.org/) for your first attempt so that you can easily see the output and interact with it, though creating a .py file will work as well.

We'll start by importing the necessary libraries. The requests library will allow us to make HTTP requests to the Pipedrive API and the [json library](https://docs.python.org/3/library/json.html) will allow us to properly parse the responses.
```
import json
import requests
```

## Checking your existing Pipedrive fields  
Before we get started, we need to find out if the field we want to write data to already exists. Since we'll be making a GET request, a POST request, and a PUT request, the variables have been prepended with *get_*, *post_* and *put_* to help you distinguish between them.
```
# token hasn't been prepended with get_ because it needs to be sent with all requests.

token = {
    'api_token': 'your-api-token-found-in-the-web-app'
}

get_url = 'https://your-domain.pipedrive.com/api/v1/personFields'

# The params argument is appended to the url as a query parameter.
get_response = requests.get(get_url, params=token)

get_content = json.loads(get_response.content)

# Upon success, the key 'success' will equal True.
print(get_content['success'])
```

A response to a successful GET request will contain the fields that you already have in the API key data. We'll print the names of all the fields and their respective indices. Unless your company naming conventions are absolutely topnotch, you'll want to go through this list manually to check if your custom field already exists. 
```
get_data = get_content['data']

for i, v in enumerate(get_data):
    print(i, v['name'])


# If you want to further examine the field at index 5.
print(get_data[5]) 
```

If the custom field that you want to write to already exists, save its “key” value to a variable.
```
# If for example the index of your field is 5.
field_key = get_data[5]['key']
```

Follow along with the next section to create a custom field if you didn't find an existing field that meets your needs.

## Creating a Pipedrive custom field 
Creating the custom field if it doesn't exist yet is fairly straightforward. You'll just need to think of a name for your custom field and decide its type.  You have several options when it comes to the field type, which you can find in the [API reference](https://developers.pipedrive.com/docs/api/v1/PersonFields#addPersonField). For our trial end date example, it makes the most sense to go with “date.”
```
# token should still be defined from the GET request, but in case you skipped over that, here it is again.

token = {
    'api_token': 'your-api-token-found-in-the-web-app'
}

# The field that you want to create.
post_data = {
    'name': 'trial end date',
    'field_type': 'date'
}

post_url = 'https://your-domain.pipedrive.com/api/v1/personFields' 

post_response = requests.post(post_url, params=token, data=post_data)

post_content = json.loads(post_response.content)

# The key 'success' should equal True.
print(post_content['success'])
```

If you successfully created a field, the response will contain a “data” key with the information of the field. This information includes a key called “key,” which you’ll need when writing data to this field.
```
field_key = post_content['data']['key']
```

## Writing data to a Pipedrive custom field 
Now that you have a custom field in place, you can write data to it. Heads up, the Pipedrive API reference is misleading (it makes it seem like you can only write data to default fields, which actually isn’t the case). To complete this step, you’ll need to find the ID of the user you want to write data to. To make it easier, you can get a list of [all your users](https://developers.pipedrive.com/docs/api/v1/Persons#getPersons) or [search for specific users](https://developers.pipedrive.com/docs/api/v1/Persons#searchPersons).
```
# token should still be defined from the GET request, but in case you skipped over that, here it is again.
token = {
    'api_token': 'your-api-token-found-in-the-web-app'
}

# Replace id-of-person with the actual ID
put_url = 'https://your-domain.pipedrive.com/api/v1/persons/id-of-person'

# field_key is the 'key' value of the field that you want to write data to
put_payload = {
    field_key: '2021-06-01' # If this person's trial ends on 2021-06-01
}

put_response = requests.put(put_url, params=token, data=put_payload)

put_content = json.loads(put_response.content)

# The key 'success' should equal True.
print(put_content['success'])
```

The output contains the user that we just wrote data to, including the newly added data. One thing to watch for is that the “success” key will equal True if you manage to write data, regardless of whether the data was correct. If you, for instance, try to write the string “wrong-data” to a date field, the “success” key will equal True and the value of the field will be set to 1970-01-01. You'll want to verify the result of your API request to make sure it’s accurate.
```
# This should equal the value that you just wrote using the PUT request.
print(put_content['data'][field_key])
```

Success! You just wrote your data to a Pipedrive custom field using the Pipedrive API... once.

## There's more to life than writing to custom fields 
It is, in itself, easy enough to write data to a custom field through the Pipedrive API. The real challenge lies in getting this process just right in production. This means scheduling this process to run periodically. This also means making sure that you don't exceed the two-second nor 24-hour rate limits - which also includes any actions that you take in the web app. You’ll also need to incorporate logging so you know exactly which data points were written successfully and which ones failed (and why). Additionally, you'll have to develop a process to retry writing these failed data points - and hope they don't fail again. The list goes on.

You can struggle your way through this process, or you can let Census worry about it. We can take all the engineering for custom connectors off your plate and make it easy to sync your customer data from your warehouse to your business tools. See if we [integrate with your tools](https://www.getcensus.com/integrations) or check out a [demo](https://www.getcensus.com/demo).