This application creates an API to queue and process bulk emails as well as a web application to view the status of each email batch.
A batch of emails can be sent as an array to the API, which will then queue and process them with a configurable delay between each. The submitted emails are also saved in a database. If the application needs to restart before all emails are processed, any unsent emails will be loaded from the database and processing will continue.
The API application is configured through appsettings.json with the following sections:
Configure the delay in seconds between processing each email.
{
"EmailQueueSettings": {
"ProcessingDelaySeconds": 5
}
}All API endpoints (except as noted below) require authentication using a Client ID passed in the X-Client-ID header
and an API Key passed in
the X-API-Key header with each request.
Valid API clients are configured in appsettings.json:
{
"ApiClients": [
{
"ClientName": "Your Web Application",
"ClientId": "your-client-guid",
"ApiKey": "your-secret-api-key"
}
]
}The Client Name and ID fields are saved in the database with each email record.
Returns "OK" if the API is running.
Returns the application version number.
Returns "Auth OK" if the provided authentication credentials are valid.
Submits a batch of email tasks for processing.
Request body: Array of email tasks.
[
{
"from": "from.email@example.net",
"recipients": [
"email@example.com"
],
"copyRecipients": [],
"subject": "Email Subject",
"body": "Email content",
"isHtml": false
}
]Each email task contains the following properties:
from: The return (from) email address (Required)recipients: List of recipient email addresses (Required; may not be empty or contain any empty values)copyRecipients: List of copied email addresses (Optional; may not contain empty values if included)subject: Email subject line, max 200 characters (Required)body: Email content, max 20,000 characters (Required)isHtml: Boolean indicating if the body is formatted as HTML (Required)
Response format if successful:
{
"status": "Success",
"count": 1,
"batchId": "guid-of-batch"
}The Batch ID is a GUID.
If no email tasks are submitted, the following response will be returned (no Batch ID will be created):
{
"status": "Empty",
"count": 0,
"batchId": ""
}Submits a batch of email tasks for processing for a specified Batch ID. (Note: The Batch ID can be one that already exists in the database, but it doesn't have to.)
Request body:
{
"batchId": "batchId",
"emails": [
{
"from": "from.email@example.net",
"recipients": [
"email@example.com"
],
"copyRecipients": [],
"subject": "Email Subject",
"body": "Email content",
"isHtml": false
}
]
}Each email task contains the same properties as in the /add endpoint above.
Response format if successful:
{
"status": "Success",
"count": 2,
"batchId": "guid-of-batch"
}The Batch ID is the submitted ID. The count is the number of emails added to the batch (not the total emails for the batch if some already exist).
If no email tasks are submitted, the following response will be returned:
{
"status": "Empty",
"count": 0,
"batchId": "guid-of-batch"
}Returns a list of all Batch IDs in the system for the provided Client ID, ordered by creation date descending.
Response format:
[
{
"batchId": "guid-of-batch",
"count": 1,
"queued": 1,
"sent": 0,
"failed": 0,
"skipped": 0,
"createdAt": "2025-06-02T19:30:00.0000000"
}
]Returns the status of a specific Batch ID.
Request body:
{
"batchId": "guid-of-batch"
}Response format:
{
"batchId": "guid-of-batch",
"count": 1,
"queued": 1,
"sent": 0,
"failed": 0,
"skipped": 0,
"createdAt": "2025-06-02T19:30:00.0000000"
}Returns details of each email task for a specific Batch ID, ordered by creation date ascending.
Request body:
{
"batchId": "guid-of-batch"
}Response format:
[
{
"id": "guid-of-email-task",
"counter": 1,
"status": "Queued",
"failureReason": null,
"createdAt": "2025-06-02T19:30:00.0000000",
"attemptedAt": "2025-06-02T19:30:00.0000000",
"from": "from.email@example.net",
"recipients": [
"email@example.com"
],
"copyRecipients": [],
"subject": "Email Subject"
}
]Returns details of each failed or skipped email task for a specific Batch ID, ordered by creation date ascending.
Request body and response format are the same as batch-details above.
A sample web application is provided to demonstrate displaying data from the API. The web application is configured
through appsettings.json with the following section:
{
"EmailQueueApi": {
"BaseUrl": "https://localhost:7145",
"ClientId": "your-client-guid",
"ApiKey": "your-secret-api-key"
}
}