Rust SDK
The official camelmailer-rs crate is async-first (reqwest + rustls, no OpenSSL), fully typed with a builder API, and ships an optional blocking client. MSRV 1.75.
Install
terminal
cargo add camelmailer-rs tokio --features tokio/full
Quickstart
main.rs
use camelmailer_rs::{CamelMailer, SendEmailRequest};
#[tokio::main]
async fn main() -> Result<(), camelmailer_rs::Error> {
let client = CamelMailer::new("cm_xxxxxxxx");
let email = SendEmailRequest::builder()
.from("billing@acme.com")
.to("ada@example.com")
.subject("Your receipt")
.html_body("<h1>Thanks for your purchase!</h1>")
.build();
let result = client.emails().send(email).await?;
println!("queued: {:?}", result.message_id);
Ok(())
}Send with a template
template.rs
let result = client.emails().send_with_template(
SendTemplateRequest::builder("welcome")
.from("hello@acme.com")
.to("ada@example.com")
.model(serde_json::json!({ "name": "Ada", "product": "Acme" }))
.build(),
).await?;Error handling
Every API error carries the stable error code from the response envelope; network failures are Error::Network.
errors.rs
match client.emails().get(42).await {
Ok(detail) => println!("{:?}", detail.message.status),
Err(error) if error.is_not_found() => println!("no such message"),
Err(Error::Api { code, message, status }) => {
eprintln!("API error {code} (HTTP {status}): {message}")
}
Err(Error::Network(source)) => eprintln!("network trouble: {source}"),
Err(other) => return Err(other.into()),
}Self-hosted instances
The client talks to the cloud (https://app.camelmailer.com) by default. Use the builder to point at your own instance:
self-hosted.rs
let client = camelmailer_rs::CamelMailer::builder("cm_xxxxxxxx")
.base_url("https://mail.example.com")
.build()?;No async runtime? Enable the
blocking feature for camelmailer_rs::blocking::CamelMailer. Full field reference: Messages API.