alguna is the official Rust client for the Alguna Public API. It has one async method for each endpoint, with request and response types generated from the versioned OpenAPI spec. Use it from Rust services where you would otherwise write HTTP calls by hand. It sets the Authorization and Alguna-Version headers, maps failed responses to typed errors, sends an idempotency key on writes, and retries a call only when a retry is safe. The objects it handles are described in How Alguna works.
The SDK is for servers only. API keys are secret, so never ship them to a browser or a client app. To embed a purchase flow in your frontend, use Embedded Checkout. Your server creates the session with this SDK, and your frontend mounts it.
How it works
- Create an API key under Settings → Connections → Developers → API keys. A key looks like
<key_id>.<key_secret>. It is a server secret. - Build the client with the key. Every request carries
Authorization: Bearerand theAlguna-Versionheader. - Call resources (
client.customers,client.subscriptions, and so on). A method returns a typed response, or anApiError.
Installation
tokio. It uses rustls for TLS. The crate is alguna on crates.io. The API docs are on docs.rs. The source is alguna-io/alguna-rust on GitHub.
build() returns ApiError::Configuration and sends nothing.
Quick start: customer → subscription → invoice → portal session
A subscription starts in
draft status. Pass auto_activate: Some(true) (as above) or call client.subscriptions.activate when you are ready to go live. See Creating a Subscription for the full set of patterns: plans, overrides and bundles all work the same way through the SDK.Resources
Each API resource is a field of the client. The client is generated from the versioned spec, so every public operation has a method. A method takes a reference to its request and an optionalRequestOptions. Method names are in snake_case. Highlights:
Other resources include
products, plans, bundles, subscription_versions, subscription_changes, checkout_sessions, wallets, wallet_grants, credit_notes, payments, refunds, quotes and metrics. Every method name follows the operation it wraps. The full list is in the API reference.
Request and response types are in alguna::prelude::*. Optional fields are Option. Request structs implement Default, so use ..Default::default() for fields you do not set. Every method takes Option<RequestOptions> as its last argument. RequestOptions can set api_version, idempotency_key, timeout_seconds, max_retries, api_key, additional_header and additional_query_param for one call.
Pagination
list returns one page of results in data. list_paginated returns a Stream of every item. It loads the next page when the stream needs it. Add futures = "0.3" to your dependencies for StreamExt.
limit. The filters match the HTTP API.
PDF downloads
invoices.generate_pdf and subscriptions.download_pdf return a ByteStream. Call collect().await to read the whole file into a Vec<u8>. Call try_next().await to read it in chunks.
Error handling
Every call returnsResult<_, ApiError>. ApiError is #[non_exhaustive], so keep a wildcard arm. The API error variants are:
Most of these carry
message and the optional detail, status, title and type_ fields of the error body. Other variants cover a failure with no API response: Network (the cause is the error’s source()), Serialization and Configuration.
detail, else its title, else its message, else the HTTP status text. For the body format and the error codes, see Errors.
Idempotency and retries
Every request other than a GET carries anIdempotency-Key header. The SDK makes a UUID v4 key for each call and sends the same key on every retry of that call, so the API acts once. See Idempotency for how the API treats keys. To make a call safe to repeat later, for example after your process stops, set your own key:
events.ingest, credits.check and credits.track are different. The API identifies their work by the request body, so the SDK makes no key for them and still retries them. The API removes duplicate events by unique_id. A key that you set is sent on every attempt. credits.check with reserve needs your key, because the key identifies the hold.
By default the SDK retries a call 2 times (3 attempts in total) after:
- a network error: the connection is refused, reset or closed before the response, or the attempt times out;
- a 408, 429, 502, 503 or 504 response;
- a 409 response with
Retry-After. The API sends it while a request with the same idempotency key is still running. Any other 409 is a conflict, and the SDK does not retry it.
Retry-After (seconds or an HTTP date), the retry waits that long, up to 60 seconds. Set max_retries on the builder or on RequestOptions. 0 turns retries off.
To stop a call, drop its future, for example with tokio::time::timeout. A dropped call makes no more attempts.
Configuration
ClientConfig to Alguna::new. Other builder methods are custom_header, custom_headers, user_agent and reqwest_client. A custom reqwest_client keeps its own timeout and transport settings.
Pass api_version to pin the version your integration is written against. Without it, the SDK sends the version it was generated from, so upgrading the crate can move you to a newer API version. See Versioning.
FAQ
Can I use the SDK in a browser or client app? No. It authenticates with your secret API key. For browser purchase flows, create a checkout session on your server and mount it with Embedded Checkout. Does the SDK cover every endpoint? Yes. The client is generated from the versioned OpenAPI spec, so every operation in the API reference has a method. Are there types for webhook payloads? Yes. Each eventtype has a payload type in the crate, such as WebhookPaymentCreatedPayload for payment.created. The SDK does not verify signatures. Before you trust a payload, verify its svix-id, svix-timestamp and svix-signature headers with the svix crate, as Verifying signatures shows.
How do I point it at the sandbox?
Use ApiClientBuilder::new("https://api.sandbox.alguna.io") with a sandbox API key. Sandbox and production are separate environments with separate keys. See Base URLs.
Which version am I on, and how does it relate to the API version?
They are different. The crate version is the release of alguna on crates.io. The API version is the date sent as Alguna-Version, and it alone decides request and response shapes. When you pass api_version, upgrading the crate does not change the API version. Change it on purpose, as its own change, following Versioning.
Is there an SDK for another language?
Yes. There are TypeScript, Python and Go SDKs and an alguna CLI. See SDKs and CLI.