API Reference

Complete endpoint reference for the SentinMail REST API with examples in cURL, JavaScript, and Python

Overview

This is a complete reference of all SentinMail API endpoints. For getting-started guides, see Authentication, Sending Emails, and Newsletter Subscriptions.

Base URL: https://api.sentinmail.app

Authentication: All endpoints require an X-API-Key header unless marked as Public.

Machine-readable spec: OpenAPI 3.0 (YAML)


Sending Emails

POST /api/emails/send/to-list/

Send a saved template to all subscribers in a list. Supports scheduling.

Info
All send endpoints are asynchronous — they return a campaign object immediately and process emails in the background via workers.
Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/send/to-list/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "March Newsletter",
6 "template_id": "TEMPLATE_UUID",
7 "smtp_config_id": "SMTP_CONFIG_UUID",
8 "list_id": "LIST_UUID"
9 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/send/to-list/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'March Newsletter',
9 template_id: 'TEMPLATE_UUID',
10 smtp_config_id: 'SMTP_CONFIG_UUID',
11 list_id: 'LIST_UUID',
12 }),
13});
14const campaign = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/send/to-list/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={
7 'name': 'March Newsletter',
8 'template_id': 'TEMPLATE_UUID',
9 'smtp_config_id': 'SMTP_CONFIG_UUID',
10 'list_id': 'LIST_UUID',
11 },
12)
13campaign = response.json()
FieldTypeRequiredDescription
namestringYesCampaign name (max 255)
template_idUUIDYesTemplate to send
smtp_config_idUUIDYesSMTP config to use
list_idUUIDYesTarget subscriber list
scheduled_forISO-8601NoSchedule delivery (null = now)
attachment_idsUUID[]NoMedia file attachments

POST /api/emails/send/to-receivers/

Send a saved template to specific recipients with per-recipient personalization.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/send/to-receivers/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Renewal Reminder",
6 "template_id": "TEMPLATE_UUID",
7 "smtp_config_id": "SMTP_CONFIG_UUID",
8 "receivers": [
9 {"email": "john@example.com", "first_name": "John", "plan": "Pro"},
10 {"email": "jane@example.com", "first_name": "Jane", "plan": "Enterprise"}
11 ]
12 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/send/to-receivers/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'Renewal Reminder',
9 template_id: 'TEMPLATE_UUID',
10 smtp_config_id: 'SMTP_CONFIG_UUID',
11 receivers: [
12 { email: 'john@example.com', first_name: 'John', plan: 'Pro' },
13 { email: 'jane@example.com', first_name: 'Jane', plan: 'Enterprise' },
14 ],
15 }),
16});
17const campaign = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/send/to-receivers/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={
7 'name': 'Renewal Reminder',
8 'template_id': 'TEMPLATE_UUID',
9 'smtp_config_id': 'SMTP_CONFIG_UUID',
10 'receivers': [
11 {'email': 'john@example.com', 'first_name': 'John', 'plan': 'Pro'},
12 {'email': 'jane@example.com', 'first_name': 'Jane', 'plan': 'Enterprise'},
13 ],
14 },
15)
16campaign = response.json()
FieldTypeRequiredDescription
namestringYesCampaign name
template_idUUIDYesTemplate to send
smtp_config_idUUIDYesSMTP config to use
receiversobject[]YesRecipients (each must have email)
scheduled_forISO-8601NoSchedule delivery
attachment_idsUUID[]NoMedia file attachments

Receiver object: Any field beyond email becomes a [[variable]] template variable. Optional cc and bcc arrays are supported.


POST /api/emails/send/custom/

