TL;DR: Settings → Destinations → + Connect. Pick the destination, OAuth in, configure scope and defaults. Done — any audience can now push to it.
HubSpot
- Click
+ Connect→ pick HubSpot - OAuth flow → log in to your HubSpot account, authorize Unstuck Engine
- Pick the HubSpot Account to push to (if your HubSpot user has access to multiple)
- Default object — Contact (default), Company, or Deal. Most workspaces use Contact for lead-level pushes
- Default list (optional) — every push lands in a HubSpot list with this name; you can override per audience
- Field mapping defaults — work_email → email, first_name → firstname, etc. Edit the mapping inline
- Test sync — Unstuck pushes a dummy record; you confirm it appeared in HubSpot
Scope requested by Unstuck Engine: contacts.read, contacts.write, lists.write, companies.read, companies.write. No deal write by default — enable separately if you push to Deals.
Salesforce
- Click
+ Connect→ pick Salesforce - OAuth flow → SFDC login, authorize
- Pick the Org (production / sandbox)
- Default object — Lead or Contact. Picking Lead is standard for net-new outbound; Contact for accounts already in your CRM
- Default campaign (optional) — every push lands in this Campaign as a CampaignMember
- Field mapping defaults — same idea, SFDC field names
- Owner assignment — auto-assign to a queue, a specific user, or by round-robin
- Test sync — same dummy-record verification
Scope: api access, contacts/leads read+write, campaigns read+write. Refresh token configured for long-running sync.
Apollo
- Click
+ Connect→ pick Apollo - Apollo doesn't use OAuth — paste your Apollo API key
- Default sequence — every push enrolls members in this sequence
- Mailbox routing — if your Apollo workspace has multiple sending mailboxes, pick the round-robin policy
- Field mapping defaults — usually minimal (email, first_name, last_name, company, title, linkedin_url)
- Test sync — adds a dummy record to a test sequence you verify
Apollo's API rate limits apply — Unstuck Engine respects them and batches sync at rate-limit-friendly intervals.
Smartlead
Same flow as Apollo, with Smartlead's API key. Default sequence is mandatory (a sync target).
Custom webhooks
For anything else (your own internal tool, a custom AI agent, a notification system):
- Click
+ Connect→ pick Custom webhook - Enter your webhook URL
- Set an auth header (e.g.
Authorization: Bearer <your-secret>) - Pick the events to POST —
member_added,member_removed,member_updated, all of the above - Test with a dummy event
Your webhook receives a JSON payload per event. Schema is documented in the Edge Function Contracts spec.
Verifying the connection
Each connected destination has a status indicator on the Destinations page:
- 🟢 Connected & syncing
- 🟡 Connected, no audiences using it
- 🔴 Connection error (OAuth token expired, rate-limited, schema mismatch)
Click into any destination to see the last 10 sync events, success / failure counts, and last error message.
Disconnecting
Settings → Destinations → row → Disconnect. Stops all syncs and revokes the OAuth token. Records already in the destination remain; Unstuck Engine doesn't clean up downstream.