cybertemp 0.1.0

Rust SDK for CyberTemp — disposable email inboxes for testing, automation, OTP flows, and AI agents.
Documentation
# cybertemp

[![crates.io](https://img.shields.io/crates/v/cybertemp.svg)](https://crates.io/crates/cybertemp)
[![docs.rs](https://docs.rs/cybertemp/badge.svg)](https://docs.rs/cybertemp)
[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](#license)

Async Rust SDK for [CyberTemp](https://cybertemp.xyz) — disposable email inboxes for testing, automation, OTP flows, and AI agents.

- Spin up a temp inbox in one call
- Poll for incoming mail with a sane timeout
- Pull a one-time code out of the body without parsing HTML yourself
- Typed errors for upgrade-required and rate-limited responses

Built on `reqwest` + `tokio` with `rustls` (no OpenSSL dependency).

## Install

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

Or:

```bash
cargo add cybertemp
cargo add tokio --features full
```

You'll need an API key — get one at <https://www.cybertemp.xyz/settings>.

## Quickstart

```rust
use cybertemp::Client;
use std::time::Duration;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = Client::new("tk_...");

    let inbox = client.create_inbox().await?;
    println!("inbox: {}", inbox.address);

    // Block until something arrives or 30s passes
    let otp = client.wait_for_otp(&inbox.id, Duration::from_secs(30)).await?;
    println!("OTP: {otp}");

    client.delete_inbox(&inbox.id).await?;
    Ok(())
}
```

## API

```rust
// Create a fresh disposable address
client.create_inbox().await?;

// Inboxes owned by your API key
client.list_inboxes().await?;

// Most recent first
client.read_messages(&inbox.id, /* limit */ 25, /* offset */ 0).await?;

// Polls until a message arrives or the timeout elapses
client.wait_for_message(&inbox.id, Duration::from_secs(30)).await?;

// Pro plan and above — extracts a 4–8 digit code from the body
client.wait_for_otp(&inbox.id, Duration::from_secs(30)).await?;

// Frees a slot against your plan limit
client.delete_inbox(&inbox.id).await?;
```

Full type docs live on <https://docs.rs/cybertemp>.

## Errors

`cybertemp::Error` is a typed enum — `Upgrade` and `RateLimited` carry the structured info CyberTemp returns so you can react instead of just retrying blindly:

```rust
use cybertemp::Error;

match client.wait_for_otp(&inbox.id, Duration::from_secs(30)).await {
    Ok(otp) => println!("got {otp}"),

    Err(Error::Upgrade { required_tier, upgrade_url, .. }) => {
        // Free tier hit Pro-gated endpoint
        eprintln!("upgrade to {required_tier:?}");
        if let Some(url) = upgrade_url {
            eprintln!("upgrade at {url}");
        }
    }

    Err(Error::RateLimited { retry_after, .. }) => {
        tokio::time::sleep(retry_after).await;
        // retry…
    }

    Err(e) => return Err(e.into()),
}
```

## Use cases

- **Playwright / Puppeteer tests** — sign up a fresh user every run, intercept the verification email, extract the OTP, click through. No mailbox mocking, no flaky shared inboxes.
- **AI agents** — spin up an inbox per agent task, let it sign up for services and confirm itself.
- **Manual QA** — Burst-create 50 inboxes for a workflow demo, then `delete_inbox` them at the end.

## Links

- Website: <https://www.cybertemp.xyz>
- Get an API key: <https://www.cybertemp.xyz/settings>
- API docs: <https://www.cybertemp.xyz/api-docs>
- Crate docs: <https://docs.rs/cybertemp>

## License

MIT