Reseller API Documentation

Integrate your system directly with our Reseller Platform using the JSON API.

Integrate with Ease

Our platform provides a robust JSON API for resellers to manage sub-accounts, credits, and transactional emails. This documentation is designed to guide you through the integration process, from your first authentication to high-volume email delivery.

Core Concepts

Before diving in, it's helpful to understand the two main ways to interact with our platform:

  • JSON API: Best for dynamic management (creating users, checking balances) and sending specific transactional emails.
  • SMTP Relay: Ideal for legacy applications or mail servers that already support the SMTP protocol.

Welcome to the MSpace Bulk Email Developer Hub. Our platform offers a high-performance, enterprise-grade SMTP and JSON API infrastructure for resellers and application developers. Scale your outreach with precision using our robust integration options.

Production API Host: https://bulkemail.mspace.co.ke/email

Use this base URL for all API requests. All endpoints require HTTPS for security.

Authentication

Secure your requests using one of the two supported authentication methods, depending on the endpoint you are accessing. Security is our top priority; never share your credentials or API keys in public repositories.

Basic Auth

Usage: Reseller API Management.
Combine your username and password with a colon, then encode the string in Base64.

Authorization: Basic b64(user:pass)

API Key

Usage: Transactional Messaging.
Generate keys in your dashboard. Pass the key directly in the JSON body of your request.

"apiKey": "YOUR_SECURE_KEY"
Developer Tip: For local development, use environment variables to store these secrets instead of hardcoding them in your source code.

Reseller: Create Sub-User

Programmatically provision new sub-accounts. Perfect for integrating our email services into your own SaaS dashboard or customer portal.

POST
/api/reseller/createSubUser

Request Payload Details

Field Type Required Description
username String Yes The unique login name for the new client.
password String Yes Must be at least 8 characters long.
credits Integer No Initial credit allocation (defaults to 0).
mobile String No Contact phone (MSISDN format, e.g., 254...).

Example Implementation

curl -X POST "https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser" \
     -u "YOUR_USERNAME:YOUR_PASSWORD" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -d '{
  "username": "developer",
  "password": "developer123",
  "firstname": "Dev",
  "surname": "Loper",
  "organization": "Winsy",
  "mobile": "254729651022",
  "credits": 50
}'
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Base64;

public class CreateSubUser {
    public static void main(String[] args) throws Exception {
        String auth = "YOUR_USERNAME:YOUR_PASSWORD";
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());

        String json = """
            {
              "username": "developer",
              "password": "developer123",
              "firstname": "Dev",
              "surname": "Loper",
              "organization": "Winsy",
              "mobile": "254729651022",
              "credits": 50
            }
            """;

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser"))
            .header("Authorization", "Basic " + encodedAuth)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
<?php
$url = "https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser";
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";

$data = [
    "username" => "developer",
    "password" => "developer123",
    "firstname" => "Dev",
    "surname" => "Loper",
    "organization" => "Winsy",
    "mobile" => "254729651022",
    "credits" => 50
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
import urllib.request
import json
import base64

url = "https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser"
auth = base64.b64encode(b"YOUR_USERNAME:YOUR_PASSWORD").decode("ascii")
data = {
    "username": "developer",
    "password": "developer123",
    "firstname": "Dev",
    "surname": "Loper",
    "organization": "Winsy",
    "mobile": "254729651022",
    "credits": 50
}

req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), method="POST")
req.add_header("Authorization", f"Basic {auth}")
req.add_header("Content-Type", "application/json")

with urllib.request.urlopen(req) as response:
    print(response.read().decode("utf-8"))
const https = require('https');

const data = JSON.stringify({
  username: 'developer',
  password: 'developer123',
  firstname: 'Dev',
  surname: 'Loper',
  organization: 'Winsy',
  mobile: '254729651022',
  credits: 50
});

const options = {
  hostname: 'bulkemail.mspace.co.ke',

  path: '/email/api/reseller/createSubUser',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length,
    'Authorization': 'Basic ' + Buffer.from('YOUR_USERNAME:YOUR_PASSWORD').toString('base64')
  }
};

const req = https.request(options, res => {
  res.on('data', d => process.stdout.write(d));
});

req.on('error', error => console.error(error));
req.write(data);
req.end();
package main

