euromail 0.1.0

Official Rust SDK for EuroMail transactional email service
Documentation

EuroMail Rust SDK

Official Rust SDK for the EuroMail transactional email service.

Installation

Add to your Cargo.toml:

[dependencies]
euromail = "0.1"

Quick Start

use euromail::{EuroMail, SendEmailParams};

#[tokio::main]
async fn main() -> Result<(), euromail::EuroMailError> {
    let client = EuroMail::new("your-api-key");

    let params = SendEmailParams {
        from: "you@yourdomain.com".to_string(),
        to: "recipient@example.com".to_string(),
        subject: Some("Hello from EuroMail".to_string()),
        html_body: Some("<h1>Welcome!</h1><p>Thanks for signing up.</p>".to_string()),
        text_body: None,
        cc: None,
        bcc: None,
        reply_to: None,
        template_alias: None,
        template_data: None,
        headers: None,
        tags: None,
        metadata: None,
        attachments: None,
        idempotency_key: None,
    };

    let response = client.send_email(&params).await?;
    println!("Sent! ID: {}", response.id);

    Ok(())
}

Usage

Account

let account = client.get_account().await?;
println!("Plan: {}, Quota: {}", account.plan, account.monthly_quota);

Sending Emails

// Single email
let response = client.send_email(&params).await?;

// Batch send
let batch = SendBatchParams {
    emails: vec![params1, params2],
};
let batch_response = client.send_batch(&batch).await?;

Templates

use euromail::{CreateTemplateParams, UpdateTemplateParams};

let template = client.create_template(&CreateTemplateParams {
    alias: "welcome".to_string(),
    name: "Welcome Email".to_string(),
    subject: "Welcome, {{name}}!".to_string(),
    html_body: Some("<h1>Welcome, {{name}}!</h1>".to_string()),
    text_body: None,
}).await?;

let templates = client.list_templates(None).await?;

Domains

let domain = client.add_domain("mail.example.com").await?;
let verification = client.verify_domain(&domain.id).await?;
if verification.fully_verified {
    println!("Domain verified!");
}

Webhooks

use euromail::CreateWebhookParams;

let webhook = client.create_webhook(&CreateWebhookParams {
    url: "https://example.com/webhook".to_string(),
    events: vec!["delivered".to_string(), "bounced".to_string()],
}).await?;

Suppressions

client.add_suppression("spam@example.com", None).await?;
client.delete_suppression("spam@example.com").await?;
let suppressions = client.list_suppressions(None).await?;

Contact Lists

use euromail::{CreateContactListParams, AddContactParams, BulkAddContactsParams};

let list = client.create_contact_list(&CreateContactListParams {
    name: "Newsletter".to_string(),
    description: Some("Monthly newsletter subscribers".to_string()),
    double_opt_in: Some(true),
}).await?;

let contact = client.add_contact(&list.id, &AddContactParams {
    email: "user@example.com".to_string(),
    metadata: None,
}).await?;

let bulk = client.bulk_add_contacts(&list.id, &BulkAddContactsParams {
    contacts: vec![
        AddContactParams { email: "a@example.com".to_string(), metadata: None },
        AddContactParams { email: "b@example.com".to_string(), metadata: None },
    ],
}).await?;

Analytics

use euromail::AnalyticsQuery;

let overview = client.get_analytics_overview(Some(&AnalyticsQuery {
    period: Some("30d".to_string()),
    from: None,
    to: None,
})).await?;

let csv = client.export_analytics_csv(None).await?;

Audit Logs

let logs = client.list_audit_logs(None).await?;
for log in &logs.data {
    println!("{}: {} on {}", log.created_at, log.action, log.resource_type);
}

Error Handling

All methods return Result<T, EuroMailError>. Error variants:

  • Authentication - Invalid or missing API key (401)
  • Validation - Invalid request parameters (422)
  • RateLimit - Too many requests, includes retry_after hint (429)
  • NotFound - Resource does not exist (404)
  • Api - Other API errors (4xx/5xx)
  • Http - Network / transport errors
match client.get_account().await {
    Ok(account) => println!("Account: {}", account.name),
    Err(EuroMailError::RateLimit { retry_after, .. }) => {
        if let Some(secs) = retry_after {
            tokio::time::sleep(std::time::Duration::from_secs(secs)).await;
        }
    }
    Err(e) => eprintln!("Error: {e}"),
}

License

MIT