Install the SDK
cargo add groundmail
cargo add tokio --features macros,rt-multi-threadConfigure your API key
export GROUNDMAIL_API_KEY=gm_your_key_hereSend an email
use groundmail::{Client, SendEmail};
#[tokio::main]
async fn main() -> Result<(), groundmail::Error> {
let client = Client::from_env()?;
let email = SendEmail::new("ops@yourdomain.com", "user@example.com", "Your receipt")
.html("<p>Thanks for your purchase.</p>")
.idempotency_key("receipt-order-1042");
let sent = client.emails().send(&email).await?;
println!("{} {}", sent.id, sent.status);
Ok(())
}Retrying with the same idempotency key returns the first result instead of sending twice. Set any other POST /emails field with .field("tags", json!(["receipt"])).
Handle errors
API errors keep their status, message and code:
match client.emails().send(&email).await {
Ok(sent) => println!("{}", sent.id),
Err(groundmail::Error::Api { status, message, code, .. }) => {
eprintln!("{status} {code:?}: {message}");
}
Err(other) => eprintln!("{other}"),
}Verify webhooks
Pass the raw request body, before parsing it, and the Groundmail-Signature header:
let valid = groundmail::verify_webhook_signature(&secret, &body, &signature_header);Other resources
The client also has client.domains(), client.webhooks(), client.templates() and client.suppressions(). Reach any other endpoint with client.request(method, path, body).