import (
    "bytes"
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser"
    auth := base64.StdEncoding.EncodeToString([]byte("YOUR_USERNAME:YOUR_PASSWORD"))
    
    jsonStr := []byte(`{
        "username": "developer",
        "password": "developer123",
        "firstname": "Dev",
        "surname": "Loper",
        "organization": "Winsy",
        "mobile": "254729651022",
        "credits": 50
    }`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("Authorization", "Basic "+auth)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program {
    static async Task Main() {
        var url = "https://bulkemail.mspace.co.ke/email/api/reseller/createSubUser";
        var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes("YOUR_USERNAME:YOUR_PASSWORD"));
        
        var json = @"{
            ""username"": ""developer"",
            ""password"": ""developer123"",
            ""firstname"": ""Dev"",
            ""surname"": ""Loper"",
            ""organization"": ""Winsy"",
            ""mobile"": ""254729651022"",
            ""credits"": 50
        }";

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + auth);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await client.PostAsync(url, content);
        var responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseString);
    }
}

Sample Responses

Success Response
{
  "status": "success",
  "message": "Sub-user created successfully"
}
Error Response (Auth Failed)
{
  "status": "error",
  "message": "Authentication passed failed."
}

Reseller: Manage Credits

Transfer email credits between your master account and sub-accounts in real-time.

POST
/api/reseller/manageCredits
Safety Note: Ensure your master balance is sufficient before initiating an ADD action.

Action Types

  • "ADD": Transfer credits from your balance to the sub-user.
  • "DEDUCT": Reclaim credits from sub-user to your balance.

Example Implementation

curl -X POST "https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits" \
     -u "YOUR_USERNAME:YOUR_PASSWORD" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -d '{
  "sub_username": "developer",
  "action": "ADD",
  "amount": 100
}'
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Base64;

public class ManageCredits {
    public static void main(String[] args) throws Exception {
        String auth = "YOUR_USERNAME:YOUR_PASSWORD";
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());

        String json = """
            {
              "sub_username": "developer",
              "action": "ADD",
              "amount": 100
            }
            """;

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits"))
            .header("Authorization", "Basic " + encodedAuth)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
<?php
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";

$data = [
    "sub_username" => "developer",
    "action" => "ADD",
    "amount" => 100
];

$ch = curl_init("https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
import urllib.request
import json
import base64

url = "https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits"
auth = base64.b64encode(b"YOUR_USERNAME:YOUR_PASSWORD").decode("ascii")
data = {
    "sub_username": "developer",
    "action": "ADD",
    "amount": 100
}

req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), method="POST")
req.add_header("Authorization", f"Basic {auth}")
req.add_header("Content-Type", "application/json")

with urllib.request.urlopen(req) as response:
    print(response.read().decode("utf-8"))
const https = require('https');

const data = JSON.stringify({
  sub_username: 'developer',
  action: 'ADD',
  amount: 100
});

const options = {
  hostname: 'bulkemail.mspace.co.ke',

  path: '/email/api/reseller/manageCredits',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length,
    'Authorization': 'Basic ' + Buffer.from('YOUR_USERNAME:YOUR_PASSWORD').toString('base64')
  }
};

const req = https.request(options, res => {
  res.on('data', d => process.stdout.write(d));
});

req.on('error', error => console.error(error));
req.write(data);
req.end();
package main

import (
    "bytes"
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits"
    auth := base64.StdEncoding.EncodeToString([]byte("YOUR_USERNAME:YOUR_PASSWORD"))
    
    jsonStr := []byte(`{
        "sub_username": "developer",
        "action": "ADD",
        "amount": 100
    }`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("Authorization", "Basic "+auth)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program {
    static async Task Main() {
        var url = "https://bulkemail.mspace.co.ke/email/api/reseller/manageCredits";
        var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes("YOUR_USERNAME:YOUR_PASSWORD"));
        
        var json = @"{
            ""sub_username"": ""developer"",
            ""action"": ""ADD"",
            ""amount"": 100
        }";

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + auth);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await client.PostAsync(url, content);
        var responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseString);
    }
}

Sample Responses

