Automatically email new leads from a form or popup
When someone fills out a form on your website — a demo request, a newsletter signup, a lead-magnet download — you can have WarmySender add them as a lead AND drop them straight into a cold email campaign, automatically. No spreadsheet exports, no manual copy-paste. This guide shows the simplest way to wire a form or popup to your campaigns.
The One-Call Recipe (Recommended):
A single request creates the lead and enrolls it in your campaign at the same time. This is the same "save lead + add to campaign" action you see in the app, exposed for your form tools.
Step 1 — Create an API key
• Go to Settings > API Keys > Create API Key.
• Give it the 'prospects:write' scope (to create leads) AND the 'enrollments:write' scope (to add them to a campaign). You need both for the one-call recipe.
• Copy the key — it's shown once and starts with ws_. Keep it somewhere safe (a password manager or your automation tool's secret store). Never paste it into public code.
Step 2 — Grab your campaign ID
• Open the campaign you want new leads to flow into. The campaign ID is in the page URL. You'll paste it as enrollInCampaignId below.
Step 3 — Send the request
POST https://warmysender.com/api/v1/prospects
Headers:
Authorization: Bearer ws_YOUR_API_KEY_HERE
Content-Type: application/json
Body:
{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"company": "Acme",
"enrollInCampaignId": "YOUR_CAMPAIGN_ID"
}
Copy-paste curl example:
curl -X POST https://warmysender.com/api/v1/prospects \
-H "Authorization: Bearer ws_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","firstName":"Jane","lastName":"Doe","company":"Acme","enrollInCampaignId":"YOUR_CAMPAIGN_ID"}'
That's it. The lead is saved (201 for a brand-new lead, 200 if that email already existed) and added to your campaign in the same call. The response includes an 'enrollment' object so you can confirm what happened:
{
"data": { "id": "...", "email": "[email protected]", "firstName": "Jane",... },
"alreadyExisted": false,
"enrollment": { "enrolled": true, "enrolledCount": 1, "warnings": [] }
}
Good to know about enrollInCampaignId:
- It's optional. Leave it out and the call simply creates/updates the lead with no campaign step (the response won't include an 'enrollment' object) — perfect if you just want to collect leads now and enroll them later.
- Your lead is always saved, even if the enrollment part can't proceed. If something's off (for example, the key is missing the enrollment permission, or the campaign ID doesn't match one of your campaigns), you still get a saved lead plus a short note in 'enrollment' explaining what to fix — the request never fails outright.
- Re-sending the same email won't create duplicates — leads are matched by email address, so a returning visitor updates the existing record.
The Two-Call Alternative:
Some tools prefer one action per step. You can split it into two requests:
1) Create the lead: POST https://warmysender.com/api/v1/prospects with body { "email": "[email protected]", "firstName": "Jane", "company": "Acme" }. Grab the returned data.id.
2) Enroll it: POST https://warmysender.com/api/v1/campaigns/YOUR_CAMPAIGN_ID/enrollments with body { "prospectIds": ["THE_ID_FROM_STEP_1"] }. You can also enroll by email instead: { "emails": ["[email protected]"] } (this matches leads that already exist in your workspace).
Both requests use the same Authorization: Bearer ws_YOUR_API_KEY_HERE header. The enrollment endpoint needs the 'enrollments:write' scope.
Connecting a Popup or Form (No Code):
Almost any form or popup builder can send a webhook when someone submits. Point that webhook at the one-call recipe above:
• Zapier — Add a 'Webhooks by Zapier' action, choose 'POST', set the URL to https://warmysender.com/api/v1/prospects, add the Authorization and Content-Type headers, and map your form fields (email, firstName, lastName, company) plus a fixed enrollInCampaignId into the JSON body.
• Make — Use the 'HTTP > Make a request' module with method POST, the same URL and headers, and a JSON body mapping your form fields.
• n8n — Use the 'HTTP Request' node (POST), same URL and headers, body mapped from the trigger.
• Any other tool — if it can POST a webhook with custom headers and a JSON body, it works. Tools like Typeform, Webflow, Framer, Tally, and most popup builders can do this directly or through one of the above.
Tip: store your API key in your automation tool's credentials/secret manager rather than typing it into the step, so it's not visible to teammates.
The One Hard Requirement — Set the Campaign to Running:
For emails to actually go out, the campaign you enroll into must be set to Running. New leads added to a draft, paused, or not-yet-started campaign are saved and queued, but no emails send until the campaign is Running. This is by design — it prevents accidental sends from a campaign you're still editing.
If the campaign isn't Running yet, the enrollment still succeeds and the response tells you exactly why nothing will send, in the 'warnings' array. For example:
• Draft campaign → "Lead enrolled, but this campaign is still a draft — no emails will send until you set it to Running."
• Paused campaign → "Lead enrolled, but this campaign is paused — emails resume when you set it back to Running."
• Scheduled campaign → "Lead enrolled. This campaign is scheduled to start later, and emails will begin automatically at its start time."
When the campaign is Running, 'warnings' is empty and your leads are picked up on the next send cycle. A simple pre-launch check: send one test lead and confirm 'enrolled' is true with an empty 'warnings' array.
What to Expect — Paced for Deliverability, Not Instant:
New leads don't get emailed the instant they're captured, and that's a feature, not a delay. WarmySender sends within each campaign's sending window (the hours and days you chose), respects your daily sending limits, and follows your warmup ramp — so your volume stays in a range inbox providers trust. Blasting every new lead the second they sign up is exactly the pattern that lands senders in spam. By pacing sends, WarmySender protects your domain's reputation so more of your emails reach the inbox over the long run. Leads captured outside your sending window simply go out when the next window opens.
Leads that shouldn't be emailed (anyone on your suppression or unsubscribe list, or a hard-bounced address) are automatically skipped — they're still saved, but they won't be contacted. You'll see that reflected in the response counts.
Beyond Cold Email:
This same lead-capture flow feeds your wider outreach. The leads you create can carry a LinkedIn profile URL (add a linkedinUrl field) so they're ready for LinkedIn outreach or multichannel campaigns too, and connected mailboxes stay protected by warmup the whole time. Cold email is the most common use for form-captured leads, so that's the focus here — but the same leads work across cold emailing, LinkedIn outreach, multichannel sequences, and email warmup.
Troubleshooting:
- Lead saved but no email went out → check the campaign is set to Running (not draft or paused) and that the current time falls inside the campaign's sending window. Look at the 'warnings' array in the response for the exact reason.
- Response says the enrollment permission is missing → your API key has 'prospects:write' but not 'enrollments:write'. Add the Campaigns enrollment permission to the key in Settings > API Keys, or create a new key with both.
- Response says the campaign wasn't found → double-check the enrollInCampaignId value matches a campaign in this workspace (copy it again from the campaign's page URL).
- Same person added twice → they won't be; leads are matched by email, so a repeat submission updates the existing lead instead of creating a duplicate.
Related Guides: 'Managing Campaigns via API', 'API Quickstart Tutorial', 'Zapier Integration', 'Make (Integromat) Integration', 'n8n Integration (Self-Hosted)'.