Keplars

Rust

Official Rust SDK for Keplars

Installation

Add to Cargo.toml

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

Set your API key

export KEPLARS_API_KEY=kms_your_workspace_id.live_your_secret

Send your first email

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

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

    let response = client.emails().send_instant(SendEmailRequest {
        to: ToRecipient::Email("[email protected]".to_string()),
        from: "[email protected]".to_string(),
        subject: "Hello!".to_string(),
        body: Some("<h1>It works!</h1>".to_string()),
        is_html: Some(true),
        ..Default::default()
    }).await?;

    println!("ID: {}", response.id);
    Ok(())
}

Usage Examples

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

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

    send_welcome_email(&client, "[email protected]", "John").await?;
    send_verification_email(&client, "[email protected]", "123456").await?;

    Ok(())
}

async fn send_welcome_email(
    client: &Keplars,
    user_email: &str,
    user_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let response = client.emails().send_async(SendEmailRequest {
        to: ToRecipient::Email(user_email.to_string()),
        from: "[email protected]".to_string(),
        subject: format!("Welcome {}!", user_name),
        body: Some(format!("<h1>Welcome {}!</h1><p>Thank you for joining.</p>", user_name)),
        is_html: Some(true),
        ..Default::default()
    }).await?;

    println!("Welcome email queued: {}", response.id);
    Ok(())
}

async fn send_verification_email(
    client: &Keplars,
    user_email: &str,
    code: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let response = client.emails().send_instant(SendEmailRequest {
        to: ToRecipient::Email(user_email.to_string()),
        from: "[email protected]".to_string(),
        subject: "Verify Your Email".to_string(),
        body: Some(format!("Your verification code: {}", code)),
        is_html: Some(false),
        ..Default::default()
    }).await?;

    println!("Verification email sent: {}", response.id);
    Ok(())
}

Axum Integration

use axum::{extract::{Json, State}, http::StatusCode, routing::post, Router};
use keplars::{Keplars, SendEmailRequest, ToRecipient};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Deserialize)]
struct EmailPayload {
    email: String,
    name: String,
}

#[derive(Serialize)]
struct ApiResponse {
    success: bool,
    message: String,
}

async fn send_welcome_handler(
    State(client): State<Arc<Keplars>>,
    Json(payload): Json<EmailPayload>,
) -> Result<Json<ApiResponse>, StatusCode> {
    let response = client.emails().send_async(SendEmailRequest {
        to: ToRecipient::Email(payload.email),
        from: "[email protected]".to_string(),
        subject: format!("Welcome {}!", payload.name),
        body: Some(format!("<h1>Welcome {}!</h1>", payload.name)),
        is_html: Some(true),
        ..Default::default()
    }).await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(ApiResponse {
        success: true,
        message: format!("Email queued: {}", response.id),
    }))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Arc::new(Keplars::new(&std::env::var("KEPLARS_API_KEY")?)?);

    let app = Router::new()
        .route("/send-welcome", post(send_welcome_handler))
        .with_state(client);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
    axum::serve(listener, app).await?;
    Ok(())
}

Priority Levels

MethodDeliveryUse case
send_instant0–5 secondsOTP, 2FA, password reset
send_high0–30 secondsTransactional confirmations
send_async / send0–5 minutesWelcome emails, notifications
send_bulkBackgroundNewsletters, campaigns
client.emails().send_instant(req).await?;
client.emails().send_high(req).await?;
client.emails().send_async(req).await?;
client.emails().send_bulk(req).await?;

Using Templates

let response = client.emails().send_instant(SendEmailRequest {
    to:          ToRecipient::Email("[email protected]".to_string()),
    from:        "[email protected]".to_string(),
    template_id: Some("your-template-id".to_string()),
    params:      Some([
        ("user_name".to_string(),         serde_json::json!("Jane")),
        ("verification_code".to_string(), serde_json::json!("123456")),
    ].into()),
    ..Default::default()
}).await?;

Schedule an Email

use keplars::ScheduleEmailRequest;

let response = client.emails().schedule(ScheduleEmailRequest {
    from:          "[email protected]".to_string(),
    to:            ToRecipient::Email("[email protected]".to_string()),
    subject:       "Weekly digest".to_string(),
    body:          Some("<p>Here is your digest.</p>".to_string()),
    is_html:       Some(true),
    scheduled_for: "2026-02-01T09:00:00Z".to_string(),
    timezone:      Some("America/New_York".to_string()),
    ..Default::default()
}).await?;

Error Handling

use keplars::error::KeplarsError;

match client.emails().send_instant(req).await {
    Ok(response) => println!("Sent: {}", response.id),
    Err(KeplarsError::Authentication(e)) => eprintln!("Invalid API key: {}", e),
    Err(KeplarsError::RateLimit(e)) => eprintln!("Rate limit, retry after: {:?}", e.retry_after),
    Err(KeplarsError::Validation(e)) => eprintln!("Validation: {}", e),
    Err(e) => return Err(e.into()),
}

Admin API

Need to manage contacts, audiences, automations, or domains? Use an admin key - same client, different key suffix:

let client = Keplars::new("kms_xxx.adm_xxx")?;

client.contacts().add(AddContactRequest { email: "[email protected]".into(), ..Default::default() }).await?;
client.audiences().create("Newsletter", None).await?;
client.automations().enroll("auto_id", "[email protected]").await?;
client.domains().verify("domain_id").await?;

See the full Admin API reference.

Next Steps

On this page