Send custom subject + HTML body without a saved template. Best for transactional emails.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/send/custom/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Order Confirmation",
6 "smtp_config_id": "SMTP_CONFIG_UUID",
7 "subject": "Order #[[order_id]] confirmed, [[first_name]]!",
8 "body": "<h1>Thanks, [[first_name]]!</h1><p>Order #[[order_id]] for [[product]] is confirmed. Total: $[[total]]</p>",
9 "receivers": [
10 {
11 "email": "john@example.com",
12 "first_name": "John",
13 "order_id": "12345",
14 "product": "Wireless Headphones",
15 "total": "79.99"
16 }
17 ]
18 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/send/custom/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'Order Confirmation',
9 smtp_config_id: 'SMTP_CONFIG_UUID',
10 subject: 'Order #[[order_id]] confirmed, [[first_name]]!',
11 body: '<h1>Thanks, [[first_name]]!</h1><p>Order #[[order_id]] confirmed.</p>',
12 receivers: [{
13 email: 'john@example.com',
14 first_name: 'John',
15 order_id: '12345',
16 product: 'Wireless Headphones',
17 total: '79.99',
18 }],
19 }),
20});
21const campaign = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/send/custom/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={
7 'name': 'Order Confirmation',
8 'smtp_config_id': 'SMTP_CONFIG_UUID',
9 'subject': 'Order #[[order_id]] confirmed, [[first_name]]!',
10 'body': '<h1>Thanks!</h1><p>Order #[[order_id]] confirmed.</p>',
11 'receivers': [{
12 'email': 'john@example.com',
13 'first_name': 'John',
14 'order_id': '12345',
15 'product': 'Wireless Headphones',
16 'total': '79.99',
17 }],
18 },
19)
20campaign = response.json()
FieldTypeRequiredDescription
namestringYesCampaign name
smtp_config_idUUIDYesSMTP config to use
subjectstringYesSubject line (supports [[variables]])
bodystringYesHTML body (supports [[variables]])
receiversobject[]YesRecipients
attachment_idsUUID[]NoMedia file attachments

Subscribers

POST /api/emails/subscribers/

Add a subscriber.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/subscribers/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{"email": "newuser@example.com", "first_name": "Jane", "last_name": "Doe"}'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/subscribers/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 email: 'newuser@example.com',
9 first_name: 'Jane',
10 last_name: 'Doe',
11 }),
12});
13const subscriber = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/subscribers/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={'email': 'newuser@example.com', 'first_name': 'Jane', 'last_name': 'Doe'},
7)
8subscriber = response.json()

GET /api/emails/subscribers/

List subscribers. Supports ?search=, ?ordering=, ?page=.

GET /api/emails/subscribers/{id}/

Get a single subscriber.

PATCH /api/emails/subscribers/{id}/

Update subscriber fields.

DELETE /api/emails/subscribers/{id}/

Permanently delete a subscriber.

POST /api/emails/subscribers/bulk/

Bulk import from CSV. Send as multipart/form-data with a file field.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/subscribers/bulk/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -F "file=@subscribers.csv"

CSV format: email,first_name,last_name

POST /api/emails/subscribers/bulk-delete/

Delete multiple subscribers by ID.

Code
json
1{ "subscriber_ids": ["UUID_1", "UUID_2"] }

POST /api/emails/subscribers/bulk-update-lists/

Add or remove subscribers from lists in bulk.

Code
json
1{
2 "subscriber_ids": ["SUB_ID_1", "SUB_ID_2"],
3 "add_to_lists": ["LIST_ID"],
4 "remove_from_lists": []
5}

GET /api/emails/subscribers/export/

Export all subscribers as a CSV file download.


Subscriber Lists

POST /api/emails/lists/

Create a subscriber list.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/lists/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{"name": "Weekly Newsletter", "description": "Weekly product updates"}'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/lists/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'Weekly Newsletter',
9 description: 'Weekly product updates',
10 }),
11});
12const list = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/lists/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={'name': 'Weekly Newsletter', 'description': 'Weekly product updates'},
7)
8list_data = response.json()

GET /api/emails/lists/

List all subscriber lists.

GET /api/emails/lists/{id}/

Get list details.

PATCH /api/emails/lists/{id}/

Update list name or description.

DELETE /api/emails/lists/{id}/

Delete a list.


Email Templates

POST /api/emails/templates/

