PyTally SDK¶
Unofficial Python SDK for the Tally.so API.
Introduction¶
PyTally SDK is a Python library that provides a simple and intuitive interface to interact with the Tally.so API. It handles authentication, request/response processing, pagination, and error handling, allowing you to focus on building your application.
What's Implemented¶
Currently, the SDK covers the following Tally API resources:
- ✅ Users - Get current user information
- ✅ Organizations - Manage users and invites
- ✅ Forms - Create, update, and manage forms and submissions
- ✅ Workspaces - List and manage workspaces
- ✅ Webhooks - Configure and monitor webhook integrations
- 🚧 MCP - Not implemented yet
Official API Documentation
For complete API details and specifications, refer to the Official Tally API Documentation.
Installation¶
Using pip¶
Using uv¶
uv is a fast Python package installer and resolver:
Requirements¶
- Python 3.11 or higher
httpxlibrary (automatically installed)
Quickstart¶
Get started with PyTally SDK in just a few lines of code:
Basic Usage¶
from tally import SUPPORTED_TALLY_API_VERSION, Tally
# Initialize the client with your API key
client = Tally(
api_key="tly_your_api_key_here",
api_version=SUPPORTED_TALLY_API_VERSION,
)
# Get current user information
user = client.users.me()
print(f"Hello, {user.full_name}!")
print(f"Email: {user.email}")
if user.subscription_plan:
print(f"Plan: {user.subscription_plan.value}")
Using Context Manager¶
The recommended approach for automatic resource cleanup:
from tally import SUPPORTED_TALLY_API_VERSION, Tally
with Tally(
api_key="tly_your_api_key_here",
api_version=SUPPORTED_TALLY_API_VERSION,
) as client:
# Get current user
user = client.users.me()
print(f"Organization ID: {user.organization_id}")
# List all forms
for form in client.forms:
print(f"Form: {form.name} (ID: {form.id})")
Working with Forms¶
from tally import SUPPORTED_TALLY_API_VERSION, Tally
client = Tally(
api_key="tly_your_api_key_here",
api_version=SUPPORTED_TALLY_API_VERSION,
)
# List forms with pagination
forms = client.forms.all(page=1, limit=10)
print(f"Found {len(forms.items)} forms")
# Get a specific form
form = client.forms.get(form_id="wXYz123")
print(f"Form: {form.name}")
print(f"Status: {form.status.value}")
print(f"Submissions: {form.number_of_submissions}")
# List form submissions
submissions = client.forms.list_submissions(
form_id="wXYz123",
filter="all",
page=1,
)
for submission in submissions.submissions:
print(f"Submission ID: {submission.id}")
print(f"Submitted: {submission.submitted_at}")
Setting up Webhooks¶
from tally import SUPPORTED_TALLY_API_VERSION, Tally
client = Tally(
api_key="tly_your_api_key_here",
api_version=SUPPORTED_TALLY_API_VERSION,
)
# Create a webhook
webhook = client.webhooks.create(
form_id="wXYz123",
url="https://your-app.com/webhooks/tally",
event_types=["FORM_RESPONSE"],
)
print(f"Webhook created: {webhook.id}")
# List webhook events
events = client.webhooks.get_events(webhook_id=webhook.id)
for event in events.events:
print(f"Event: {event.event_type.value} - {event.delivery_status.value}")
API Versioning¶
The Tally API uses date-based versioning. You can specify a specific API version when initializing the client:
from tally import SUPPORTED_TALLY_API_VERSION, Tally
client = Tally(
api_key="tly_your_api_key_here",
api_version=SUPPORTED_TALLY_API_VERSION,
)
The SDK is validated against 2025-05-30 and uses that version by default.
Error Handling¶
The SDK provides specific exceptions for different error scenarios:
from tally import Tally, UnauthorizedError, RateLimitError, NotFoundError
client = Tally(api_key="tly_your_api_key_here")
try:
form = client.forms.get(form_id="invalid_id")
except UnauthorizedError:
print("Invalid API key!")
except NotFoundError:
print("Form not found!")
except RateLimitError as e:
print(f"Rate limit exceeded. Try again later.")
print(f"Status code: {e.status_code}")
For more details, see the Error Handling guide.
Configuration Options¶
The TallyClient accepts the following configuration options:
from tally import SUPPORTED_TALLY_API_VERSION, Tally
client = Tally(
api_key="tly_your_api_key_here", # Required: Your Tally API key
api_version=SUPPORTED_TALLY_API_VERSION, # Optional: defaults to the SDK compatibility target
timeout=30.0, # Optional: Request timeout in seconds (default: 30.0)
base_url="https://api.tally.so", # Optional: Custom base URL (default: https://api.tally.so)
)
Testing¶
The project includes two test layers:
- Unit tests for
TallyClientand forms serialization/parsing - Live read-only API tests for listing forms and form submissions
export TALLY_API_KEY="tly_your_api_key_here"
export TALLY_FORM_ID="your_form_id"
export TALLY_API_VERSION="2025-05-30"
PYTHONPATH=src python -m pytest -m live_api tests/integration/test_forms_live.py
Next Steps¶
- 🔑 Get your API Key - Learn how to obtain API keys from Tally
- 📖 API Reference - Explore all available methods
- ⚠️ Error Handling - Learn about exception handling
Links¶
License¶
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Disclaimer
This is an unofficial SDK and is not affiliated with or endorsed by Tally. Tally and the Tally logo are trademarks of Tally B.V.