keplars 2.1.0

Official Rust SDK for Keplars Email API
Documentation
# Keplars Rust SDK

Official Rust SDK for [Keplars](https://keplars.com) — a modern transactional email API.

## Installation

Add to your `Cargo.toml`:

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

## Quick Start

```rust
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

```rust
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:

```bash
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

```rust
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

```rust
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

```rust
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

```rust
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:

```rust
let admin = Keplars::new("kms_your_key_id.adm_your_secret")?;
```

```rust
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

```rust
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

```rust
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

```rust
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

```rust
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