How to schedule an automatic HubSpot export to CSV
Many teams want a weekly CSV of their HubSpot contacts and deals, as a backup or for reporting, without anyone having to remember to do it. This page explains what HubSpot does natively and how to build the automation yourself.
What HubSpot does natively
Manual record exports. From any contacts or deals view you can click Export and get a CSV or Excel file by email (HubSpot: Export your records). The export includes current property values and associations, and you need export permissions. Someone has to start it each time.
Scheduled dashboard emails. HubSpot can email dashboards on a daily, weekly or monthly schedule. That gives you a recurring report, not a raw record file.
Scheduled record exports. I could not find HubSpot documentation of a built-in recurring export for record views. A HubSpot Community thread asks for exactly this feature. Some third-party articles say recurring exports exist, so check the export settings in your own account in case your plan offers something newer. If it doesn't, use the method below.
Build it: Exports API + a scheduler
HubSpot's CRM Exports API runs the same export as the button, for a view or a list, from code.
1. Create credentials
Create a private app (or an OAuth app) in HubSpot with the crm.export scope. HubSpot's guide notes that with OAuth, the installing user must be a Super Admin to grant this scope. Store the token as a secret, never in the script itself.
2. Start an export
Send a POST to /crm/v3/exports/export/async. A typical request body looks like this (check field names against the current guide):
`json
{
"exportType": "VIEW",
"exportName": "weekly-contacts",
"format": "CSV",
"language": "EN",
"objectType": "CONTACT",
"objectProperties": ["email", "firstname", "lastname", "lifecyclestage", "hubspot_owner_id"]
}
`
Use "objectType": "DEAL" with properties like dealname, dealstage, amount and closedate for deals. List the properties explicitly. That keeps the columns the same every week and the file small.
3. Poll and download
The POST returns a task ID. Check the task's status with a GET until it finishes, then download the file from the result link. In Python:
`python
import os, time, requests, datetime
H = {"Authorization": f"Bearer {os.environ['HUBSPOT_TOKEN']}"}
API = "https://api.hubapi.com/crm/v3/exports/export/async"
body = {"exportType":"VIEW","exportName":"weekly-contacts","format":"CSV",
"language":"EN","objectType":"CONTACT",
"objectProperties":["email","firstname","lastname","lifecyclestage"]}
task = requests.post(API, json=body, headers=H).json()["id"]
while True:
s = requests.get(f"{API}/tasks/{task}/status", headers=H).json()
if s["status"] == "COMPLETE":
break
time.sleep(10)
data = requests.get(s["result"]).content
open(f"hubspot-contacts-{datetime.date.today()}.zip", "wb").write(data)
`
The download may come as a zip, depending on the export. Unzip it in the script if you want the CSV directly.
4. Schedule it
- cron:
0 6 * * 1 /usr/bin/python3 /opt/exports/hubspot_export.pyruns it every Monday at 06:00. - Windows Task Scheduler: create a weekly trigger that runs the script.
- GitHub Actions: a workflow with
on: schedule: - cron: "0 6 * * 1"and the token stored in repository secrets.
5. Deliver it
Save the file into a folder synced to Google Drive or Dropbox, or upload it with that service's API. Put the date in the filename so older weeks are never overwritten.
Pitfalls
- Permissions. Exports fail without export rights, and with OAuth the scope needs a Super Admin.
- Silent failures. An expired or revoked token stops the job without any warning. Send yourself an alert when a run fails or no new file appears.
- Property names vs. labels. The API uses internal names (
lifecyclestage) while the UI shows labels ("Lifecycle Stage"). Keep this in mind if you compare against manual exports. - All properties. Exporting every property produces very wide files that change whenever someone adds a field. Pick a fixed list.
- Personal data. Contact exports contain personal data. Store them in an access-controlled location and decide how long you keep them.
Where Sundayfile fits
We make Sundayfile. It does not run scheduled exports or connect to HubSpot. If you already have HubSpot contacts or deals CSVs, whether from the Export button or from a script like this one, you can drop them in. It detects the export type, maps common column names to one fixed layout, keeps a profile for each client and gives you a clean client-type-date.csv. Your files then have the same columns every time, even when the raw exports differ.