Keplars

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:manage and api-keys:create scopes
  • 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)

On this page