Create an email template.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/templates/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Welcome Email",
6 "subject": "Welcome, [[first_name]]!",
7 "body": "<h1>Welcome!</h1><p>Thanks for joining, [[first_name]].</p>",
8 "template_mode": "basic",
9 "template_type": "marketing"
10 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/templates/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'Welcome Email',
9 subject: 'Welcome, [[first_name]]!',
10 body: '<h1>Welcome!</h1><p>Thanks for joining, [[first_name]].</p>',
11 template_mode: 'basic',
12 template_type: 'marketing',
13 }),
14});
15const template = await response.json();
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/templates/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={
7 'name': 'Welcome Email',
8 'subject': 'Welcome, [[first_name]]!',
9 'body': '<h1>Welcome!</h1><p>Thanks for joining, [[first_name]].</p>',
10 'template_mode': 'basic',
11 'template_type': 'marketing',
12 },
13)
14template = response.json()
FieldTypeRequiredDescription
namestringYesTemplate name
subjectstringYesSubject line (supports [[variables]])
bodystringNoHTML body
template_modestringNobasic or visual
template_typestringNomarketing or transactional

GET /api/emails/templates/

List templates.

GET /api/emails/templates/{id}/

Get template details.

PATCH /api/emails/templates/{id}/

Update a template.

DELETE /api/emails/templates/{id}/

Delete a template.


SMTP Configuration

POST /api/emails/smtp-configs/

Add an SMTP server configuration.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/smtp-configs/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Production SES",
6 "host": "email-smtp.us-east-1.amazonaws.com",
7 "port": 587,
8 "username": "AKIAIOSFODNN7EXAMPLE",
9 "password": "YOUR_SMTP_PASSWORD",
10 "use_tls": true,
11 "sender_name": "My App",
12 "sender_email": "hello@myapp.com"
13 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/smtp-configs/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 name: 'Production SES',
9 host: 'email-smtp.us-east-1.amazonaws.com',
10 port: 587,
11 username: process.env.SES_USERNAME,
12 password: process.env.SES_PASSWORD,
13 use_tls: true,
14 sender_name: 'My App',
15 sender_email: 'hello@myapp.com',
16 }),
17});
18const smtpConfig = await response.json();
Code
python
1import os
2import requests
3 
4response = requests.post(
5 'https://api.sentinmail.app/api/emails/smtp-configs/',
6 headers={'X-API-Key': 'fm_your_api_key_here'},
7 json={
8 'name': 'Production SES',
9 'host': 'email-smtp.us-east-1.amazonaws.com',
10 'port': 587,
11 'username': os.environ['SES_USERNAME'],
12 'password': os.environ['SES_PASSWORD'],
13 'use_tls': True,
14 'sender_name': 'My App',
15 'sender_email': 'hello@myapp.com',
16 },
17)
18smtp_config = response.json()
FieldTypeRequiredDescription
namestringYesDisplay name
hoststringYesSMTP server hostname
portintegerYesPort (usually 587 for TLS)
usernamestringYesSMTP username
passwordstringYesSMTP password
use_tlsbooleanNoEnable TLS (default: true)
sender_namestringNoFrom name
sender_emailstringYesFrom email address

POST /api/emails/smtp/validate/

Test SMTP credentials without saving.

GET /api/emails/smtp-configs/

List SMTP configs.

PATCH /api/emails/smtp-configs/{id}/

Update an SMTP config.

DELETE /api/emails/smtp-configs/{id}/

Delete an SMTP config.


Campaigns

GET /api/emails/campaigns/

List all campaigns.

GET /api/emails/campaigns/{id}/

Get campaign details and status.

