# Nightly HubSpot to OneSignal push audience tag sync

> Every night we copy the customer details that matter onto your push audience, so campaign targeting always matches your CRM instead of stale tags.

- Workflow type: code
- Services: OneSignal, HubSpot, Slack
- Categories: Marketing, Operations
- Published: 2026-08-09

## What it does

- Runs on its own every night and reads your current contact list, so nobody has to maintain push audience tags by hand.
- Copies the details your marketing team actually targets on, such as lifecycle stage, plan or tier, contact owner, and last activity date, onto each matching person in your push tool.
- Clears a tag when the matching CRM field is empty, so people drop out of segments like trial users or dormant accounts as soon as they no longer belong there.
- Posts a one line recap to your team channel each morning showing how many people were updated, skipped, or hit a problem.

## What you'll need

- A HubSpot account containing the contacts you want to target
- A OneSignal app, plus the customer ID you already store on each contact so the two systems can be matched up
- A Slack workspace and a channel where the nightly recap should land
- Contact records filled in with the details you want to target on, for example lifecycle stage or plan

## Prompt

Every night at 2am, keep my OneSignal audience in sync with HubSpot so the marketing team can target push campaigns using current CRM data instead of stale tags. Use a cron trigger. Every step is a fixed field to field mapping over structured records with no judgement calls, so build this as a code workflow.

Start by pulling contacts from HubSpot with the List Contacts operation. Request only the properties that matter for targeting: lifecycle stage, plan or tier, contact owner, last activity date, and the property that stores the person's OneSignal external user id. List Contacts is paginated, so page through every result and keep going until HubSpot stops returning a next page cursor. Do not assume the whole audience fits in one page.

For every contact that carries an external user id, write those values onto the matching OneSignal user with the Edit Tags by External User ID operation. Each HubSpot property maps one to one onto a named OneSignal tag: lifecycle stage to lifecycle_stage, plan or tier to plan, contact owner to owner, and last activity date to last_activity_date. Keep the tag names stable and predictable, because the marketing team's segments are built on top of them.

Two rules drive correctness. First, skip any contact with no external user id, since there is no OneSignal user to write to, and count it as skipped. Second, when a HubSpot property is blank, still send the matching tag with an empty string rather than omitting it. On this operation an empty string deletes the tag, and that is what makes the clean up half of this sync work: someone who drops out of a plan or goes quiet stops matching that segment on the very next run, so nobody is left sitting in a segment they no longer belong to.

Pace the writes, because a nightly full sync over a large contact list will otherwise trip OneSignal's limits. User and subscription writes are capped at 1,000 per second per app, and separately at 1 request per second for any individual user or subscription, so batch the updates and spread them out instead of firing the entire contact list at once. If OneSignal returns a 429, read the Retry-After header, wait that many seconds, then retry with exponential backoff. Treat 400, 401 and 403 as permanent failures for that contact: do not retry them, record the contact as errored, and continue, so one bad record never halts the run.

Finish by posting a one line summary to Slack with the Send a Message operation, reporting how many users were updated, how many were skipped for having no external user id, and how many errored. Send it to the marketing operations channel.

## How to customize

- Change the 2am timing, or run the sync more than once a day if your CRM changes quickly
- Pick exactly which contact details become targeting tags, and what each one is called in your push tool
- Choose the channel that receives the recap, or narrow the sync to a single list of contacts instead of everyone

## Example output

OneSignal audience sync complete: 4,812 users updated, 337 skipped with no linked customer ID, 6 errored.

## FAQ

### What happens to contacts who are not in my push tool yet?

They are skipped and counted in the nightly recap. The sync only updates people it can match to an existing push profile using the customer ID stored on the contact, so nothing is created by accident.

### Will this send anyone a push notification?

No. This workflow only updates the targeting information attached to each person. Your campaigns still send on whatever schedule and rules you already have set up.

### Do I have to rebuild my existing segments?

No. Segments keep working as they are. They read the same tags this sync keeps up to date, so a segment like trial users or active customers simply becomes accurate again after the first run.

### What happens when someone changes plan or goes quiet?

Their tags are overwritten on the next run. If the field is emptied in your CRM, the matching tag is cleared rather than left behind, so they stop matching segments they have outgrown.

### Will this work with a large contact list?

Yes. The sync works through your contacts page by page and paces its updates to stay within your push tool's limits, backing off and retrying if it is asked to slow down.

Use this prompt in General Input: https://www.generalinput.com/prompts/nightly-hubspot-to-onesignal-push-audience-tag-sync