Success Response
{
  "status": "success",
  "message": "Credits updated",
  "reseller_balance": 1015,
  "subuser_balance": 20
}
Error Response (Insufficient Funds)
{
  "status": "error",
  "message": "Insufficient reseller credits"
}
Error Response (Auth Failed)
{
  "status": "error",
  "message": "Authentication passed failed."
}

Messaging: Send Transactional

Send high-priority individual emails with attachment and HTML support. Transactional emails are typically automated responses to user actions, such as welcome emails, password resets, or order confirmations.

POST
/api/send
Best for: Real-time, one-to-one communication where delivery speed is critical.

Parameters Reference

Field Required Description
apiKey Yes Generate this in the API Keys tab of your dashboard.
to Yes Recipient email address.
subject Yes Email subject line.
body Yes HTML or Plain Text content.
fromName No Custom sender name show to recipient.

Example Implementation

curl -X POST "https://bulkemail.mspace.co.ke/email/api/send" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -d '{
  "apiKey": "YOUR_API_KEY",
  "to": "recipient@example.com",
  "subject": "Hello from MSpace",
  "body": "<h1>HTML Content</h1>",
  "fromName": "MSpace System"
}'
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

public class SendTransactional {
    public static void main(String[] args) throws Exception {
        String json = """
            {
              "apiKey": "YOUR_API_KEY",
              "to": "recipient@example.com",
              "subject": "Hello from MSpace",
              "body": "<h1>HTML Content</h1>",
              "fromName": "MSpace System"
            }
            """;

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://bulkemail.mspace.co.ke/email/api/send"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
<?php
$data = [
    "apiKey" => "YOUR_API_KEY",
    "to" => "recipient@example.com",
    "subject" => "Hello from MSpace",
    "body" => "<h1>HTML Content</h1>",
    "fromName" => "MSpace System"
];

$ch = curl_init("https://bulkemail.mspace.co.ke/email/api/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
import urllib.request
import json

url = "https://bulkemail.mspace.co.ke/email/api/send"
data = {
    "apiKey": "YOUR_API_KEY",
    "to": "recipient@example.com",
    "subject": "Hello from MSpace",
    "body": "<h1>HTML Content</h1>",
    "fromName": "MSpace System"
}

req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), method="POST")
req.add_header("Content-Type", "application/json")

with urllib.request.urlopen(req) as response:
    print(response.read().decode("utf-8"))
const https = require('https');

const data = JSON.stringify({
  apiKey: 'YOUR_API_KEY',
  to: 'recipient@example.com',
  subject: 'Hello from MSpace',
  body: '<h1>HTML Content</h1>',
  fromName: 'MSpace System'
});

const options = {
  hostname: 'bulkemail.mspace.co.ke/email'
  port: 2525,
  path: '/email/api/send',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
};

const req = https.request(options, res => {
  res.on('data', d => process.stdout.write(d));
});

req.on('error', error => console.error(error));
req.write(data);
req.end();
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "https://bulkemail.mspace.co.ke/email/api/send"
    jsonStr := []byte(`{
        "apiKey": "YOUR_API_KEY",
        "to": "recipient@example.com",
        "subject": "Hello from MSpace",
        "body": "<h1>HTML Content</h1>",
        "fromName": "MSpace System"
    }`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program {
    static async Task Main() {
        var url = "https://bulkemail.mspace.co.ke/email/api/send";
        var json = @"{
            ""apiKey"": ""YOUR_API_KEY"",
            ""to"": ""recipient@example.com"",
            ""subject"": ""Hello from MSpace"",
            ""body"": ""<h1>HTML Content</h1>"",
            ""fromName"": ""MSpace System""
        }";

        using var client = new HttpClient();
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await client.PostAsync(url, content);
        var responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseString);
    }
}

Sample Responses

Success Response
{
  "status": "success",
  "message": "Email queued successfully",
  "messageId": "msg_123456789"
}
Error Response (Invalid API Key)
{
  "status": "error",
  "message": "Authentication passed failed."
}

Messaging: SMTP Integration

Integrate with our relay servers using standard SMTP protocols. Perfect for traditional mail servers (like Postfix or Exchange) and legacy applications that already have SMTP support built-in.

API vs SMTP: Which one to choose?

Use the JSON API if you need programmatic control and better error handling within your code. Use SMTP if you want a drop-in solution for existing software that doesn't require new code development.

