Skip to main content

Official Python SDK for Windback — AI-powered churn recovery for SaaS

Project description

windback

Official Python SDK for Windback — AI-powered churn recovery for SaaS.

Install

pip install windback

Quick Start

from windback import Windback

pb = Windback("sk_live_your_api_key")

event = pb.track_churn(
    email="jane@company.com",
    name="Jane Doe",
    provider="stripe",
    plan_name="Pro",
    mrr=4900,          # $49.00 in cents
    currency="USD",
    tenure_days=120,
    cancel_reason="too_expensive",
    cancel_reason_text="Costs more than our budget allows",
)

Usage

Initialize

# Simple
pb = Windback("sk_live_your_api_key")

# With options
pb = Windback(
    "sk_live_your_api_key",
    base_url="https://api.windbackai.com",  # default
    timeout=10.0,  # seconds
    retries=2,
)

Track Churn

Call this wherever your cancellation logic runs. Windback stores the event; use generate_variants + send_variant to trigger the winback email manually, or pass cancel_reason and call report_cancel_reason to trigger it automatically.

event = pb.track_churn(
    email="jane@company.com",    # required
    provider="stripe",            # required — see providers below
    mrr=4900,                     # required, in cents

    name="Jane Doe",              # optional
    plan_name="Pro",              # optional
    currency="USD",               # optional, default "USD"
    tenure_days=120,              # optional
    last_active_at="2026-02-10T12:30:00Z",  # optional, ISO 8601
    cancel_reason="too_expensive",           # optional — see cancel reasons below
    cancel_reason_text="Too costly for our stage",  # optional, free text
    notes="Requested downgrade first",              # optional, internal notes
)

Cancel Reason — Two Integration Patterns

Pattern A — All-in-one (cancel happens in real time)

Use this when the customer fills in the cancel reason on YOUR platform at the moment they cancel. Windback creates the event, picks the best winback strategy for the reason, and sends the email automatically.

resp = pb.submit_cancel_flow(
    email="jane@company.com",    # required
    provider="stripe",            # required
    mrr=4900,                     # required, in cents
    currency="USD",               # required
    cancel_reason="too_expensive",               # required
    cancel_reason_text="It's more than our budget",  # optional

    name="Jane Doe",
    plan_name="Pro",
    tenure_days=120,
)
# Email is sent automatically.
# resp = { "churn_event_id": "...", "status": "new", "message": "..." }

Pattern B — Webhook first, survey later

Use this when your payment provider (Stripe, Dodo, Razorpay) fires a webhook that Windback picks up automatically to create the churn event — and your cancel survey collects the reason separately (e.g. shown after the customer confirms cancellation).

# Step 1 — Windback creates the event from the payment webhook automatically.
# Your webhook handler just needs to be set up in the Windback dashboard.

# Step 2 — Once your cancel survey captures the reason, call:
pb.report_cancel_reason(
    event_id=event.id,
    cancel_reason="missing_features",
    cancel_reason_text="We need Salesforce integration",
)
# Windback updates the event and sends the targeted winback email automatically.

Cancel Reason Values

Value When to use Email strategy
too_expensive Price is the blocker Discount offer
missing_features They need something you don't have Highlight unused / upcoming features
not_using_enough Low engagement / forgot about it Value recap
switching_competitor Moving to a competing product Social proof
technical_issues Bugs, downtime, or integration problems Pain point fix + apology
poor_support Unhappy with support experience Founder personal email
dont_need_anymore Use case is gone (company pivot, etc.) Pause option
other None of the above — use cancel_reason_text Feedback request

Windback maps each reason to the best winback email strategy automatically.


Supported Providers

stripe | razorpay | paypal | wise | paddle | polar | dodo | chargebee | lemonsqueezy | custom


Other Methods

# Get a churn event
event = pb.get_event("event_id")

# Generate AI recovery email variants manually
result = pb.generate_variants("event_id")

# Send a specific variant manually
pb.send_variant("event_id", "variant_id")

Context Manager

with Windback("sk_live_your_api_key") as pb:
    pb.track_churn(email="jane@co.com", provider="stripe", mrr=4900)
# HTTP client is automatically closed

Error Handling

from windback import Windback, WindbackError

try:
    pb.track_churn(email="jane@co.com", provider="stripe", mrr=4900)
except WindbackError as e:
    print(e)          # "Windback: invalid API key"
    print(e.status)   # 401

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

windback-0.2.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

windback-0.2.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file windback-0.2.0.tar.gz.

File metadata

  • Download URL: windback-0.2.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for windback-0.2.0.tar.gz
Algorithm Hash digest
SHA256 be389a12e82693b38080f5df486ab5366fce86e47170eda2613045a85fa187ef
MD5 d52eb88acc1e64990d9f6fa0644436a6
BLAKE2b-256 0106f6136d3e7928ab8e3658f380351fc9924a43eab84543ccd32950d9a80f4c

See more details on using hashes here.

File details

Details for the file windback-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: windback-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for windback-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb2c30260d990fa8662591d5b9c078a5cf49c9be7724585551ccb0e481ccaf28
MD5 b755ff67f9070eec379f0995f1763a9e
BLAKE2b-256 cab4ef0dace459edc6110e85ab1c0a60f9c3bf0a8981c1be81151549c0292684

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page