Skip to main content

Python Client SDK for the Tirdad API.

Project description

Tirdad Python SDK

Type-safe Python client for the Tirdad API: billing, metering, and subscription management for SaaS and usage-based products.

Requirements

  • Python 3.10+

Installation

pip install tirdad-sdk

With uv or poetry:

uv add tirdad-sdk
# or
poetry add tirdad-sdk

Runnable samples are in the examples/ directory.

Environment

Variable Required Description
TIRDAD_API_KEY Yes API key
TIRDAD_API_HOST Optional Full base URL including https:// and /v1 (default: https://api.tirdad.ai/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 tirdad_sdk import Tirdad

api_key = os.getenv("TIRDAD_API_KEY", "YOUR_API_KEY")
server_url = os.getenv(
    "TIRDAD_API_HOST", "https://api.tirdad.ai/v1"
)

with Tirdad(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 tirdad_sdk import Tirdad

async def main():
    server_url = os.getenv(
        "TIRDAD_API_HOST", "https://api.tirdad.ai/v1"
    )
    async with Tirdad(
        server_url=server_url,
        api_key_auth=os.getenv("TIRDAD_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_auth when creating the client. The SDK sends it in the x-api-key header.
  • Set TIRDAD_API_HOST to a full URL (see Environment) or use the default https://api.tirdad.ai/v1.
  • Prefer environment variables; get keys from your Tirdad dashboard or docs.

Error handling

API errors are raised as exceptions. Catch them and inspect the response as needed:

try:
    with Tirdad(server_url="...", api_key_auth="...") as tirdad:
        result = tirdad.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_auth is set (or set TIRDAD_API_KEY and pass it in). Keys are for server-side use only.
  • Wrong server URL: Use a full URL such as https://api.tirdad.ai/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

Tirdad sends webhook events to your server for async updates on payments, invoices, subscriptions, wallets, and more.

Flow:

  1. Register your endpoint URL in the Tirdad dashboard
  2. Receive POST with raw JSON body
  3. Read event_type to route
  4. Parse payload into typed model
  5. Handle business logic idempotently
  6. Return 200 quickly
import json
from tirdad_sdk.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.credit_balance.dropped · wallet.credit_balance.recovered · wallet.ongoing_balance.dropped · wallet.ongoing_balance.recovered
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 — Tirdad retries on non-2xx
  • Return 200 for unknown event types — prevents unnecessary retries
  • Do heavy processing async — respond fast, queue the work

Documentation

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

tirdad_sdk-2.1.15.tar.gz (244.1 kB view details)

Uploaded Source

Built Distribution

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

tirdad_sdk-2.1.15-py3-none-any.whl (558.7 kB view details)

Uploaded Python 3

File details

Details for the file tirdad_sdk-2.1.15.tar.gz.

File metadata

  • Download URL: tirdad_sdk-2.1.15.tar.gz
  • Upload date:
  • Size: 244.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for tirdad_sdk-2.1.15.tar.gz
Algorithm Hash digest
SHA256 9bcc371530c6567e6229a59b62939ffd3ad900be677dcd4b4343e08bf8053f8f
MD5 4918c20e1ef2847956117025719657c9
BLAKE2b-256 28a6291713f65810a6c43f785d5173c91dfce4c7c2adb91925077ba145d31fa4

See more details on using hashes here.

File details

Details for the file tirdad_sdk-2.1.15-py3-none-any.whl.

File metadata

  • Download URL: tirdad_sdk-2.1.15-py3-none-any.whl
  • Upload date:
  • Size: 558.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for tirdad_sdk-2.1.15-py3-none-any.whl
Algorithm Hash digest
SHA256 2a6e5b44e87eff9be1a071e769c75239e79a72c1ebc7c6899b2afce3e3c0ae8f
MD5 1c7437d1ee0df662c348a0cd3b1f2ba2
BLAKE2b-256 27f50b622392f6c30bd45454d351fb61cee12e92f42e5feb7d0b0ae347b73b34

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