keplars 2.1.0

Official Rust SDK for Keplars Email API
Documentation

Keplars Rust SDK

Official Rust SDK for Keplars — a modern transactional email API.

Installation

Add to your Cargo.toml:

[dependencies]
keplars = "1.10"
tokio = { version = "1", features = ["full"] }

Quick Start

use keplars::{Keplars, SendEmailRequest, ToRecipient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Keplars::new("kms_your_key_id.live_your_secret")?;

    let response = client.emails().send(SendEmailRequest {
        to: ToRecipient::Email("user@example.com".to_string()),
        from: "noreply@yourdomain.com".to_string(),
        subject: "Welcome!".to_string(),
        html: Some("<h1>Hello!</h1>".to_string()),
        ..Default::default()
    }).await?;

    println!("Sent! Job ID: {}", response.data.job_id);
    Ok(())
}

Configuration

use keplars::{Keplars, KeplarsConfig};
use std::time::Duration;

let client = Keplars::with_config(KeplarsConfig {
    api_key: "kms_your_key_id.live_your_secret".to_string(),
    base_url: "https://api.keplars.com".to_string(),
    timeout: Duration::from_secs(30),
    max_retries: 3,
    retry_delay: Duration::from_secs(1),
})?;

You can also set the API key via environment variable:

export KEPLARS_API_KEY="kms_your_key_id.live_your_secret"

API Key Types

Type Format Used for
Regular kms_<id>.live_<secret> Email sending
Admin kms_<id>.adm_<secret> Contacts, audiences, automations, domains

Sending Emails

Priority Levels

Method Priority Use Case
send_instant Instant OTP, auth codes
send_high High Password reset, alerts
send / send_async Async Welcome emails, notifications
send_bulk Bulk Newsletters, campaigns

Send with HTML

use keplars::{SendEmailRequest, ToRecipient};

client.emails().send_instant(SendEmailRequest {
    to: ToRecipient::Email("user@example.com".to_string()),
    from: "noreply@yourdomain.com".to_string(),
    subject: "Your OTP Code".to_string(),
    html: Some("<h1>Your code: <strong>847291</strong></h1>".to_string()),
    text: Some("Your code: 847291".to_string()),
    ..Default::default()
}).await?;

Send with Template

use std::collections::HashMap;
use serde_json::json;

client.emails().send(SendEmailRequest {
    to: ToRecipient::Email("user@example.com".to_string()),
    from: "noreply@yourdomain.com".to_string(),
    subject: "Welcome!".to_string(),
    template_id: Some("tmpl_welcome_001".to_string()),
    template_data: Some(HashMap::from([
        ("first_name".to_string(), json!("Jane")),
        ("dashboard_url".to_string(), json!("https://app.yourdomain.com")),
    ])),
    ..Default::default()
}).await?;

Send to Multiple Recipients

use keplars::EmailRecipient;

client.emails().send_bulk(SendEmailRequest {
    to: ToRecipient::Recipients(vec![
        EmailRecipient { email: "a@example.com".to_string(), name: None },
        EmailRecipient { email: "b@example.com".to_string(), name: None },
    ]),
    from: "newsletter@yourdomain.com".to_string(),
    subject: "Monthly Update".to_string(),
    html: Some("<h1>Here is what is new</h1>".to_string()),
    ..Default::default()
}).await?;

Schedule an Email

use keplars::ScheduleEmailRequest;

client.emails().schedule(ScheduleEmailRequest {
    email: SendEmailRequest {
        to: ToRecipient::Email("user@example.com".to_string()),
        from: "noreply@yourdomain.com".to_string(),
        subject: "See you tomorrow!".to_string(),
        html: Some("<p>Just a reminder for your meeting.</p>".to_string()),
        ..Default::default()
    },
    scheduled_for: "2026-12-01T09:00:00Z".to_string(),
    timezone: Some("UTC".to_string()),
}).await?;

Contacts

Use an admin key (kms_<id>.adm_<secret>) for contacts, audiences, automations, and domains:

let admin = Keplars::new("kms_your_key_id.adm_your_secret")?;
use keplars::{AddContactRequest, UpdateContactRequest};

// Add
admin.contacts().add(AddContactRequest {
    email: "user@example.com".to_string(),
    name: Some("Jane Doe".to_string()),
    audience_id: None,
}).await?;

// Get
admin.contacts().get("user@example.com").await?;

// List
admin.contacts().list(Some("aud_123"), Some(1), Some(20)).await?;

// Update
admin.contacts().update("user@example.com", UpdateContactRequest {
    name: Some("Jane Smith".to_string()),
    audience_id: None,
}).await?;

// Delete
admin.contacts().delete("user@example.com").await?;

Audiences

admin.audiences().create("Newsletter Subscribers", Some("Main newsletter list")).await?;
admin.audiences().list(Some(1), Some(20)).await?;
admin.audiences().get("aud_123").await?;
admin.audiences().delete("aud_123").await?;

Automations

admin.automations().list(None, None).await?;
admin.automations().get("auto_123").await?;
admin.automations().enroll("auto_123", "user@example.com").await?;
admin.automations().unenroll("auto_123", "user@example.com").await?;

Domains

admin.domains().add("yourdomain.com").await?;
admin.domains().list().await?;
admin.domains().get_status("dom_123").await?;
admin.domains().verify("dom_123").await?;
admin.domains().delete("dom_123").await?;
admin.domains().create_api_key("dom_123", Some("production")).await?;

Error Handling

use keplars::KeplarsError;

match client.emails().send(request).await {
    Ok(response) => println!("Sent: {}", response.data.job_id),
    Err(KeplarsError::Authentication { message, .. }) => {
        eprintln!("Invalid API key: {}", message);
    }
    Err(KeplarsError::RateLimit { retry_after, .. }) => {
        eprintln!("Rate limited, retry after {}s", retry_after);
    }
    Err(KeplarsError::Validation { message, .. }) => {
        eprintln!("Bad request: {}", message);
    }
    Err(KeplarsError::DomainNotVerified { message, .. }) => {
        eprintln!("Domain not verified: {}", message);
    }
    Err(KeplarsError::Network(e)) => {
        eprintln!("Network error: {}", e);
    }
    Err(e) => eprintln!("Error: {}", e),
}

Requirements

  • Rust 1.70+
  • Tokio async runtime

License

MIT