How-to
Subscribe URL
Every audience has a hosted subscribe URL that adds people without an API key. Learn the request format, how to call it safely, its limits and how to reset it.
Each audience has a subscribe URL: a public endpoint that adds a person to the audience without an API key. Use it to connect a sign-up form on your site, or a no-code tool that can send a JSON request, to an audience.
POST https://api.emailit.com/subscribe/{token}The token is secret to the audience. Anyone who has the URL can add addresses to the audience, so treat it like a password.
Find the URL
-
Open the audience. Go to Email MarketingAudiences and select the audience.
-
Copy the URL. Select Subscribe URL and copy the URL from the dialog.
With the API, Retrieve an audience returns the same value in token.
Request format
Send a POST request with a JSON body and Content-Type: application/json. No Authorization header is needed.
emailstringrequiredfirst_namestringlast_namestringcustom_fieldsobjectThe endpoint only reads JSON. Form-encoded bodies, which a plain HTML <form> sends, are rejected with 400 and “Invalid JSON in request body”.
Responses
| Status | Body | When |
|---|---|---|
200 |
{ "message": "Subscribed successfully" } |
The person was added, resubscribed or was already subscribed. |
400 |
{ "error": "Missing required field: email" } or { "error": "Invalid email format" } |
The email is missing or malformed, or the body isn’t JSON. |
404 |
{ "error": "Audience not found" } |
The token is wrong or was reset. |
422 |
{ "error": "...", "usage": { ... } } |
The audience reached its subscriber limit. |
429 |
More than 30 requests in a minute from the same IP address. |
What a sign-up does
- New address: Emailit creates the contact and subscribes it to the audience.
- Existing contact, not on the audience: Emailit updates the names and custom fields you sent and subscribes the contact.
- Existing subscriber who had unsubscribed: Emailit subscribes them again.
- Existing subscriber who is subscribed: nothing changes except the subscription date, and the response is still
200.
Sign-ups through the subscribe URL don’t send subscriber.* or contact.* webhook events and don’t start Added to audience automations. They also don’t change a contact’s marketing status: if the contact was globally unsubscribed, campaigns keep skipping it until you resubscribe it on the Contacts list.
Connect a sign-up form
The subscribe URL has no bot protection, and it only accepts JSON. The safest setup is to post your form to your own server, check it there, and call the subscribe URL from the server. That keeps the token out of your page source and lets you block spam before it reaches your audience.
-
Add the form to your page. Post it to an endpoint on your own site. The hidden
websitefield is a honeypot: people don’t see it, but bots often fill it in.<form id="signup" method="post" action="/newsletter"> <label for="email">Email</label> <input id="email" name="email" type="email" required> <label for="first_name">First name</label> <input id="first_name" name="first_name" type="text"> <!-- Honeypot: hidden from people, often filled in by bots --> <div style="position:absolute;left:-10000px" aria-hidden="true"> <input name="website" type="text" tabindex="-1" autocomplete="off"> </div> <button type="submit">Subscribe</button> <p class="status" role="status"></p> </form> -
Handle the form on your server. Drop honeypot hits, check a CAPTCHA if you use one, then forward the fields to the subscribe URL as JSON. Keep the token in an environment variable such as
EMAILIT_SUBSCRIBE_TOKEN. See the server examples below. -
Test it. Submit the form with your own address and check that you appear in the audience’s subscribers table.
Server examples
import express from 'express';
const app = express();
app.post('/newsletter', express.urlencoded({ extended: false }), async (req, res) => {
// Bots fill in the honeypot. Pretend it worked and stop.
if (req.body.website) return res.redirect(303, '/thanks');
const response = await fetch(
`https://api.emailit.com/subscribe/${process.env.EMAILIT_SUBSCRIBE_TOKEN}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: req.body.email,
first_name: req.body.first_name || undefined,
}),
},
);
if (!response.ok) {
const { error } = await response.json().catch(() => ({}));
return res.status(response.status).send(error || 'Could not subscribe.');
}
res.redirect(303, '/thanks');
});
app.listen(3000);<?php
// Bots fill in the honeypot. Pretend it worked and stop.
if (!empty($_POST['website'])) {
header('Location: /thanks', true, 303);
exit;
}
$token = getenv('EMAILIT_SUBSCRIBE_TOKEN');
$ch = curl_init("https://api.emailit.com/subscribe/{$token}");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'email' => $_POST['email'] ?? '',
'first_name' => $_POST['first_name'] ?? null,
]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
http_response_code($status);
echo json_decode($body, true)['error'] ?? 'Could not subscribe.';
exit;
}
header('Location: /thanks', true, 303);curl "https://api.emailit.com/subscribe/$EMAILIT_SUBSCRIBE_TOKEN" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "email": "ada@example.com", "first_name": "Ada" }'If your page submits with JavaScript instead of a full page load, call your own endpoint with fetch and keep the Emailit call on the server:
document.querySelector('#signup').addEventListener('submit', async (event) => {
event.preventDefault();
const form = new FormData(event.target);
const response = await fetch('/newsletter', { method: 'POST', body: new URLSearchParams(form) });
event.target.querySelector('.status').textContent = response.ok
? 'Thanks, you are subscribed.'
: 'Something went wrong. Please try again.';
});Rate limit and higher volumes
The subscribe URL accepts 30 requests per minute from each IP address and returns 429 above that. When your server forwards every sign-up, they all come from your server’s IP, so the 30 per minute apply to your whole site. If you expect more, call Add a subscriber from your server with an API key instead. That endpoint also returns 409 for people who are already subscribed and starts Added to audience automations, for example to send a welcome email.
Confirm sign-ups
The subscribe URL adds people immediately. Emailit doesn’t send a confirmation email or ask the person to confirm their address (double opt-in).
If you want confirmed sign-ups, build the confirmation into your own flow: when someone submits the form, store the request on your server and send them an email with a confirmation link that points back to your site. Call the subscribe URL only after they open that link.
Reset the URL
Reset the token if the URL leaked or you’re getting spam sign-ups. The old URL stops working immediately and returns 404.
-
Open the dialog. On the audience page, select Subscribe URL.
-
Reset. Select Reset token and confirm. Emailit generates a new URL.
-
Update your integrations. Replace the token everywhere you use it, such as the
EMAILIT_SUBSCRIBE_TOKENvariable on your server.
Resetting the token is only available in the dashboard.