Newsletter
Subscribe readers, list subscribers, and manage newsletter issues via the MisarBlog API.
MisarBlog includes a built-in newsletter system for creators. Readers can subscribe to a creator's newsletter, and creators can view subscribers, export lists, and send issues from the dashboard.
Subscribe to a Newsletter
api.misar.io/blog/newsletter/subscribeSubscribes an email address to a creator's newsletter. A verification email is sent — the subscription is pending until the reader confirms.
This endpoint requires no API key, but it is CSRF-protected and expects a valid CSRF token on the request. It is designed for the MisarBlog first-party subscribe form; cross-origin embedding will fail CSRF validation.
This endpoint is rate-limited to 3 requests per 5 minutes per IP to prevent abuse.
Request body
newsletter_idstringbodyrequiredThe UUID of the creator's newsletter. Find it in your dashboard at misar.blog/dashboard/newsletter.
emailstringbodyrequiredThe reader's email address.
Response fields
successbooleantrue when the subscription was created and a verification email was sent.
{
"newsletter_id": "uuid-of-the-newsletter",
"email": "reader@example.com"
}{ "success": true }{ "success": false, "error": "Invalid email address" }const res = await fetch("https://api.misar.io/blog/newsletter/subscribe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
newsletter_id: "your-newsletter-uuid",
email: "reader@example.com",
}),
});
const data = await res.json();
if (data.success) {
console.log("Check your inbox to confirm!");
}Unsubscribe
api.misar.io/blog/newsletter/unsubscribeUnsubscribes an email from a newsletter using the token included in every outgoing email's unsubscribe link. No authentication required. (The same endpoint also accepts GET /newsletter/unsubscribe?token=... for one-click email links, which redirects to a confirmation page.)
Request body
tokenstringbodyrequiredUnsubscribe token extracted from the ?token= query parameter in the email's unsubscribe link.
Response fields
successbooleantrue when the subscription was cancelled.
{
"token": "signed-unsubscribe-token"
}{ "success": true }List Subscribers
api.misar.io/blog/newsletter/subscribersReturns the authenticated creator's subscriber list.
Session-authenticated
This is a first-party dashboard endpoint. It authenticates with your logged-in MisarBlog session (cookie), not an API key.
Query parameters
limitintegerquerydefault: 50Results per page (clamped to 1–200).
offsetintegerquerydefault: 0Pagination offset.
statusstringqueryFilter by status: pending, active, unsubscribed, bounced.
exportbooleanquerySet true to download a CSV file instead of JSON.
Response fields
subscribersArray<Subscriber>Array of subscriber objects. Each has id, newsletter_id, email, user_id, tier (free | paid), status (pending | active | unsubscribed | bounced), verified_at, unsubscribed_at, and created_at.
totalCountnumberTotal number of subscribers matching the current status filter.
hasMorebooleanWhether more results exist beyond the current page.
{
"subscribers": [
{
"id": "uuid",
"newsletter_id": "uuid",
"email": "reader@example.com",
"user_id": null,
"tier": "free",
"status": "active",
"verified_at": "2026-03-10T08:05:00Z",
"unsubscribed_at": null,
"created_at": "2026-03-10T08:00:00Z"
}
],
"totalCount": 1240,
"hasMore": true
}Content-Type: text/csv
Content-Disposition: attachment; filename=subscribers.csv# List active subscribers
curl "https://api.misar.io/blog/newsletter/subscribers?status=active&limit=100" \
-H "Cookie: <your session cookie>"
# Export all as CSV
curl "https://api.misar.io/blog/newsletter/subscribers?export=true" \
-H "Cookie: <your session cookie>" \
-o subscribers.csvCSV exports are rate-limited to 3 exports per hour to prevent bulk exfiltration.
List Newsletter Issues
api.misar.io/blog/newsletter/issuesReturns the authenticated creator's newsletter issues, ordered by created_at descending.
Session-authenticated
This is a first-party dashboard endpoint. It authenticates with your logged-in MisarBlog session (cookie), not an API key.
Query parameters
limitintegerquerydefault: 20Results per page (clamped to 1–100).
offsetintegerquerydefault: 0Pagination offset.
statusstringqueryFilter by status: draft, scheduled, sending, sent.
Response fields
issuesArray<NewsletterIssue>Array of newsletter issues. Each has id, subject, preview_text, target_tier, status, sent_at, scheduled_at, recipient_count, open_count, click_count, created_at, and updated_at.
totalCountnumberTotal number of issues matching the current filter.
hasMorebooleanWhether more results exist beyond the current page.
{
"issues": [
{
"id": "uuid",
"subject": "Weekly Digest #12",
"preview_text": "This week in review…",
"target_tier": "all",
"status": "sent",
"sent_at": "2026-04-14T09:00:00Z",
"scheduled_at": null,
"recipient_count": 984,
"open_count": 403,
"click_count": 112,
"created_at": "2026-04-13T18:00:00Z",
"updated_at": "2026-04-14T09:00:00Z"
}
],
"totalCount": 12,
"hasMore": false
}curl "https://api.misar.io/blog/newsletter/issues?status=sent" \
-H "Cookie: <your session cookie>"