blooio
Typed, low-overhead Rust bindings for the Blooio API (iMessage / SMS automation), exposing both an async and a blocking surface from a single sans-IO core. Sync users pull no async runtime.
Features
| Feature | Default | Description |
|---|---|---|
async |
✅ | The async Client executor (reqwest). |
sync |
The blocking BlockingClient executor (ureq), no tokio. |
|
rustls |
✅ | TLS via rustls. |
native-tls |
TLS via the system's native stack. | |
webhooks |
✅ | Typed webhook payloads + HMAC signature verification. |
axum |
Verified axum webhook extractor; implies webhooks. |
|
actix |
Verified actix-web webhook extractor; implies webhooks. |
|
tracing |
✅ | Secret-redacted request instrumentation. |
At least one of async / sync must be enabled (enforced at compile time).
Install
[]
= "0.2"
Blocking client only, no async runtime:
[]
= { = "0.2", = false, = ["sync", "rustls", "webhooks"] }
Quick start (async)
use Client;
async
Quick start (blocking)
use BlockingClient;
The async and blocking surfaces are mirror images: the same resource handles and
method names, differing only by .await.
Resources
Resource handles hang off the client and group the endpoints:
| Handle | Highlights |
|---|---|
account() |
get |
chats() / chat(id) |
list, send/send_text, messages, reactions, polls, typing, read receipts, backgrounds |
contacts() |
list, create, get, update, delete, capabilities, tags |
groups() |
list, create, get, update, delete, icons, members(id) |
contact_card() |
get, update |
facetime() |
call |
location() |
list, get, refresh |
numbers() |
list |
phone_numbers() |
lookup, lookup_post, batch |
webhooks() |
list, create, get, update, delete, rotate_secret, logs(id) |
Builders
Endpoints with many optional fields use a fluent builder. For example, sending a message:
# async
Pagination
List endpoints expose a *_all paginator that fetches successive pages lazily:
# async
In the blocking client, the paginator also implements Iterator.
With the async client, a paginator can also be converted into a Stream:
# async
Escape hatch
Every endpoint is described once as a public Operation. Anything not covered
by a convenience method can be sent directly:
# async
Configuration
Client::new(key) uses production defaults. For more control, build a
ClientConfig:
use ;
use Duration;
#
Applications that already own an HTTP client can reuse it:
use ;
#
The API key is wrapped in a Secret, which zeroizes on drop and redacts itself
in Debug output (api_key: [REDACTED]) — it is never logged or serialized in
cleartext.
Retries and rate limits
Transient failures are retried by default with jittered backoff. Customize that
behavior with ClientConfig::with_retry, or pass RetryPolicy::none() to
disable it.
Use send_with_meta to inspect response metadata such as rate-limit headers and
Retry-After:
# async
Errors
All fallible calls return blooio::Result<T>. The Error enum distinguishes
Api (non-2xx, with a machine-readable code), Transport, Encode,
Decode, and (with webhooks) Webhook. Match on the stable code for
programmatic handling:
#
Webhooks
With the webhooks feature, verify and parse incoming events. The module is
framework-agnostic, and the optional axum and actix features add verified
server extractors:
use ;
#
For an axum app, put a WebhookVerifier in router state and accept
VerifiedWebhook in the handler:
#
# async
Tracing
With the tracing feature, each request emits a blooio.request span carrying
the method, path, status, and elapsed time. The API key is never recorded.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.