Code
bash
1curl https://api.sentinmail.app/api/emails/campaigns/CAMPAIGN_UUID/ \
2 -H "X-API-Key: fm_your_api_key_here"
Code
javascript
1const response = await fetch(
2 `https://api.sentinmail.app/api/emails/campaigns/${campaignId}/`,
3 { headers: { 'X-API-Key': process.env.SENTINMAIL_API_KEY } }
4);
5const campaign = await response.json();
6console.log(`Status: ${campaign.status}, Sent: ${campaign.sent_count}/${campaign.total_emails}`);
Code
python
1import requests
2 
3response = requests.get(
4 f'https://api.sentinmail.app/api/emails/campaigns/{campaign_id}/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6)
7campaign = response.json()
8print(f"Status: {campaign['status']}, Sent: {campaign['sent_count']}/{campaign['total_emails']}")

Campaign statuses: pending, sending, completed, partial, failed, scheduled, cancelled

POST /api/emails/campaigns/{id}/resume/

Resume a failed or partially completed campaign. Already-sent recipients are skipped.

POST /api/emails/campaigns/{id}/cancel/

Cancel a scheduled campaign.

GET /api/emails/campaigns/{id}/analytics/

Get campaign analytics (opens, clicks, bounces).

GET /api/emails/campaigns/{id}/export/

Export campaign results as CSV.


Webhooks

POST /api/emails/webhook-endpoints/

Register a webhook to receive delivery events.

Code
bash
1curl -X POST https://api.sentinmail.app/api/emails/webhook-endpoints/ \
2 -H "X-API-Key: fm_your_api_key_here" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://yourapp.com/webhooks/sentinmail",
6 "events": ["delivered", "opened", "clicked", "bounced", "unsubscribed"]
7 }'
Code
javascript
1const response = await fetch('https://api.sentinmail.app/api/emails/webhook-endpoints/', {
2 method: 'POST',
3 headers: {
4 'X-API-Key': process.env.SENTINMAIL_API_KEY,
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 url: 'https://yourapp.com/webhooks/sentinmail',
9 events: ['delivered', 'opened', 'clicked', 'bounced', 'unsubscribed'],
10 }),
11});
Code
python
1import requests
2 
3response = requests.post(
4 'https://api.sentinmail.app/api/emails/webhook-endpoints/',
5 headers={'X-API-Key': 'fm_your_api_key_here'},
6 json={
7 'url': 'https://yourapp.com/webhooks/sentinmail',
8 'events': ['delivered', 'opened', 'clicked', 'bounced', 'unsubscribed'],
9 },
10)

Event types: delivered, opened, clicked, bounced, unsubscribed

GET /api/emails/webhook-endpoints/

List registered webhooks.

PUT /api/emails/webhook-endpoints/{id}/

Update a webhook URL or events.

DELETE /api/emails/webhook-endpoints/{id}/

Delete a webhook.


Suppressions

POST /api/emails/suppressions/

Block emails to an address or domain.

Code
json
1{"email": "bounced@example.com", "reason": "Hard bounce"}

GET /api/emails/suppressions/

List suppressions.

DELETE /api/emails/suppressions/{id}/

Remove a suppression.


Segments

POST /api/emails/segments/

Create a dynamic subscriber segment based on rules.

Code
json
1{
2 "name": "Engaged Users",
3 "description": "Opened an email in the last 30 days",
4 "rules": {
5 "conditions": [
6 {"field": "last_opened", "operator": "within_days", "value": 30}
7 ],
8 "match": "all"
9 }
10}

GET /api/emails/segments/

List segments.

PATCH /api/emails/segments/{id}/

Update segment rules.

DELETE /api/emails/segments/{id}/

Delete a segment.


Media Files

POST /api/emails/media/

Upload a file (multipart/form-data).

GET /api/emails/media/

List uploaded files.

DELETE /api/emails/media/{id}/

Delete a file.


Sent Emails & Events

GET /api/emails/sent-emails/

List all sent emails with delivery status.

GET /api/emails/events/

List email events (opens, clicks, bounces, unsubscribes).


Public Endpoints

These endpoints require no authentication and are used for subscriber-facing features.

EndpointMethodDescription
/api/emails/public/subscribe/{company_id}/POSTSubscribe to newsletter (3/min rate limit per IP)
/api/emails/public/confirm/{token}/POSTConfirm double opt-in subscription
/api/emails/public/unsubscribe/{sent_email_id}/GET/POSTUnsubscribe from emails
/api/emails/public/view/{sent_email_id}/GETView email in browser
/api/emails/public/preferences/{token}/GET/PUTView/update subscriber preferences

