alguna is the official Python client for the Alguna Public API. It has one typed method per endpoint: customers, products and plans, subscriptions, usage events, credits and wallets, invoices, payments, and checkout and portal sessions. Requests and responses are Pydantic v2 models generated from the versioned OpenAPI spec. Use it from Python 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 that use one, and retries transient failures only when a retry is safe. The objects it works with are described in How Alguna works.
The SDK is for servers only. API keys are secret: never put one in a browser or a mobile app. For 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>. - Create the client with the key. Each request carries the key and pins the API version in the
Alguna-Versionheader. - Call resources such as
client.customersandclient.subscriptions. Each method returns a typed model. A failed request raises a typed error.
Installation
alguna on PyPI, and its source is alguna-io/alguna-python on GitHub. The package ships py.typed, so mypy and pyright check your calls.
Alguna() raises ValueError before it sends a request.
Quick start: customer → subscription → invoice → portal session
Subscriptions are created in
draft status. Pass auto_activate=True (as above) or call client.subscriptions.activate(id) when you are ready to go live. See Creating a Subscription for the full set of patterns."1250.50". Use decimal.Decimal for arithmetic, not float.
Resources
The client has one attribute for each API resource, and every public operation has a method. Method names are snake_case, for exampleclient.customers.create(...) and client.invoices.get(...). Examples:
Other resources include
products, plans, bundles, quotes, credit_notes, payments, refunds, wallets, wallet_grants, metrics, checkout_sessions, subscription_versions, subscription_changes and tax. reference.md in the SDK repository lists every method with its parameters. The generated API reference describes each endpoint.
Request and response models, and the webhook payload models, are exported from the package root:
request_options dictionary for one request. It accepts timeout, max_retries, additional_headers, additional_query_parameters, additional_body_parameters and chunk_size. Methods that write also take idempotency_key.
Async client
AsyncAlguna takes the same arguments and has the same methods, as awaitables:
Pagination and filtering
A list method acceptslimit, offset, sort (in field:order format) and the same filters as the HTTP API. It returns one page. data holds the items of the page:
paginate. It asks for the largest page that the list method allows, moves the offset, and stops after the first short page. Filters go through to the list method. apaginate does the same for AsyncAlguna.
PDF downloads
client.invoices.generate_pdf, client.quotes.get_pdf and client.subscriptions.download_pdf return an iterator of bytes chunks. Write the chunks to a file:
Error handling
An error status raisesalguna.ApiError or one of its subclasses. The error has status_code, body (the API’s error response) and headers. str(error) is HTTP <status>: <message>. The message is the API’s detail, else its title, else its message, else the HTTP status text.
All of these extend
ApiError. When no response arrives, after the retries, the SDK raises the httpx exception, such as httpx.ConnectError. A successful response never raises because of an unexpected body. Fields that the SDK does not know stay available on the model. Status meanings and retry guidance are on the Errors page.
Idempotency and retries
Every request that is not a GET sends anIdempotency-Key. Pass your own idempotency_key, or the SDK makes a UUID v4 for each call. The API then returns the original result instead of repeating the action. See Idempotency.
client.events.ingest, client.credits.check and client.credits.track are different. The request body identifies their work, so the SDK makes no key for them and still retries them. An idempotency_key that you pass is sent on every attempt. See Writes identified by their events. Pass your own key when you retry a call yourself, for example after a restart:
- the status is 408, 429, 502, 503 or 504.
- the status is 409 and the response has
Retry-After. The API sends this only while a request with the same key is still running. Any other 409 raisesConflictErrorat once. - the connection is refused, reset or closed, or the attempt times out.
Retry-After, up to 60 seconds. Without it, the client backs off exponentially with jitter, starting at 1 second. Every retry sends the same key. Set max_retries on the client or in request_options for one request. 0 turns retries off. When you cancel an async call, for example with asyncio.timeout, the client does not retry it.
timeout, in seconds, on the client or in request_options.
Configuration
base_url="https://api.sandbox.alguna.io" and a sandbox API key. For a proxy, TLS settings or another transport, pass your own httpx.Client (an httpx.AsyncClient for AsyncAlguna) as httpx_client. If you pass httpx_client and no timeout, the timeout of your httpx_client applies.
api_version to pin the version your integration is written against. Without it, the SDK sends the version it was generated from, so a package upgrade can move you to a newer API version. See Versioning. Each request also sends User-Agent: alguna-python/<version>.
FAQ
Can I use the SDK in the browser? No. It uses 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 event type has a model, such asWebhookInvoicePaidPayload. The SDK does not verify signatures. Before you trust a payload, verify its svix-id, svix-timestamp and svix-signature headers with the svix package, as Verifying signatures shows. Payload keys are camelCase, and the models have snake_case fields.
How do I point it at a sandbox?
Pass base_url="https://api.sandbox.alguna.io" with a sandbox API key. Sandbox and production are separate environments with separate keys. See Base URLs.
Is there an SDK for another language?
Yes. There are TypeScript, Go and Rust SDKs and an alguna CLI. See SDKs and CLI.
Which version am I on?
The package version is the PyPI release of alguna. Run pip show alguna to read it. The API version is the date sent as Alguna-Version, and it alone decides request and response shapes. When you pass api_version, a package upgrade never changes it.
How do I report a bug?
Open an issue in alguna-io/alguna-python. Alguna generates the SDK in a private repository, so a pull request there is not merged directly. The change arrives with a later release.