Examples
End-to-end code examples for common Keplars API workflows.
Domain Provisioning & Sending
This example walks through the full flow - add a domain, verify it, generate a sending API key, and send an email - entirely via the API.
Prerequisites:
- An Admin API key with
domains:manageandapi-keys:createscopes - DNS access to your domain
All requests go to https://api.keplars.com. Replace ADMIN_KEY with your Admin API key.
ADMIN_KEY="your_admin_key"
BASE="https://api.keplars.com"
# Step 1 - Add domain
DOMAIN_RESP=$(curl -s -X POST "$BASE/api/v1/public/domains/add-domain" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"mail.yourdomain.com","region":"us-east-1"}')
DOMAIN_ID=$(echo $DOMAIN_RESP | jq -r '.data.id')
echo "Domain ID: $DOMAIN_ID"
echo "Add these DNS records: $(echo $DOMAIN_RESP | jq '.data.dns_records')"
# Step 2 - Check status (repeat until verification_status == "verified")
curl -s "$BASE/api/v1/public/domains/domain-status/$DOMAIN_ID" \
-H "Authorization: Bearer $ADMIN_KEY" | jq '.data.verification_status'
# Step 3 - Create sending API key (save secret_key - shown once!)
# expires_at is optional - ISO 8601 format e.g. "2026-12-31T23:59:59Z"
SENDING_KEY=$(curl -s -X POST "$BASE/api/v1/public/domains/api-keys/create" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d "{\"name\":\"My App Sending Key\",\"custom_domain_id\":\"$DOMAIN_ID\"}" \
| jq -r '.data.secret_key')
echo "Sending key: $SENDING_KEY"
# Step 4 - Send email
curl -s -X POST "$BASE/api/v1/send-email/instant" \
-H "Authorization: Bearer $SENDING_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": [{"email": "[email protected]"}],
"subject": "Hello from my domain",
"html": "<p>It works!</p>"
}'const BASE_URL = 'https://api.keplars.com';
const ADMIN_KEY = process.env.KEPLARS_ADMIN_KEY;
const headers = {
'Authorization': `Bearer ${ADMIN_KEY}`,
'Content-Type': 'application/json',
};
async function provisionDomain(domain) {
// Step 1 - Add domain
const addRes = await fetch(`${BASE_URL}/api/v1/public/domains/add-domain`, {
method: 'POST',
headers,
body: JSON.stringify({ domain, region: 'us-east-1' }),
});
const { data: domainData } = await addRes.json();
console.log('DNS records to add:', domainData.dns_records);
const domainId = domainData.id;
// Step 2 - Poll until verified
let verified = false;
while (!verified) {
await new Promise(r => setTimeout(r, 10_000));
const { data } = await fetch(
`${BASE_URL}/api/v1/public/domains/domain-status/${domainId}`,
{ headers }
).then(r => r.json());
console.log('Status:', data.verification_status);
verified = data.verification_status === 'verified';
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. '2026-12-31T23:59:59Z'
const { data: keyData } = await fetch(`${BASE_URL}/api/v1/public/domains/api-keys/create`, {
method: 'POST',
headers,
body: JSON.stringify({ name: 'My App Sending Key', custom_domain_id: domainId }),
}).then(r => r.json());
console.log('Sending key (store this!):', keyData.secret_key);
return keyData.secret_key;
}
async function sendEmail(sendingKey, from, to, subject, html) {
// Step 4 - Send email
return fetch(`${BASE_URL}/api/v1/send-email/instant`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${sendingKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ from, to: [{ email: to }], subject, html }),
}).then(r => r.json());
}
const sendingKey = await provisionDomain('mail.yourdomain.com');
const result = await sendEmail(sendingKey, '[email protected]', '[email protected]', 'Hello from my domain', '<p>It works!</p>');
console.log('Sent:', result);import os
import time
import requests
BASE_URL = 'https://api.keplars.com'
ADMIN_KEY = os.environ['KEPLARS_ADMIN_KEY']
headers = {'Authorization': f'Bearer {ADMIN_KEY}', 'Content-Type': 'application/json'}
def provision_domain(domain: str) -> str:
# Step 1 - Add domain
domain_data = requests.post(
f'{BASE_URL}/api/v1/public/domains/add-domain',
headers=headers,
json={'domain': domain, 'region': 'us-east-1'},
).json()['data']
print('DNS records to add:', domain_data['dns_records'])
domain_id = domain_data['id']
# Step 2 - Poll until verified
while True:
time.sleep(10)
status = requests.get(
f'{BASE_URL}/api/v1/public/domains/domain-status/{domain_id}',
headers=headers,
).json()['data']['verification_status']
print('Status:', status)
if status == 'verified':
break
# Step 3 - Create sending API key
# expires_at is optional - ISO 8601 e.g. '2026-12-31T23:59:59Z'
sending_key = requests.post(
f'{BASE_URL}/api/v1/public/domains/api-keys/create',
headers=headers,
json={'name': 'My App Sending Key', 'custom_domain_id': domain_id},
).json()['data']['secret_key']
print('Sending key (store this!):', sending_key)
return sending_key
def send_email(sending_key: str, from_addr: str, to: str, subject: str, html: str):
# Step 4 - Send email
return requests.post(
f'{BASE_URL}/api/v1/send-email/instant',
headers={'Authorization': f'Bearer {sending_key}', 'Content-Type': 'application/json'},
json={'from': from_addr, 'to': [{'email': to}], 'subject': subject, 'html': html},
).json()
sending_key = provision_domain('mail.yourdomain.com')
result = send_email(sending_key, '[email protected]', '[email protected]', 'Hello from my domain', '<p>It works!</p>')
print('Sent:', result)package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
)
const baseURL = "https://api.keplars.com"
func apiPost(path, token string, body any) map[string]any {
b, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", baseURL+path, bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
var result map[string]any
json.NewDecoder(resp.Body).Decode(&result)
return result
}
func apiGet(path, token string) map[string]any {
req, _ := http.NewRequest("GET", baseURL+path, nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
var result map[string]any
json.NewDecoder(resp.Body).Decode(&result)
return result
}
func provisionDomain(domain, adminKey string) string {
// Step 1 - Add domain
data := apiPost("/api/v1/public/domains/add-domain", adminKey, map[string]any{
"domain": domain, "region": "us-east-1",
})["data"].(map[string]any)
domainID := data["id"].(string)
fmt.Println("DNS records:", data["dns_records"])
// Step 2 - Poll until verified
for {
time.Sleep(10 * time.Second)
s := apiGet("/api/v1/public/domains/domain-status/"+domainID, adminKey)["data"].(map[string]any)["verification_status"].(string)
fmt.Println("Status:", s)
if s == "verified" {
break
}
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. "2026-12-31T23:59:59Z"
sendingKey := apiPost("/api/v1/public/domains/api-keys/create", adminKey, map[string]any{
"name": "My App Sending Key", "custom_domain_id": domainID,
})["data"].(map[string]any)["secret_key"].(string)
fmt.Println("Sending key (store this!):", sendingKey)
return sendingKey
}
func main() {
adminKey := os.Getenv("KEPLARS_ADMIN_KEY")
sendingKey := provisionDomain("mail.yourdomain.com", adminKey)
// Step 4 - Send email
result := apiPost("/api/v1/send-email/instant", sendingKey, map[string]any{
"from": "[email protected]", "to": []map[string]any{{"email": "[email protected]"}},
"subject": "Hello from my domain", "html": "<p>It works!</p>",
})
fmt.Println("Sent:", result)
}using System.Net.Http.Json;
using System.Text.Json;
var baseUrl = "https://api.keplars.com";
var adminKey = Environment.GetEnvironmentVariable("KEPLARS_ADMIN_KEY")!;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {adminKey}");
async Task<JsonElement> Post(string path, object body, string? token = null)
{
using var req = new HttpRequestMessage(HttpMethod.Post, baseUrl + path);
req.Headers.Add("Authorization", $"Bearer {token ?? adminKey}");
req.Content = JsonContent.Create(body);
var resp = await http.SendAsync(req);
var json = await resp.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data");
}
async Task<JsonElement> Get(string path)
{
var resp = await http.GetAsync(baseUrl + path);
var json = await resp.Content.ReadFromJsonAsync<JsonElement>();
return json.GetProperty("data");
}
// Step 1 - Add domain
var domainData = await Post("/api/v1/public/domains/add-domain",
new { domain = "mail.yourdomain.com", region = "us-east-1" });
var domainId = domainData.GetProperty("id").GetString()!;
Console.WriteLine($"Domain ID: {domainId}");
// Step 2 - Poll until verified
while (true)
{
await Task.Delay(10_000);
var status = await Get($"/api/v1/public/domains/domain-status/{domainId}");
var s = status.GetProperty("verification_status").GetString();
Console.WriteLine($"Status: {s}");
if (s == "verified") break;
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. "2026-12-31T23:59:59Z"
var keyData = await Post("/api/v1/public/domains/api-keys/create",
new { name = "My App Sending Key", custom_domain_id = domainId });
var sendingKey = keyData.GetProperty("secret_key").GetString()!;
Console.WriteLine($"Sending key (store this!): {sendingKey}");
// Step 4 - Send email
var result = await Post("/api/v1/send-email/instant",
new { from = "[email protected]", to = new[] { new { email = "[email protected]" } },
subject = "Hello from my domain", html = "<p>It works!</p>" },
token: sendingKey);
Console.WriteLine($"Sent: {result}");import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;
import java.time.Duration;
public class KeplarsProvisioning {
static final String BASE = "https://api.keplars.com";
static final String ADMIN_KEY = System.getenv("KEPLARS_ADMIN_KEY");
static final HttpClient CLIENT = HttpClient.newHttpClient();
static final ObjectMapper JSON = new ObjectMapper();
static JsonNode post(String path, String body, String token) throws Exception {
var req = HttpRequest.newBuilder(URI.create(BASE + path))
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(body))
.build();
var resp = CLIENT.send(req, HttpResponse.BodyHandlers.ofString());
return JSON.readTree(resp.body()).get("data");
}
static JsonNode get(String path) throws Exception {
var req = HttpRequest.newBuilder(URI.create(BASE + path))
.header("Authorization", "Bearer " + ADMIN_KEY)
.GET().build();
var resp = CLIENT.send(req, HttpResponse.BodyHandlers.ofString());
return JSON.readTree(resp.body()).get("data");
}
public static void main(String[] args) throws Exception {
// Step 1 - Add domain
var domainData = post("/api/v1/public/domains/add-domain",
"""{"domain":"mail.yourdomain.com","region":"us-east-1"}""", ADMIN_KEY);
var domainId = domainData.get("id").asText();
System.out.println("Domain ID: " + domainId);
// Step 2 - Poll until verified
while (true) {
Thread.sleep(10_000);
var status = get("/api/v1/public/domains/domain-status/" + domainId)
.get("verification_status").asText();
System.out.println("Status: " + status);
if ("verified".equals(status)) break;
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. "2026-12-31T23:59:59Z"
var keyData = post("/api/v1/public/domains/api-keys/create",
"""{"name":"My App Sending Key","custom_domain_id":"%s"}""".formatted(domainId),
ADMIN_KEY);
var sendingKey = keyData.get("secret_key").asText();
System.out.println("Sending key (store this!): " + sendingKey);
// Step 4 - Send email
var result = post("/api/v1/send-email/instant",
"""{"from":"[email protected]","to":[{"email":"[email protected]"}],"subject":"Hello from my domain","html":"<p>It works!</p>"}""",
sendingKey);
System.out.println("Sent: " + result);
}
}import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
const baseUrl = 'https://api.keplars.com';
final adminKey = Platform.environment['KEPLARS_ADMIN_KEY']!;
Future<Map<String, dynamic>> apiPost(String path, Map<String, dynamic> body,
{String? token}) async {
final res = await http.post(
Uri.parse('$baseUrl$path'),
headers: {
'Authorization': 'Bearer ${token ?? adminKey}',
'Content-Type': 'application/json',
},
body: jsonEncode(body),
);
return (jsonDecode(res.body) as Map<String, dynamic>)['data'];
}
Future<Map<String, dynamic>> apiGet(String path) async {
final res = await http.get(
Uri.parse('$baseUrl$path'),
headers: {'Authorization': 'Bearer $adminKey'},
);
return (jsonDecode(res.body) as Map<String, dynamic>)['data'];
}
Future<void> main() async {
// Step 1 - Add domain
final domainData = await apiPost('/api/v1/public/domains/add-domain',
{'domain': 'mail.yourdomain.com', 'region': 'us-east-1'});
final domainId = domainData['id'] as String;
print('DNS records: ${domainData['dns_records']}');
// Step 2 - Poll until verified
while (true) {
await Future.delayed(const Duration(seconds: 10));
final status = await apiGet('/api/v1/public/domains/domain-status/$domainId');
print('Status: ${status['verification_status']}');
if (status['verification_status'] == 'verified') break;
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. '2026-12-31T23:59:59Z'
final keyData = await apiPost('/api/v1/public/domains/api-keys/create',
{'name': 'My App Sending Key', 'custom_domain_id': domainId});
final sendingKey = keyData['secret_key'] as String;
print('Sending key (store this!): $sendingKey');
// Step 4 - Send email
final result = await apiPost(
'/api/v1/send-email/instant',
{
'from': '[email protected]',
'to': [{'email': '[email protected]'}],
'subject': 'Hello from my domain',
'html': '<p>It works!</p>',
},
token: sendingKey,
);
print('Sent: $result');
}<?php
$baseUrl = 'https://api.keplars.com';
$adminKey = getenv('KEPLARS_ADMIN_KEY');
function apiRequest(string $method, string $path, ?array $body, string $token): array {
global $baseUrl;
$ch = curl_init("$baseUrl$path");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
]);
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
return $resp['data'];
}
// Step 1 - Add domain
$domainData = apiRequest('POST', '/api/v1/public/domains/add-domain',
['domain' => 'mail.yourdomain.com', 'region' => 'us-east-1'], $adminKey);
$domainId = $domainData['id'];
echo "Domain ID: $domainId\n";
// Step 2 - Poll until verified
while (true) {
sleep(10);
$status = apiRequest('GET', "/api/v1/public/domains/domain-status/$domainId", null, $adminKey);
echo "Status: {$status['verification_status']}\n";
if ($status['verification_status'] === 'verified') break;
}
// Step 3 - Create sending API key
// expires_at is optional - ISO 8601 e.g. '2026-12-31T23:59:59Z'
$keyData = apiRequest('POST', '/api/v1/public/domains/api-keys/create',
['name' => 'My App Sending Key', 'custom_domain_id' => $domainId], $adminKey);
$sendingKey = $keyData['secret_key'];
echo "Sending key (store this!): $sendingKey\n";
// Step 4 - Send email
$result = apiRequest('POST', '/api/v1/send-email/instant', [
'from' => '[email protected]',
'to' => [['email' => '[email protected]']],
'subject' => 'Hello from my domain',
'html' => '<p>It works!</p>',
], $sendingKey);
echo "Sent: " . json_encode($result) . "\n";require 'net/http'
require 'json'
require 'uri'
BASE_URL = 'https://api.keplars.com'
ADMIN_KEY = ENV['KEPLARS_ADMIN_KEY']
def api_request(method, path, body = nil, token: ADMIN_KEY)
uri = URI("#{BASE_URL}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = case method
when :post then Net::HTTP::Post.new(uri)
when :get then Net::HTTP::Get.new(uri)
end
req['Authorization'] = "Bearer #{token}"
req['Content-Type'] = 'application/json'
req.body = body.to_json if body
JSON.parse(http.request(req).body)['data']
end
# Step 1 - Add domain
domain_data = api_request(:post, '/api/v1/public/domains/add-domain',
{ domain: 'mail.yourdomain.com', region: 'us-east-1' })
domain_id = domain_data['id']
puts "DNS records: #{domain_data['dns_records']}"
# Step 2 - Poll until verified
loop do
sleep 10
status = api_request(:get, "/api/v1/public/domains/domain-status/#{domain_id}")['verification_status']
puts "Status: #{status}"
break if status == 'verified'
end
# Step 3 - Create sending API key
# expires_at is optional - ISO 8601 e.g. '2026-12-31T23:59:59Z'
sending_key = api_request(:post, '/api/v1/public/domains/api-keys/create',
{ name: 'My App Sending Key', custom_domain_id: domain_id })['secret_key']
puts "Sending key (store this!): #{sending_key}"
# Step 4 - Send email
result = api_request(:post, '/api/v1/send-email/instant',
{ from: '[email protected]', to: [{ email: '[email protected]' }],
subject: 'Hello from my domain', html: '<p>It works!</p>' },
token: sending_key)
puts "Sent: #{result}"Sending a Transactional Email
A minimal example for sending a single transactional email with an existing Regular API key.
curl -X POST https://api.keplars.com/api/v1/send-email/instant \
-H "Authorization: Bearer $KEPLARS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": [{"email": "[email protected]"}],
"subject": "Your verification code",
"html": "<p>Your code is <strong>482910</strong></p>"
}'await fetch('https://api.keplars.com/api/v1/send-email/instant', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.KEPLARS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: '[email protected]',
to: [{ email: '[email protected]', name: 'User' }],
subject: 'Your verification code',
html: '<p>Your code is <strong>482910</strong></p>',
}),
});import os, requests
requests.post(
'https://api.keplars.com/api/v1/send-email/instant',
headers={'Authorization': f'Bearer {os.environ["KEPLARS_API_KEY"]}'},
json={
'from': '[email protected]',
'to': [{'email': '[email protected]'}],
'subject': 'Your verification code',
'html': '<p>Your code is <strong>482910</strong></p>',
},
)body := `{"from":"[email protected]","to":[{"email":"[email protected]"}],"subject":"Your verification code","html":"<p>Your code is <strong>482910</strong></p>"}`
req, _ := http.NewRequest("POST", "https://api.keplars.com/api/v1/send-email/instant", strings.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("KEPLARS_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)using var http = new HttpClient();
var result = await http.PostAsJsonAsync(
"https://api.keplars.com/api/v1/send-email/instant",
new {
from = "[email protected]",
to = new[] { new { email = "[email protected]" } },
subject = "Your verification code",
html = "<p>Your code is <strong>482910</strong></p>",
});var body = """
{"from":"[email protected]","to":[{"email":"[email protected]"}],
"subject":"Your verification code","html":"<p>Your code is <strong>482910</strong></p>"}
""";
var req = HttpRequest.newBuilder(URI.create("https://api.keplars.com/api/v1/send-email/instant"))
.header("Authorization", "Bearer " + System.getenv("KEPLARS_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());await http.post(
Uri.parse('https://api.keplars.com/api/v1/send-email/instant'),
headers: {
'Authorization': 'Bearer ${Platform.environment['KEPLARS_API_KEY']}',
'Content-Type': 'application/json',
},
body: jsonEncode({
'from': '[email protected]',
'to': [{'email': '[email protected]'}],
'subject': 'Your verification code',
'html': '<p>Your code is <strong>482910</strong></p>',
}),
);<?php
$ch = curl_init('https://api.keplars.com/api/v1/send-email/instant');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KEPLARS_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'from' => '[email protected]',
'to' => [['email' => '[email protected]']],
'subject' => 'Your verification code',
'html' => '<p>Your code is <strong>482910</strong></p>',
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);require 'net/http'
require 'json'
uri = URI('https://api.keplars.com/api/v1/send-email/instant')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Bearer #{ENV['KEPLARS_API_KEY']}"
req['Content-Type'] = 'application/json'
req.body = {
from: '[email protected]',
to: [{ email: '[email protected]' }],
subject: 'Your verification code',
html: '<p>Your code is <strong>482910</strong></p>',
}.to_json
http.request(req)