From your backend.
Send through the email API from any server that can make HTTP requests. Create a sending key in your account and keep it in your server environment.
Explore the email API ↗Works with your stack
Connect your application with WazobiaMail through HTTP API or authenticated SMTP, and connect Google through OAuth.
For developers · Backend written in Rust
A signup needs its login code. An order needs its receipt. Send both from your backend with one HTTP request.
Use HTTP for new integrations or authenticated SMTP for tools you already use. Keep keys out of browser code and public repositories.
Follow the quickstart ↗A successful response means accepted for sending. Check delivery activity to see what happens next.
curl -X POST https://app.wazobiamail.com/api/v1/sending/messages -H 'Content-Type: application/json' -H "X-API-Key: $WAZOBIA_API_KEY" -d '{
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
}'// Node.js 18+ · run on your server
const response = await fetch('https://app.wazobiamail.com/api/v1/sending/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.WAZOBIA_API_KEY
},
body: JSON.stringify({
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
})
});
const result = await response.json();
if (!response.ok || result.success !== true) throw new Error(result.message || 'Send failed');
console.log(result);// Node.js 18+ · run on your server
const key = process.env.WAZOBIA_API_KEY;
if (!key) throw new Error('Set WAZOBIA_API_KEY');
const message = {
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
};
const response = await fetch('https://app.wazobiamail.com/api/v1/sending/messages', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': key },
body: JSON.stringify(message)
});
const result = await response.json();
if (!response.ok || result.success !== true) throw new Error(result.message || 'Send failed');
console.log(result);<?php
// Requires the PHP cURL extension.
$key = getenv('WAZOBIA_API_KEY');
if (!$key) throw new RuntimeException('Set WAZOBIA_API_KEY');
$message = json_decode('{"envelopeSender":"hello@yourbrand.com","to":["you@example.com"],"content":{"from":"Your Brand <hello@yourbrand.com>","subject":"Welcome to Your Brand","htmlBody":"<p>Your account is ready. Welcome aboard!</p>"}}', true, 512, JSON_THROW_ON_ERROR);
$curl = curl_init('https://app.wazobiamail.com/api/v1/sending/messages');
curl_setopt_array($curl, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-API-Key: ' . $key],
CURLOPT_POSTFIELDS => json_encode($message, JSON_THROW_ON_ERROR)
]);
$body = curl_exec($curl);
if ($body === false) throw new RuntimeException(curl_error($curl));
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 300 || ($result['success'] ?? false) !== true) {
throw new RuntimeException($result['message'] ?? 'Send failed');
}
print_r($result);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
)
func main() {
key := os.Getenv("WAZOBIA_API_KEY")
if key == "" { panic("Set WAZOBIA_API_KEY") }
payload := []byte(`{
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
}`)
req, err := http.NewRequest("POST", "https://app.wazobiamail.com/api/v1/sending/messages", bytes.NewReader(payload))
if err != nil { panic(err) }
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", key)
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil { panic(err) }
if res.StatusCode >= 300 || result["success"] != true { panic(fmt.Sprint(result)) }
fmt.Println(result)
}// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// serde_json = "1"
use reqwest::blocking::Client;
use serde_json::{json, Value};
use std::{env, time::Duration};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = env::var("WAZOBIA_API_KEY")?;
let message = json!({
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
});
let result: Value = Client::builder().timeout(Duration::from_secs(30)).build()?
.post("https://app.wazobiamail.com/api/v1/sending/messages")
.header("X-API-Key", key)
.json(&message).send()?.error_for_status()?.json()?;
if result["success"] != true { return Err(format!("Send failed: {result}").into()); }
println!("{result}");
Ok(())
}# Python 3 · standard library only
import json
import os
import urllib.request
message = {
"envelopeSender": "hello@yourbrand.com",
"to": [
"you@example.com"
],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
}
request = urllib.request.Request(
'https://app.wazobiamail.com/api/v1/sending/messages',
data=json.dumps(message).encode('utf-8'),
headers={
'Content-Type': 'application/json',
'X-API-Key': os.environ['WAZOBIA_API_KEY'],
},
method='POST',
)
# HTTP errors raise urllib.error.HTTPError.
with urllib.request.urlopen(request, timeout=30) as response:
result = json.load(response)
if result.get('success') is not True:
raise RuntimeError(result.get('message', 'Send failed'))
print(result)// .NET 6+ · run on your server
using System.Net.Http.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key",
Environment.GetEnvironmentVariable("WAZOBIA_API_KEY"));
var response = await client.PostAsJsonAsync(
"https://app.wazobiamail.com/api/v1/sending/messages",
new {
envelopeSender = "hello@yourbrand.com",
to = new[] { "you@example.com" },
content = new {
from = "Your Brand <hello@yourbrand.com>",
subject = "Welcome to Your Brand",
htmlBody = "<p>Your account is ready. Welcome aboard!</p>"
}
});
response.EnsureSuccessStatusCode();// Java 11+ · run on your server
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
var json = """
{
"envelopeSender": "hello@yourbrand.com",
"to": ["you@example.com"],
"content": {
"from": "Your Brand <hello@yourbrand.com>",
"subject": "Welcome to Your Brand",
"htmlBody": "<p>Your account is ready. Welcome aboard!</p>"
}
}""";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://app.wazobiamail.com/api/v1/sending/messages"))
.header("Content-Type", "application/json")
.header("X-API-Key", System.getenv("WAZOBIA_API_KEY"))
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() / 100 != 2) throw new RuntimeException("Send failed: " + response.body());Send an email straight to your inbox.
Use your verified domain and sending API key. This test uses your account's sending allowance.
Send through the email API from any server that can make HTTP requests. Create a sending key in your account and keep it in your server environment.
Explore the email API ↗Connect applications that support authenticated SMTP. Use the host, port and credentials shown for your configured sending service.
SMTP or HTTP? ↗Connect Google through OAuth. Review and grant the permissions for Gmail sending and Contacts access according to your workflow.
Explore Google connections ↗Your name belongs in your email
Custom domain inboxes for you and your team. Email sending for your apps.