Weekly HubSpot CRM backup with automatic 90-day cleanup

Every Sunday night your contacts, companies and deals are exported to a dated folder you control, and copies older than 90 days are cleaned up for you.

Deterministic Code
HubSpotGeneral Input StorageSlack BotOperationsSalesData SyncNotifications & Alerts
PromptCreate

Every Sunday at 2am, back up my HubSpot CRM into General Input Storage so I have a durable point in time copy that I control. Use a cron trigger.

Put the settings at the very top of the workflow as named constants so they are obvious and easy to change: RETENTION_DAYS = 90, OBJECT_TYPES = ["contacts", "companies", "deals"], BACKUP_PREFIX = "hubspot-backup", and SLACK_CHANNEL for the channel that gets the summary. Everything downstream reads from these, so dropping "deals" from OBJECT_TYPES or moving retention to 30 days should be a one line edit and nothing else.

For each object type in the list, page through the entire object set using HubSpot's List Contacts, List Companies, and List Deals operations. Request 100 records per page, which is the maximum for the CRM v3 list endpoints, and follow the cursor at paging.next.after until it is absent. Do not use the search endpoints for this: they cap at 10,000 total results, and a backup has to include everything. Ask for an explicit property list per object type rather than the default handful, so the export captures the fields people actually rely on.

Write each object type to its own CSV. Put the record id in the first column, followed by one column per property. Union the property keys across every record of that type first, so a record that is missing a property still lines up with the header row. Quote any field containing a comma, a quote, or a newline, since CRM notes and addresses routinely contain all three.

Upload each CSV to General Input Storage using Presign Upload, under a timestamped key like hubspot-backup/2026-08-30/contacts.csv built from the run date. Keys are store relative paths with forward slashes and no leading slash, and there are no real folders, so the date segment is what creates the grouping. Pass the true byte length as sizeBytes, since that is what the quota check uses, then PUT the bytes to the returned URL with the headers it returns and Content-Type text/csv. Presigned URLs are valid for 15 minutes, so mint one per file at the moment you upload that file, and never store or reuse one.

Only after every upload in this run has succeeded, prune old backups. Call List Objects with the BACKUP_PREFIX prefix, paging through the cursor, and parse the date segment out of each returned key. Group keys by that date, and for any date older than RETENTION_DAYS, remove every object under it with Delete Object. Delete Object is idempotent, so a key that is already gone is not a failure. If any upload failed, skip the prune entirely and say so in the Slack message: deleting the only good copies right after a failed backup is the one outcome that must never happen.

Finish by posting to the channel in SLACK_CHANNEL with the Slack Bot Send a Message operation. Include the row count for each CSV, the size of each file and the total size of the snapshot, the full prefix the snapshot was written to, and which old backup dates were removed along with how many objects that covered. If nothing was old enough to prune, say that explicitly rather than staying silent, so a quiet week still looks different from a broken workflow.

For reliability: if a HubSpot page fails, retry it a few times with a backoff, and respect the Retry-After header on a 429 rather than hammering the API. If an object type cannot be exported completely, do not upload a partial CSV under a name that looks complete. Report that type as failed in the Slack message and leave the existing backups untouched.

What does this prompt do?

  • Exports every contact, company and deal from your HubSpot account once a week, with no record limit and nothing left behind on page two
  • Saves each object type as its own spreadsheet-friendly CSV file in a dated folder, so you can always go back to how your CRM looked on a specific Sunday
  • Deletes backup folders older than your chosen retention window, so storage does not grow forever without anyone watching it
  • Posts a Slack summary with the number of records in each file, the total size of the snapshot, and exactly which old backups were removed
  • Never prunes anything if the export failed, so a bad run can never delete your only good copies

What do I need to use this?

  • A HubSpot account with permission to view contacts, companies and deals
  • General Input Storage, which is included and needs no separate signup
  • A Slack workspace and a channel where the weekly summary should be posted

How can I customize it?

  • Change the retention window from 90 days to whatever your policy requires, or set it long enough that nothing is ever deleted
  • Add or remove object types if you only care about deals, or want tickets and companies handled differently
  • Move the run to a different day or hour, and point the summary at a different Slack channel

FAQs

Does this work on HubSpot Free?
Yes. Reading your contacts, companies and deals is available on every HubSpot tier including Free, so the backup runs the same way whether you are on Free or Enterprise.
Where do the files actually go, and can I get them out?
They go into General Input Storage, which is included with your account. Each file is a plain CSV in a folder named for the date it ran, so you can download any of them and open them in Excel or Google Sheets, or re-import them into HubSpot.
What happens if the backup fails halfway through?
The cleanup step is skipped entirely and the Slack message tells you which part failed. Old backups are only ever deleted after a complete, successful export, so a failed run can never leave you with nothing.
Will this slow down or affect my HubSpot account?
No. It only reads data and never changes a record. It runs in the middle of the night and paces its requests to stay inside HubSpot's limits.
How much storage will a year of backups use?
Far less than most people expect, because CSV text compresses well and old snapshots are pruned automatically. With the default 90 day window you are only ever holding about thirteen weekly copies at a time.
Can I keep a copy forever instead of deleting old ones?
Yes. Set the retention window to a very large number and nothing will ever be removed, or raise it to match whatever your compliance policy requires.

Related templates

A brand asset library your marketing team actually searches

Every logo, photo, video cut and ad export in one searchable grid, with previews, campaign tags and rights expiry dates at a glance.

General Input Storage
General Input Database
JigsawStack
+1
App
Turn Mailjet email clicks into ranked HubSpot follow-ups

Twice a day we spot the people clicking your pricing and demo pages, create a follow-up task for their owner, and post a ranked recap to Slack.

Mailjet
HubSpot
Slack Bot
Agentic Task
Clean out the Looker dashboards and Looks nobody opens

One board showing every dashboard and Look with its folder, owner and favorite count, so you can find dead content and retire it safely.

Looker
Slack Bot
App
LiveKit live operations console for room moderation

Watch every live room on one screen, remove disruptive guests, start recordings and end stuck sessions without anyone opening a terminal.

LiveKit
Slack Bot
General Input Database
App
Wake up dormant Keap leads with a researched reason

Every Monday we find leads who never bought, research a real reason to reach out, and send a short personal email instead of another check in.

Keap
Slack Bot
Agentic Task
iMessage campaign console with pre-flight checks and delivery board

Build every text campaign in one screen: check who is actually reachable, see a realistic send plan, then watch delivery land row by row.

LoopMessage
Google Sheets
HubSpot
App

Your CRM is your business. Keep a copy you actually control.

Set this up once and every Sunday night you get a fresh, dated snapshot of your entire HubSpot database, with old copies cleaned up automatically.