Build a HubSpot Deal Data API with Python and Flask
!["HubSpot Deal Assoications" title with Replit and HubSpot logos in bottom-right corner](https://cdn.sanity.io/images/bj34pdbp/migration/b90e21aeea292cc25b970472f0ea7b1617038e11-2400x1350.jpg?w=1600&q=60&fit=clip&auto=format)
Introduction #
HubSpot is one of the leading CRMs used by companies of all sizes. HubSpot's API is great for pulling data for deals, contacts, and companies in your CRM. These associates can be visible within HubSpot but sometimes, you need to interact with this data programmatically with the associations merged in a clean, readable format.
This guide and the provided templates will show you how to fetch deals from HubSpot along with their associated contacts, companies, and owners, while respecting HubSpot's API rate limits. Once you get this associated data, you’ll be able to deploy this custom API as your own API for your team to use.
Using our templates, you can have your internal HubSpot Deals API up and running in 5 minutes or less.
Getting started #
This guide comes with two sections:
- Creating the simple data aggregation script. Full code for this project here.
- Converting this script into an internal API. Full code for this project here.
For either template, click "Use template" and name your project however you like.
Create a Private app in HubSpot
Log in to your HubSpot account and navigate to Settings > Integrations > Private Apps
![HubSpot Private apps creation UI - 2024-06-28](https://cdn.sanity.io/images/bj34pdbp/migration/f3079dfe5befcd53407a1e0626f144b11e48da53-2302x752.png?w=1600&q=60&fit=clip&auto=format)
Click "Create a private app” and set a name for your app.
![HubSpot Private app naming UI - 2024-06-24](https://cdn.sanity.io/images/bj34pdbp/migration/b20f78101da0a3b2e6cb4f8ed740f0f00a89955d-2944x1238.png?w=1600&q=60&fit=clip&auto=format)
Set the necessary scopes (you'll need access to deals, contacts, companies, and owners).
![HubSpot Private app scopes UI](https://cdn.sanity.io/images/bj34pdbp/migration/40e3bbe0ad7c95efa0caf4f5124e633de1d97851-2560x1286.png?w=1600&q=60&fit=clip&auto=format)
Once your scopes are set, click Create app. You'll receive a private app access token.
To keep this secret safe, add it to the Secrets tab in your Repl. In the bottom-left corner of the Replit workspace, there is a section called "Tools."
Select "Secrets" within the Tools pane, and add your Private App access token to the Secret labeled HUBSPOT_ACCESS_TOKEN.
![Replit Secrets UI adding a HUBSPOT_ACCESS_TOKEN](https://cdn.sanity.io/images/bj34pdbp/migration/ad9fd82556f12a9a2c93280e54ef563fe5daf0ef-1390x470.png?w=1600&q=60&fit=clip&auto=format)
Setting up the HubSpot client and rate limiting #
Let's start by setting up our HubSpot client and implementing a rate limiting system that keeps our API calls within HubSpots rate limit of 10 calls per second:
In Replit, os.environ['HUBSPOT_ACCESS_TOKEN'] will automatically fetch the token we stored in the Secrets tab.
Fetching deals #
Now let's create a function to fetch deals:
This function fetches 25 deals, processes each one, and then prints the results using simplejson for better handling of complex data types. If you would like to pull more deals from your HubSpot CRM, simply increase the limit parameter in this line:
deals_page = hubspot_client.crm.deals.basic_api.get_page(limit=25)
Processing deals and fetching associated data #
Let's create a function to process each deal and fetch its associated data:
Tip: If you want a deeper explanation of what a certain section of code does in your project, simply highlight the lines in question, right click, and select “Explain with AI”.
Running the script #
To run our script, we add this at the end of the file:
Once that’s in, hit the Run button in your Repl, if all is set up correctly, you will see your data appear in the Console. From here you can ask Replit AI to turn the results into a CSV, txt file, or continue adding more functionality once you receive your aggregated Deals data.
If you’d like to turn this into an internal API that the rest of your team can use, read on!
Converting your script into an API #
To make your HubSpot deal data aggregator more accessible to your team, let's convert it into a Flask API. This will allow other members of your organization to request deal data programmatically.
Setting up Flask #
Let’s modify our script to convert it into a Flask application. At the bottom of main.py replace the fetch_deals_with_associations() function with the following:
Add these imports at the top:
Your final main.py file should be:
Hit the Run button again. If everything is set up correctly, you should get the Webview tab to appear like this:
![Replit WebView with title "Not Found"](https://cdn.sanity.io/images/bj34pdbp/migration/38016fc69f697f726b60ead9984f12d7a70c6171-551x458.png?w=1600&q=60&fit=clip&auto=format)
Securing your API #
Next, we want to be sure that only members of our team will be able to send requests to our new API. Here’s how we can set up an internal key.
First, head to your Secrets tab again and add a new key called INTERNAL_API_KEY. For your value, add any password or secret string you like. Ideally, you should generate a 15-20 character string with a mix of numbers, letters, and symbols. Paste this in as your value.
You can store this value in a secure password manager like 1Password to share with the rest of your team.
Testing your API #
Once your Flask app is running, it will automatically have its own development environment URL. To find it, click on the Webview URL preview it should show a pop up like this:
![Replit development environment url pop up](https://cdn.sanity.io/images/bj34pdbp/migration/ac5dff0361c4588c8a2933d3c5a75775ff98b04d-607x479.png?w=1600&q=60&fit=clip&auto=format)
You can also find your development URL by typing ⌘ + K (or Ctrl + K) and typing "networking". Copy this URL to your clipboard.
![Replit networking tab](https://cdn.sanity.io/images/bj34pdbp/migration/ac65d57110b9a4084970814c0d9c6c1fac22c170-728x471.png?w=1600&q=60&fit=clip&auto=format)
Then, open the Shell and enter the following command. Replace YOUR_INTERNAL_API_KEY with the value in your Secrets and YOUR_DEV_URL with the URL copied from the Webview or Networking tab.
Deploying your API #
Open a new tab in the Workspace and search for “Deployments” or open the control console by typing ⌘ + K (or Ctrl + K) and type "deploy". You should find a screen like this.
![Replit Deployments selection UI](https://cdn.sanity.io/images/bj34pdbp/migration/380de4cfa1e19deeef83bf29e56748bad1b9dec4-1414x1023.png?w=1600&q=60&fit=clip&auto=format)
For APIs like this, we recommend using Autoscale. Click on Set up your deployment to continue. On the next screen, click Approve and configure build settings most internal APIs work fine with the default machine settings but if you need more power later, you can always come back and change these settings later. You can monitor your usage and billing at any time at: replit.com/usage.
On the next screen, you’ll be able to set your primary domain and edit the Secrets that will be in your production deployment. Usually, we keep these settings as they are.
Finally, click Deploy and watch your API go live!
If your deployment succeeds, you now have a production URL and /get-deals-with-associations endpoint for the rest of your team to pull clean, readable data directly from your HubSpot CRM.
Conclusion #
You've now created a Flask API in Replit that fetches deals from HubSpot along with their associated contacts, companies, and owners. You can now integrate this API and data into other internal tools (e.g. Salesforce or Google Sheets).
This API respects HubSpot's rate limit of 10 requests per second limits, provides a comprehensive view of your deal data, and offers a secure way for your team to access this data programmatically.