FlexPrice Python SDK
Type-safe Python client for the FlexPrice API: billing, metering, and subscription management for SaaS and usage-based products.
Requirements
- Python 3.10+
Installation
pip install flexprice
With uv or poetry:
uv add flexprice
# or
poetry add flexprice
Runnable samples are in the examples/ directory.
Environment
| Variable | Required | Description |
|---|---|---|
FLEXPRICE_API_KEY |
Yes | API key |
FLEXPRICE_API_HOST |
Optional | Full base URL including https:// and /v1 (default: https://us.api.flexprice.io/v1). No trailing slash. |
Integration tests in api/tests/python/test_sdk.py use a different env shape; see api/tests/README.md.
Quick start
Initialize the client, create a customer, ingest an event:
import os
from flexprice import Flexprice
api_key = os.getenv("FLEXPRICE_API_KEY", "YOUR_API_KEY")
server_url = os.getenv(
"FLEXPRICE_API_HOST", "https://us.api.flexprice.io/v1"
)
with Flexprice(server_url=server_url, api_key_auth=api_key) as client:
external_id = "customer-123"
client.customers.create_customer(
external_id=external_id,
email="user@example.com",
name="Example Customer",
)
result = client.events.ingest_event(
request={
"event_name": "Sample Event",
"external_customer_id": external_id,
"properties": {"source": "python_app", "environment": "test"},
"source": "python_app",
}
)
print(result)
Async usage
The same client supports async when used as an async context manager:
import asyncio
import os
from flexprice import Flexprice
async def main():
server_url = os.getenv(
"FLEXPRICE_API_HOST", "https://us.api.flexprice.io/v1"
)
async with Flexprice(
server_url=server_url,
api_key_auth=os.getenv("FLEXPRICE_API_KEY", "YOUR_API_KEY"),
) as client:
result = await client.events.ingest_event_async(
request={
"event_name": "Sample Event",
"external_customer_id": "customer-123",
"properties": {"source": "python_async", "environment": "test"},
"source": "python_async",
}
)
print(result)
asyncio.run(main())
Authentication
- Pass your API key as
api_key_authwhen creating the client. The SDK sends it in thex-api-keyheader. - Set
FLEXPRICE_API_HOSTto a full URL (see Environment) or use the defaulthttps://us.api.flexprice.io/v1. - Prefer environment variables; get keys from your FlexPrice dashboard or docs.
Error handling
API errors are raised as exceptions. Catch them and inspect the response as needed:
try:
with Flexprice(server_url="...", api_key_auth="...") as flexprice:
result = flexprice.events.ingest_event(request={...})
except Exception as e:
print(f"Error: {e}")
# Inspect status code and body if available on the exception
See the API docs for error formats and status codes.
Features
- Full API coverage (customers, plans, events, invoices, payments, entitlements, etc.)
- Sync and async support
- Type-safe request/response models (Pydantic)
- Built-in retries and error handling
For a full list of operations, see the API reference and the examples in this repo.
Troubleshooting
- Missing or invalid API key: Ensure
api_key_authis set (or setFLEXPRICE_API_KEYand pass it in). Keys are for server-side use only. - Wrong server URL: Use a full URL such as
https://us.api.flexprice.io/v1(include/v1; no trailing slash). - 4xx/5xx on ingest: Event ingest returns 202 Accepted; for errors, check request fields (
event_name,external_customer_id,properties,source) against the API docs.
Handling Webhooks
Flexprice sends webhook events to your server for async updates on payments, invoices, subscriptions, wallets, and more.
Flow:
- Register your endpoint URL in the Flexprice dashboard
- Receive
POSTwith raw JSON body - Read
event_typeto route - Parse payload into typed model
- Handle business logic idempotently
- Return
200quickly
import json
from flexprice.models import (
WebhookDtoPaymentWebhookPayload,
WebhookDtoSubscriptionWebhookPayload,
WebhookDtoInvoiceWebhookPayload,
)
def handle_webhook(raw_body: str) -> None:
event = json.loads(raw_body)
match event.get("event_type"):
case "payment.success" | "payment.failed" | "payment.updated":
payload = WebhookDtoPaymentWebhookPayload.model_validate(event)
if payload.payment:
print(f"payment {payload.payment.id}")
# TODO: update payment record
case "subscription.activated" | "subscription.cancelled" | "subscription.updated":
payload = WebhookDtoSubscriptionWebhookPayload.model_validate(event)
if payload.subscription:
print(f"subscription {payload.subscription.id}")
case "invoice.update.finalized" | "invoice.payment.overdue":
payload = WebhookDtoInvoiceWebhookPayload.model_validate(event)
if payload.invoice:
print(f"invoice {payload.invoice.id}")
case _:
print(f"unhandled event: {event.get('event_type')}")
Event types
| Category | Events |
|---|---|
| Payment | payment.created · payment.updated · payment.success · payment.failed · payment.pending |
| Invoice | invoice.create.drafted · invoice.update · invoice.update.finalized · invoice.update.payment · invoice.update.voided · invoice.payment.overdue · invoice.communication.triggered |
| Subscription | subscription.created · subscription.draft.created · subscription.activated · subscription.updated · subscription.paused · subscription.resumed · subscription.cancelled · subscription.renewal.due |
| Subscription Phase | subscription.phase.created · subscription.phase.updated · subscription.phase.deleted |
| Customer | customer.created · customer.updated · customer.deleted |
| Wallet | wallet.created · wallet.updated · wallet.terminated · wallet.transaction.created · wallet.transaction.updated · wallet.credit_balance.dropped · wallet.credit_balance.recovered · wallet.ongoing_balance.dropped · wallet.ongoing_balance.recovered · wallet.ongoing_balance.updated |
| Feature / Entitlement | feature.created · feature.updated · feature.deleted · feature.wallet_balance.alert · entitlement.created · entitlement.updated · entitlement.deleted |
| Credit Note | credit_note.created · credit_note.updated |
Production rules:
- Keep handlers idempotent — Flexprice retries on non-
2xx - Return
200for unknown event types — prevents unnecessary retries - Do heavy processing async — respond fast, queue the work
Documentation
- FlexPrice API documentation
- Python SDK examples in this repo
- SDK integration tests — different
FLEXPRICE_API_HOSTshape for automated tests
Release files for flexprice 2.1.33
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flexprice-2.1.33.tar.gz | 319.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flexprice-2.1.33-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.1 MB
Release files / flexprice-2.1.33.tar.gz
| Download URL | flexprice-2.1.33.tar.gz |
|---|---|
| Size | 319.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fcab3e064963e924c965f749c3122b947f9ae7868f3abbf766e72d967818d976
|
|
BLAKE2b-256 checksum How to use checksums |
bc2467b2d76bea34e694bd4dadb82e3990476e9f067a00350a69ac22c83f5939
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / flexprice-2.1.33-py3-none-any.whl
| Download URL | flexprice-2.1.33-py3-none-any.whl |
|---|---|
| Size | 744.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
47cbc31458bbd14eb39dddb80bd51fbc1f95d72e71fb2222e181ad694bd1433d
|
|
BLAKE2b-256 checksum How to use checksums |
b89897f143c429ee1fb05d82cbe89d7c4bb65c729a09ca5829bd54bb8125dd16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|