Relay Host bulkemail.mspace.co.ke/email
Standard Port 2525
Alternative Port 587
Security Type STARTTLS / TLS
Username Reseller ID or the username of the main account

Code Implementation Examples

Choose your preferred technology stack to view a production-ready implementation example.

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class EmailSender {
    public static void main(String[] args) {
        final String username = "YOUR_USERNAME";
        final String password = "YOUR_PASSWORD";

        Properties prop = new Properties();
        prop.put("mail.smtp.host", "bulkemail.mspace.co.ke");
        prop.put("mail.smtp.port", "2525");
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.starttls.enable", "true");

        Session session = Session.getInstance(prop, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("noreply@mspace.co.ke"));
            message.setRecipients(Message.RecipientType.TO, 
                InternetAddress.parse("recipient@example.com"));
            message.setSubject("Hello from MSpace");
            message.setText("This is the email body.");
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}
<?php
use PHPMailer\PHPMailer\PHPMailer;

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'bulkemail.mspace.co.ke';
$mail->SMTPAuth   = true;
$mail->Username   = 'YOUR_USERNAME';
$mail->Password   = 'YOUR_PASSWORD';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port       = 2525;

$mail->setFrom('info@mspace.co.ke', 'MSpace Info');
$mail->addAddress($recipient);
$mail->Subject = $subject;
$mail->Body    = $body;
$mail->send();
import smtplib
from email.mime.text import MIMEText

def send_email(recipient, body, subject):
    msg = MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = "Sender Name <noreply@mspace.co.ke>"
    msg['To'] = recipient

    with smtplib.SMTP("bulkemail.mspace.co.ke", 2525) as server:
        server.starttls()
        server.login("YOUR_USERNAME", "YOUR_PASSWORD")
        server.send_message(msg)
const nodemailer = require('nodemailer');

async function sendMail() {
  let transporter = nodemailer.createTransport({
    host: 'bulkemail.mspace.co.ke',
    port: 2525,
    secure: false,
    auth: {
      user: 'YOUR_USERNAME',
      pass: 'YOUR_PASSWORD'
    }
  });

  let info = await transporter.sendMail({
    from: '"Sender Name" <noreply@mspace.co.ke>',
    to: 'recipient@example.com',
    subject: 'Hello from MSpace',
    text: 'Hello world?',
    html: '<b>Hello world?</b>'
  });
}
package main

import (
    "net/smtp"
)

func main() {
    auth := smtp.PlainAuth("", "YOUR_USERNAME", "YOUR_PASSWORD", "bulkemail.mspace.co.ke")
    to := []string{"recipient@example.com"}
    msg := []byte("To: recipient@example.com\r\n" +
        "Subject: Hello from MSpace\r\n" +
        "\r\n" +
        "This is the email body.\r\n")
    
    err := smtp.SendMail("bulkemail.mspace.co.ke:2525", auth, "noreply@mspace.co.ke", to, msg)
    if err != nil {
        panic(err)
    }
}
using System.Net;
using System.Net.Mail;

public class EmailSender {
    public void Send() {
        var client = new SmtpClient("bulkemail.mspace.co.ke", 2525) {
            Credentials = new NetworkCredential("YOUR_USERNAME", "YOUR_PASSWORD"),
            EnableSsl = true
        };
        client.Send("noreply@mspace.co.ke", "recipient@example.com", "Subject", "Body");
    }
}

Error Response Reference

When an error occurs, the API returns a corresponding error code and descriptive message. Understanding these responses helps you build more resilient integrations.

Status Message Context / Troubleshooting
error Authentication passed failed. Verify that your Basic Auth header is correctly Base64 encoded and matching your dashboard login.
error Insufficient reseller credits Your master account balance (reseller balance) is too low. Top up via the portal.
error The target sub-username was not found. The sub_username provided does not exist under your reseller account.
error Rate limit or connection error. You've exceeded the allowed requests per second. Implement a retry mechanism with exponential backoff.

Integration Best Practices

Security

  • Always use HTTPS.
  • Rotate API keys every 90 days.
  • Whitelist your server IPs in the dashboard if available.

Performance

  • Batch requests when manageable.
  • Avoid frequent polling; use our dashboard for status where possible.
  • Keep payloads concise for faster processing.
Hello! How can we assist you today?