Common Integration Patterns

Transactional Email (e.g., Order Confirmation)

Code
javascript
1// After order is placed
2async function sendOrderConfirmation(order) {
3 const response = await fetch('https://api.sentinmail.app/api/emails/send/custom/', {
4 method: 'POST',
5 headers: {
6 'X-API-Key': process.env.SENTINMAIL_API_KEY,
7 'Content-Type': 'application/json',
8 },
9 body: JSON.stringify({
10 name: `Order ${order.id} confirmation`,
11 smtp_config_id: process.env.SENTINMAIL_SMTP_ID,
12 subject: 'Order #[[order_id]] confirmed!',
13 body: '<h1>Thanks, [[first_name]]!</h1><p>Order #[[order_id]] confirmed. Total: $[[total]]</p>',
14 receivers: [{
15 email: order.customerEmail,
16 first_name: order.customerName,
17 order_id: order.id,
18 total: order.total.toFixed(2),
19 }],
20 }),
21 });
22 return response.json();
23}

Newsletter Signup + Welcome Email

Code
javascript
1// 1. Add subscriber
2const subRes = await fetch('https://api.sentinmail.app/api/emails/subscribers/', {
3 method: 'POST',
4 headers: {
5 'X-API-Key': process.env.SENTINMAIL_API_KEY,
6 'Content-Type': 'application/json',
7 },
8 body: JSON.stringify({ email: userEmail, first_name: userName }),
9});
10const subscriber = await subRes.json();
11 
12// 2. Add to newsletter list
13await fetch('https://api.sentinmail.app/api/emails/subscribers/bulk-update-lists/', {
14 method: 'POST',
15 headers: {
16 'X-API-Key': process.env.SENTINMAIL_API_KEY,
17 'Content-Type': 'application/json',
18 },
19 body: JSON.stringify({
20 subscriber_ids: [subscriber.id],
21 add_to_lists: [process.env.NEWSLETTER_LIST_ID],
22 remove_from_lists: [],
23 }),
24});
25 
26// 3. Send welcome email
27await fetch('https://api.sentinmail.app/api/emails/send/to-receivers/', {
28 method: 'POST',
29 headers: {
30 'X-API-Key': process.env.SENTINMAIL_API_KEY,
31 'Content-Type': 'application/json',
32 },
33 body: JSON.stringify({
34 name: `Welcome - ${userEmail}`,
35 template_id: process.env.WELCOME_TEMPLATE_ID,
36 smtp_config_id: process.env.SENTINMAIL_SMTP_ID,
37 receivers: [{ email: userEmail, first_name: userName }],
38 }),
39});

Webhook-Driven Bounce Handling

Code
javascript
1// Express.js webhook handler
2app.post('/webhooks/sentinmail', (req, res) => {
3 const event = req.body;
4 res.status(200).send('OK'); // Acknowledge immediately
5 
6 switch (event.type) {
7 case 'bounced':
8 db.users.update({ email: event.recipient }, { email_valid: false });
9 break;
10 case 'unsubscribed':
11 db.users.update({ email: event.recipient }, { marketing_opted_in: false });
12 break;
13 case 'opened':
14 analytics.track('email_opened', { email: event.recipient, campaign: event.campaign_id });
15 break;
16 }
17});
Code
python
1# Django webhook handler
2from django.http import HttpResponse
3from django.views.decorators.csrf import csrf_exempt
4import json
5 
6@csrf_exempt
7def sentinmail_webhook(request):
8 event = json.loads(request.body)
9 HttpResponse(status=200) # Acknowledge
10 
11 if event['type'] == 'bounced':
12 User.objects.filter(email=event['recipient']).update(email_valid=False)
13 elif event['type'] == 'unsubscribed':
14 User.objects.filter(email=event['recipient']).update(marketing_opted_in=False)
15 
16 return HttpResponse(status=200)
apireferenceendpointsrest