Quickstart
Quickstart: create an invoice in Rust
No official SDK — use reqwest + serde_json
No official Rust SDK for Scell.io. Standard combo: `reqwest` (async/blocking HTTP client) + `serde` + `serde_json`. Compatible with Tokio and async-std. For production, add `reqwest-middleware` + `reqwest-retry` (exponential retries). JSON snake_case serialization works natively with `#[derive(Serialize, Deserialize)]`. Ideal for microservices, Tauri (desktop), or serverless (Cloudflare Workers via `worker-rs`). Target: stable Rust (2021 edition+).
Key facts
- Requirements: Rust stable 1.75+, Cargo
- No official SDK: `reqwest` + `serde_json`
- Env var: `std::env::var("SCELL_API_KEY")`
- HTTP: `reqwest` 0.12+ (with `json` feature)
- Expected output: `serde_json::Value` or typed struct
- Error codes: `response.error_for_status()` + `Result<T, reqwest::Error>`
Code example
// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }
// tokio = { version = "1", features = ["full"] }
// serde_json = "1"
// uuid = { version = "1", features = ["v4"] }
use serde_json::{json, Value};
use uuid::Uuid;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = std::env::var("SCELL_API_KEY")?;
let http = reqwest::Client::new();
let call = |path: &'static str, body: Value| {
let http = http.clone();
let key = key.clone();
async move {
let r = http.post(format!("https://api.scell.io/api/v1{}", path))
.header("X-API-Key", &key)
.header("Idempotency-Key", Uuid::new_v4().to_string())
.json(&body).send().await?.error_for_status()?
.json::<Value>().await?;
Ok::<Value, reqwest::Error>(r)
}
};
let seller = json!({
"siret": "12345678901234", "name": "Ma SAS", "vat_number": "FR12345678901",
"address": {"street": "1 rue Test", "city": "Paris", "postal_code": "75001", "country": "FR"}
});
let b2b = call("/invoices", json!({
"format": "factur-x", "profile": "EN16931", "currency": "EUR", "seller": seller,
"buyer": {"siret": "98765432109876", "name": "Client SARL",
"address": {"street": "2 avenue Demo", "city": "Lyon", "postal_code": "69001", "country": "FR"}},
"lines": [{"description": "Prestation conseil", "quantity": 1, "unit_price": 1000.0, "vat_rate": 20.0}]
})).await?;
println!("B2B: {} ({})", b2b["id"], b2b["status"]);
let b2c = call("/invoices", json!({
"format": "factur-x", "profile": "EN16931", "currency": "EUR", "seller": seller,
"buyer": {"buyer_is_individual": true, "name": "Jean Dupont", "email": "jean@example.com",
"address": {"street": "3 bd Client", "city": "Marseille", "postal_code": "13001", "country": "FR"}},
"lines": [{"description": "Abonnement", "quantity": 1, "unit_price": 49.90, "vat_rate": 20.0}]
})).await?;
println!("B2C: {} ({})", b2c["id"], b2c["status"]);
let sig = call("/signatures", json!({
"document_url": "https://example.com/contrat.pdf",
"signers": [{"name": "Jean Dupont", "email": "jean@example.com", "phone": "+33612345678"}],
"signature_options": {"signature_mode": "drawn", "timezone": "Europe/Paris"}
})).await?;
println!("Signature: {} -> {}", sig["id"], sig["signing_url"]);
Ok(())
}