Skip to main content

Official Python SDK for the SupportHub REST API

Project description

SupportHub Python SDK

Official Python SDK for the SupportHub REST API.

It provides ergonomic synchronous and asynchronous clients, fully typed pydantic v2 response models, and a high-level long-polling helper for real-time updates.

Installation

With Poetry:

poetry add supporthub-sdk

With pip:

pip install supporthub-sdk

Requires Python 3.10+.

Quick start

Synchronous

from supporthub import Client

with Client(api_key="sk_live_...") as client:
    page = client.tickets.list(status="open", page=1)
    for ticket in page.items:
        print(ticket.id, ticket.subject, ticket.status)

    ticket = client.tickets.create(
        contact={"email": "alice@example.com", "name": "Alice"},
        subject="Cannot log in",
        message="I get a 500 error when logging in.",
        priority="high",
    )

    client.messages.send(ticket_id=ticket.id, content="Thanks, looking into it!")
    client.tickets.close(ticket.id)

Asynchronous

import asyncio
from supporthub import AsyncClient

async def main():
    async with AsyncClient(api_key="sk_live_...") as client:
        page = await client.tickets.list(status="open")
        for t in page.items:
            print(t.id, t.subject)

asyncio.run(main())

Configuration

Client(
    api_key="sk_...",
    base_url="https://api.support.forestsnet.com/api/v1",  # optional
    timeout=30.0,                                           # optional
)

You can also inject your own httpx.Client / httpx.AsyncClient via http_client= if you need custom transports, proxies, retries, etc.

Resources

All clients expose the same resource attributes: client.tickets, client.messages, client.contacts, client.updates, client.webhooks.

Tickets

page    = client.tickets.list(status="open", priority="high", page=1, page_size=20)
detail  = client.tickets.get("ticket-uuid", last_messages=50)
ticket  = client.tickets.create(
    contact={"email": "user@example.com"},
    subject="Help",
    message="Initial message",
    priority="normal",
    tags=["billing"],
)
ticket  = client.tickets.update("ticket-uuid", status="resolved")
ticket  = client.tickets.close("ticket-uuid")
ticket  = client.tickets.reopen("ticket-uuid")

Messages

page = client.messages.list(ticket_id="ticket-uuid", page=1, page_size=50)
msg  = client.messages.send(ticket_id="ticket-uuid", content="Hello!", is_internal=False)

# Inbound from an external source (creates/finds contact and ticket automatically):
result = client.messages.create_inbound(
    contact={"email": "user@example.com", "name": "Alice"},
    message="Hi, I have a question",
    session_id="sess-abc",
)

Contacts

contacts = client.contacts.list(search="alice", page=1)
contact  = client.contacts.get("contact-uuid")
contact  = client.contacts.upsert(
    internal_id="user-123",
    full_name="Alice Smith",
    email="alice@example.com",
)

Updates (long polling)

Telegram-style long polling. The server holds the connection open until new events arrive or timeout seconds pass.

offset = 0
while True:
    updates = client.updates.poll(
        offset=offset,
        timeout=25,
        types=["ticket.created", "message.created"],
    )
    for u in updates:
        print(u.type, u.data)
        offset = max(offset, u.id)

The async client provides a higher-level streaming helper that tracks the offset internally and yields events as they arrive:

async with AsyncClient(api_key="sk_...") as client:
    async for update in client.updates.stream(types=["message.created"]):
        print(update.type, update.data)

Webhooks

webhooks = client.webhooks.list()
wh = client.webhooks.create(
    url="https://example.com/hooks/supporthub",
    events=["ticket.created", "message.created"],
    description="Production ingestion",
)
print(wh.secret)  # only returned once, on creation
client.webhooks.delete(wh.id)

Long polling vs webhooks

  • Webhooks are best for production servers with a public HTTPS endpoint. SupportHub will POST events to your URL and sign them with your webhook secret.
  • Long polling (/updates) is great for development, prototyping, workers behind NAT, or any environment without a public callback URL. Use AsyncClient.updates.stream(...) for an async iterator that handles offset tracking and reconnection for you.

Error handling

All HTTP errors raise subclasses of supporthub.APIError:

Status Exception
400 ValidationError
401 AuthError
403 PermissionError
404 NotFoundError
422 ValidationError
429 RateLimitError
5xx ServerError

Each exception exposes:

  • .status_code — HTTP status
  • .error_code — backend error_code if present
  • .message — human-readable message
  • .detail — raw detail payload from the API
from supporthub import Client, RateLimitError, AuthError, APIError

try:
    client.tickets.list()
except AuthError:
    print("Bad API key")
except RateLimitError as e:
    print("Slow down, retry after", e.retry_after)
except APIError as e:
    print("API error:", e.status_code, e.message)

Models

All responses are parsed into pydantic v2 models with extra="allow" so unknown future fields will not break your code. Common types:

  • Ticket, TicketDetail, TicketStatus, TicketPriority
  • Message, SenderType
  • Contact
  • Update, UpdatesResponse
  • Webhook
  • PaginatedTickets, PaginatedMessages, PaginatedContacts

Use model.model_dump() to get a plain dict.

Development

cd sdks/python
poetry install
poetry run pytest
poetry run ruff check .

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

supporthub_sdk-0.1.0.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

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

supporthub_sdk-0.1.0-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file supporthub_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: supporthub_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for supporthub_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 824250fa1d115a491f76d31f76725c6da7b8349309a50b945d31c7a790b55619
MD5 f8a8345b3f0bb5e3266ac56cd04aea84
BLAKE2b-256 b1312165ba4234b9424e9079e82850ad776bf0e22960e80b564409e916e9a4df

See more details on using hashes here.

Provenance

The following attestation bundles were made for supporthub_sdk-0.1.0.tar.gz:

Publisher: publish-sdk.yml on forestsnet/saas-support

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file supporthub_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: supporthub_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for supporthub_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7d0f4ee8c3e6730454f8805e266b783f10a96ffad5d8dd23d214b34fbd606908
MD5 d29fad0274b4e802f4fab5ba0303e490
BLAKE2b-256 15ff7bec13e1f4ac729d7a4d788e0c4bfeb0546db00ca9eb31eef9ff4b3eb953

See more details on using hashes here.

Provenance

The following attestation bundles were made for supporthub_sdk-0.1.0-py3-none-any.whl:

Publisher: publish-sdk.yml on forestsnet/saas-support

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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