Integrations
Connect third-party tools over OAuth and send data out via webhooks.
Integrations push SendSets events into the rest of your stack: a reply lands, a meeting is booked, an email bounces, and your CRM, chat channel, or automation tool hears about it.
The Integrations page is a searchable directory with your existing connections along the top. State stays live, so a connection needing reauthorization surfaces without a refresh.
Supported providers
| Provider | Category | Connect | What it does |
|---|---|---|---|
| HubSpot | CRM | one-click OAuth | Create or update a contact, log the reply as a note |
| Salesforce | CRM | one-click OAuth | Upsert a contact on reply or on demand |
| Pipedrive | CRM | one-click OAuth | Upsert a person on reply or on demand |
| Close | CRM | API key | Upsert a lead on reply or on demand |
| Zapier, Make, n8n | Automation | SendSets API key | Fan events to that tool's webhook URL |
| Slack | Notifications | one-click OAuth | Ping a channel on reply, bounce, or deliverability dips |
| Stripe | Payments | Restricted read key and signing secret | Recording preview for signed customer events |
| Discord | Notifications | webhook URL | Ping a server channel on reply, bounce, or warmup health |
| Calendly, Cal.com | Meetings | minted inbound URL | Track booked, rescheduled, and canceled calls |
| MillionVerifier | Verification | API key | Check every contact's address through your pay-as-you-go credits instead of the built-in probe |
| CleanMyList | Verification | API key | Verify contacts using your CleanMyList plan allowance and credits |
Only one Verification connection is active at a time; see one verifier at a time.
Three connect styles appear on the catalog cards: one-click OAuth, api_key for providers without an OAuth app, and webhook for a minted inbound URL or a pasted channel URL.
OAuth providers cannot be connected with a pasted key
You must start the authorize flow; pasting credentials for an OAuth provider is rejected so a token is never stored the wrong way. An expired or revoked token moves the connection to "reconnect required" and one click fixes it.
Automation tools store no secret
Zapier, Make, and n8n connect in one click with nothing stored on the integration. SendSets sends events to the webhook URL you configure there; when they call back into SendSets they use a scoped API key you create.
MillionVerifier is checked before it is saved
The key is tested against your MillionVerifier account when you connect, so a mistyped key is refused rather than silently leaving contacts on the built-in check. From then on every new contact, and every re-verify, spends one credit there. When the balance runs out or the key is revoked, the connection is marked and the built-in check covers until it is fixed. See address verification.
Credentials (OAuth tokens, pasted keys, webhook URLs) are sealed with envelope encryption before touching the database. Only non-secret display details like an account name or Salesforce instance host are stored in the clear, so the dashboard can label the connection.
Record customer Stripe events
Stripe is available as a recording preview on the extended integrations surface. It records verified events; payment reconciliation, historical import, paid-customer conversion, refunds, and MRR reporting are not implemented yet. Operators must enable SENDSETS_ENABLE_EXTENDED_SURFACES=true to expose the existing integration setup routes. This connection is separate from the Stripe account SendSets uses for its own billing.
- Open Integrations → Stripe → Connect. Create a Stripe restricted key with Balance and Events read access. Use
rk_test_for test mode orrk_live_for live mode. Unrestricted secret keys are rejected. SendSets checks both read endpoints without creating or changing anything in Stripe. - Copy the displayed webhook URL after entering the key. In Stripe Workbench, create a snapshot webhook endpoint for Your account, in the same mode. Select
checkout.session.completed,checkout.session.async_payment_succeeded,customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,invoice.paid,refund.created, andrefund.updated. Connect-account events are rejected. - Paste the endpoint's
whsec_signing secret and connect. The key and secret are encrypted with your workspace key. Key validation confirms API access and mode; the signing secret is verified when the first delivery arrives. - Send a test delivery from Stripe. Last sync updates after a signature-verified event is committed to Postgres. It confirms recording, not payment processing. Setup is available again in the connection drawer to replace credentials or connect the other mode.
There is one connection per workspace and mode, labeled Stripe test or Stripe live. Reconnecting replaces its credentials and retains its ID. A repeated connect with the same credentials is naturally safe to retry. Webhook URLs identify the workspace and mode; they carry no secret. Stripe's signature over the original body authenticates each delivery, with the SDK's five-minute timestamp tolerance. Use HTTPS in production.
Each distinct event ID is recorded once per workspace and mode. Deliveries with changed retry metadata are accepted as duplicates; conflicting event content returns 409. Raw payloads are encrypted before storage. A storage or encryption failure returns an error so Stripe can retry. Different event IDs for the same invoice or payment are still separate receipts; object-level deduplication and out-of-order reconciliation are pending. Subscription or trial events do not create paid customers in this preview.
The engagement-event retention window clears encrypted payloads, 365 days by default. Receipt metadata and payload hashes remain for delivery deduplication. Disconnecting removes credentials and stops new ingestion, while retained receipts stay in the workspace. Deleting the workspace removes them. Individual identity erasure for these receipts will be added with payment normalization; the preview has no person linkage yet.
Connections and receipts travel in the Automations export group. A passphrase export re-encrypts credentials and raw payloads for the destination. An export without credentials carries receipt metadata with the encrypted payload omitted. The destination's webhook URL names its new workspace; update the endpoint in Stripe after import. See workspace export and import and Stripe's webhook setup guidance.
Connect CleanMyList
- Verify your account email in CleanMyList, then create a workspace key under App → API keys.
- In SendSets, open Integrations → CleanMyList → Connect and paste the key. SendSets validates it with a free, read-only account request and stores it encrypted.
- New contacts and re-verification requests use CleanMyList. Each address uses one unit of plan allowance first, then credits. Its deliverable, risky, undeliverable, and unknown verdicts map to SendSets's corresponding statuses.
CleanMyList does not expose a balance through its API, so SendSets omits the credit counter. View your allowance and credits in CleanMyList. If verification fails, including an exhausted account, SendSets uses the built-in check. Fix the account or reconnect a revoked key to restore verification.
An account with nothing left is only visible when a check is refused, so SendSets stops checking against it for 15 minutes rather than retrying every address. Topping up takes effect on the next pass after that. See the CleanMyList API documentation and address verification.
One verifier at a time
A workspace uses one verification service. Connecting a second one is refused while the first is connected, because which one ran would otherwise be decided by connection order alone and every check would quietly move to a different bill. Disconnect the current service first, then connect the new one.
CRM field mappings
A mapping decides how a SendSets contact projects onto provider fields. Every connection ships a sensible default:
| Provider | Default mapping |
|---|---|
| HubSpot | email, firstname, lastname, company, phone |
| Salesforce | Email, FirstName, LastName, Phone |
| Pipedrive | name, email, phone (a person) |
| Close | name, email, phone, company (a lead) |
Override per connection: each row pairs a SendSets source field with a destination name and can apply a uppercase, lowercase, or trim transform, or write a fixed static value. Custom contact fields are addressed as custom:your_key, and a static value can include event variables like {{.company}}.
Mappings resolve by specificity: provider defaults, then your connection map, then per-automation overrides, with the most specific winning.
Blank values are not written
Empty values are dropped before the upsert, so a missing first name never blanks an existing one in your CRM.
Webhook delivery
Outbound events are HMAC-SHA256 signed so receivers can verify them. Reveal the connection's whsec_ signing secret in its settings and check the signature header on every request. The signed body carries a stable delivery id, event type, version, timestamp, and full event data.
URLs are validated before storage under the same policy as customer webhooks: the scheme must be https and the host must be publicly routable, with no localhost, loopback, private, or link-local addresses. This blocks requests aimed at internal services. Only development or self-hosted setups can opt out with SENDSETS_ALLOW_UNSAFE_WEBHOOK_URLS=true.
Send a test event
Send test event fires a synthetic payload through the real delivery path, signed exactly like production, so you can verify your signature check first. CRM upserts are skipped during a test, so nothing junk lands in your CRM.
Inbound webhooks work the other way: Calendly and Cal.com call into a URL SendSets mints for you, landing booked, rescheduled, and canceled calls on the contact timeline in real time. Rotate the secret from connection settings if exposed.
Feeding automations
Integrations are most useful as the actions at the end of an automation: post to Slack or Discord, upsert into a CRM, or fan out to Zapier, Make, n8n, or any signed webhook.
The most actionable events are available as triggers: reply received (with intent), contact created, form submitted, email bounced, unsubscribed, meeting booked, rescheduled, or canceled, warmup health changed, and deliverability complaint.
Data flows in as well as out. An automation's inbound webhook URL plus its Create or update contact action turns any push (a lead-form connector in Zapier, Make or n8n, a form tool's webhook, your own code) into a tagged, campaign-enrolled contact. See Lead intake.
Actions run in the background, so a slow third party never blocks the event that triggered it. Failures are recorded against the connection's health and visible in its recent activity rather than retried forever or silently lost.
You can filter when an action runs, commonly firing only on a positive reply or above a minimum classifier confidence. Beyond events, you can push a batch of contacts into a connected CRM on demand, with each record reporting its own result.
