A Python client for the HelpScout Mailbox API v2.
Disclaimer: This package is unofficial and not associated with or endorsed by HelpScout. It is provided "as is" without warranty of any kind. Please use GitHub Discussions for support — there is no guarantee that Connectify staff will respond.
- OAuth2 client-credentials authentication with automatic token refresh
- Retry logic for rate limiting (429), server errors (5xx), and transient failures
- Conversation management: search, read, snooze, tag
- Thread operations: notes, replies, drafts, attachments
- Clean API with type hints and comprehensive docstrings
pip install helpscout-mailboximport os
from datetime import date, datetime, timedelta, timezone
from helpscout_mailbox import HelpScoutClient
# Set credentials (create app at HelpScout → Your Profile → My Apps)
os.environ["HELPSCOUT_APP_ID"] = "your-app-id"
os.environ["HELPSCOUT_APP_SECRET"] = "your-app-secret"
# Initialize client (fetches OAuth2 token automatically)
client = HelpScoutClient()
# Search conversations
for conv in client.search_conversations('subject:"Invoice"', since=date(2026, 6, 1)):
print(f"#{conv['number']}: {conv['subject']}")
# Get conversation details
conversation = client.get_conversation(12345)
print(conversation["subject"])
# Add a note
client.add_note(12345, "Processed invoice #INV-001")
# Snooze until tomorrow
tomorrow = datetime.now(timezone.utc) + timedelta(days=1)
client.snooze_conversation(12345, tomorrow)
# Add tags
client.add_tags(12345, ["billing", "processed"])search_conversations(query, since)- Search with client-side date filteringget_conversation(conversation_id)- Fetch conversation detailssnooze_conversation(conversation_id, snoozed_until)- Snooze conversationadd_tags(conversation_id, tags)- Add tags (preserves existing)
conversation_threads(conversation_id)- List threads (cached)conversation_body(conversation_id)- Concatenated HTML bodyadd_note(conversation_id, text)- Create note threadupdate_thread_text(conversation_id, thread_id, text)- Update thread bodycreate_reply(conversation_id, customer_id, text, draft)- Create replysend_draft(conversation_id, thread_id)- Send draft reply
attachment_data(conversation_id, attachment_id)- Download attachment bytes
| Variable | Required | Description |
|---|---|---|
HELPSCOUT_APP_ID |
Yes | OAuth2 app ID (from My Apps) |
HELPSCOUT_APP_SECRET |
Yes | OAuth2 app secret (from My Apps) |
The client uses OAuth2 client-credentials flow. Create an app at HelpScout → Your Profile → My Apps:
- Click "Create My App"
- Give it a name (e.g., "Invoice Processor")
- Copy the App ID and App Secret
- Set them as environment variables
The client automatically:
- Fetches access tokens on initialization
- Refreshes tokens before expiry
- Retries on 401 with fresh token
All API errors raise HelpScoutError:
from helpscout_mailbox import HelpScoutClient, HelpScoutError
try:
client = HelpScoutClient()
client.get_conversation(99999)
except HelpScoutError as e:
print(f"API error: {e}")The client automatically retries:
- 429 rate limits (respects
Retry-Afterheader) - 5xx server errors (exponential backoff)
- Transport failures (connection resets, timeouts)
Full API documentation: https://connectify.github.io/helpscout-mailbox/
HelpScout API reference: https://developer.helpscout.com/mailbox-api/
# Clone repository
git clone https://github.com/Connectify/helpscout-mailbox.git
cd helpscout-mailbox
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linters
pre-commit run --all-files
# Build documentation
pip install -e ".[docs]"
pdoc -o docs/ helpscout_mailboxPatches via pull request are welcome — please file an issue first to discuss the change before submitting a PR. Issues are not for technical support; use Discussions for that. See CONTRIBUTING.md for guidelines.
BSD-3-Clause. See LICENSE for details.
- Discussions: GitHub Discussions — for questions and support
- HelpScout API Docs: developer.helpscout.com