> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mailbreeze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust SDK

> Official Rust SDK for MailBreeze

## Installation

Add to your `Cargo.toml`:

```toml theme={null}
[dependencies]
mailbreeze = "0.1"
tokio = { version = "1", features = ["full"] }
```

## Requirements

* Rust 1.70+
* Tokio async runtime

## Quick Start

```rust theme={null}
use mailbreeze::{MailBreeze, SendEmailParams};

#[tokio::main]
async fn main() -> mailbreeze::Result<()> {
    let client = MailBreeze::new(std::env::var("MAILBREEZE_API_KEY")?)?;

    let email = client.emails.send(&SendEmailParams {
        from: "hello@yourdomain.com".to_string(),
        to: vec!["user@example.com".to_string()],
        subject: Some("Welcome!".to_string()),
        html: Some("<h1>Welcome to our platform!</h1>".to_string()),
        ..Default::default()
    }).await?;

    println!("Email sent: {}", email.id);
    Ok(())
}
```

## Configuration

```rust theme={null}
use mailbreeze::MailBreeze;
use std::time::Duration;

let client = MailBreeze::builder("sk_live_xxx")
    .base_url("https://api.mailbreeze.com")  // Optional
    .timeout(Duration::from_secs(30))        // Optional
    .max_retries(3)                          // Optional
    .build()?;
```

## Resources

### Emails

```rust theme={null}
// Send email
let email = client.emails.send(&SendEmailParams {
    from: "hello@yourdomain.com".to_string(),
    to: vec!["user@example.com".to_string()],
    subject: Some("Hello".to_string()),
    html: Some("<p>Hello!</p>".to_string()),
    ..Default::default()
}).await?;

// Send with template
let email = client.emails.send(&SendEmailParams {
    from: "hello@yourdomain.com".to_string(),
    to: vec!["user@example.com".to_string()],
    template_id: Some("welcome-template".to_string()),
    variables: Some(json!({"name": "John"})),
    ..Default::default()
}).await?;

// List emails
let result = client.emails.list(&ListEmailsParams {
    status: Some("delivered".to_string()),
    page: Some(1),
    limit: Some(20),
    ..Default::default()
}).await?;

for email in result.items {
    println!("{:?}", email.subject);
}

// Get email
let email = client.emails.get("msg_xxx").await?;

// Get stats
let stats = client.emails.stats().await?;
println!("Total: {}, Sent: {}, Success rate: {}%", stats.total, stats.sent, stats.success_rate);
```

### Attachments

```rust theme={null}
// Create upload URL
let upload = client.attachments.create_upload_url(&CreateUploadParams {
    filename: "report.pdf".to_string(),
    content_type: "application/pdf".to_string(),
    size: 1024000,
}).await?;

// Upload file to the provided URL
let file_data = std::fs::read("report.pdf")?;
reqwest::Client::new()
    .put(&upload.upload_url)
    .header("Content-Type", "application/pdf")
    .body(file_data)
    .send()
    .await?;

// Confirm upload
client.attachments.confirm(&upload.upload_token).await?;

// Use attachment_id in email
```

### Lists

```rust theme={null}
// Create list
let list = client.lists.create(&CreateListParams {
    name: "Newsletter".to_string(),
    description: Some("Weekly newsletter subscribers".to_string()),
}).await?;

// List all
let result = client.lists.list(&ListListsParams::default()).await?;

// Get, update, delete
let list = client.lists.get("lst_xxx").await?;
let list = client.lists.update("lst_xxx", &UpdateListParams {
    name: Some("New Name".to_string()),
    ..Default::default()
}).await?;
client.lists.delete("lst_xxx").await?;

// Get stats
let stats = client.lists.stats("lst_xxx").await?;
```

### Contacts

```rust theme={null}
// Create contact
let contact = client.contacts.create(&CreateContactParams {
    list_id: "lst_xxx".to_string(),
    email: "user@example.com".to_string(),
    first_name: Some("John".to_string()),
    last_name: Some("Doe".to_string()),
    ..Default::default()
}).await?;

// List contacts
let result = client.contacts.list(&ListContactsParams {
    list_id: "lst_xxx".to_string(),
    ..Default::default()
}).await?;

// Get, update, delete
let contact = client.contacts.get("cnt_xxx").await?;
let contact = client.contacts.update("cnt_xxx", &UpdateContactParams {
    first_name: Some("Jane".to_string()),
    ..Default::default()
}).await?;
client.contacts.delete("cnt_xxx").await?;

// Unsubscribe contact
client.contacts.unsubscribe("cnt_xxx").await?;
```

### Verification

```rust theme={null}
// Verify single email
let result = client.verification.verify("user@example.com").await?;
if result.is_valid {
    println!("Safe to send");
}

// Batch verify
let batch = client.verification.batch(vec![
    "user1@example.com".to_string(),
    "user2@example.com".to_string(),
]).await?;

// Poll for results
let status = client.verification.get(&batch.verification_id).await?;

// List and stats
let result = client.verification.list(None).await?;
let stats = client.verification.stats().await?;
```

## Error Handling

```rust theme={null}
use mailbreeze::{MailBreeze, Error};

match client.emails.send(&params).await {
    Ok(email) => println!("Sent: {}", email.id),
    Err(Error::Api { code, message, status }) => {
        println!("API Error: {} - {}", code, message);

        // Handle specific errors
        match code.as_str() {
            "DNS_VERIFICATION_FAILED" => {
                // Domain not verified
            }
            "RATE_LIMIT_EXCEEDED" => {
                // Retry after delay
            }
            _ => {}
        }
    }
    Err(Error::Network(e)) => {
        println!("Network error: {}", e);
    }
    Err(Error::Timeout) => {
        println!("Request timed out");
    }
    Err(e) => {
        println!("Other error: {}", e);
    }
}
```

## Error Types

| Type                                      | Description           |
| ----------------------------------------- | --------------------- |
| `Error::Api { code, message, status }`    | API returned an error |
| `Error::Network(reqwest::Error)`          | Network/HTTP error    |
| `Error::Timeout`                          | Request timed out     |
| `Error::Serialization(serde_json::Error)` | JSON parse error      |
| `Error::Configuration(String)`            | Invalid configuration |

## Features

* **Async/await** - Full async with Tokio
* **Type-safe** - Serde for serialization
* **thiserror** - Custom error types
* **Automatic retries** - Exponential backoff
* **API key redaction** - Keys hidden in Debug output
* **Comprehensive tests**

## Links

<CardGroup cols={2}>
  <Card title="crates.io" icon="rust" href="https://crates.io/crates/mailbreeze">
    View on crates.io
  </Card>

  <Card title="GitHub" icon="github" href="https://github.com/MailBreeze/mailbreeze-rust">
    Source code
  </Card>
</CardGroup>
