1 # smbcloud-email-sdk
2
3 Rust client for the **smbCloud transactional email API**. Send transactional
4 email from a verified domain and read each message's delivery status.
5
6 The crate handles the HTTP transport and the `Authorization: Bearer <api_key>`
7 header. You build the message and own the content.
8
9 ## Install
10
11 ```toml
12 [dependencies]
13 smbcloud-email-sdk = "0.4"
14 tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
15 ```
16
17 ## Authentication
18
19 Mint a `smb_mail_…` API key for your Mail app in the smbCloud console. Sending is
20 scoped to that app's verified domain; reading messages needs a read-scope key.
21
22 ## Send
23
24 ```rust,no_run
25 use smbcloud_email_sdk::{EmailClient, EmailCredentials, Environment, SendEmail};
26
27 #[tokio::main]
28 async fn main() -> anyhow::Result<()> {
29 let client = EmailClient::from_credentials(
30 Environment::Production,
31 EmailCredentials { api_key: "smb_mail_your_key" },
32 );
33
34 let message = SendEmail::new("billing@example.com", ["customer@acme.com"])
35 .subject("Your receipt")
36 .html("<h1>Thanks!</h1>")
37 .text("Thanks!")
38 .idempotency_key("receipt-2026-0001");
39
40 let sent = client.send(&message).await?;
41 println!("sent {} ({:?})", sent.id, sent.status);
42 Ok(())
43 }
44 ```
45
46 ## Attachments, cc/bcc, headers, tags
47
48 ```rust,no_run
49 # use smbcloud_email_sdk::{Attachment, SendEmail};
50 let message = SendEmail::new("billing@example.com", ["customer@acme.com"])
51 .subject("Invoice")
52 .html("<p>See attached.</p>")
53 .cc(["accounts@acme.com"])
54 .reply_to(["support@example.com"])
55 .attachment(Attachment {
56 filename: "invoice.pdf".into(),
57 content_base64: "JVBERi0xLjQ...".into(),
58 })
59 .header("X-Entity-Ref-ID", "inv_123")
60 .tag("category", "invoice");
61 ```
62
63 ## Read delivery status
64
65 ```rust,no_run
66 # async fn run(client: smbcloud_email_sdk::EmailClient) -> anyhow::Result<()> {
67 let message = client.get_message("eml_…").await?;
68 println!("status: {:?}", message.status);
69 for event in &message.events {
70 println!(" {} at {}", event.event_type, event.occurred_at);
71 }
72
73 let recent = client.list_messages(Some("bounced"), Some(20)).await?;
74 println!("{} bounced", recent.len());
75 # Ok(())
76 # }
77 ```
78
79 ## License
80
81 Apache-2.0