HisendHISEND Docs
Sdk

Python SDK

Official Python SDK for HiSend

The HiSend Python SDK (hisend) provides a convenient wrapper around our REST APIs, carefully typed for Python projects. It's the recommended way to integrate HiSend into your Python backend or serverless environments, making heavy use of TypedDict to provide excellent IDE intellisense without relying on heavy frameworks.

Installation

You can install the SDK using your preferred package manager (like pip, poetry, or uv):

pip install hisend

Initialization

Import the client and initialize it using the API Key generated in your project dashboard.

from hisend import Hisend

client = Hisend(api_key="YOUR_API_KEY")

# Start using the client

Resources

The SDK is divided into resources, each handling a specific domain of the API. These are accessible via the initialized client.

Emails (client.emails)

The emails resource handles sending messages and fetching sent/received history.

send(data: SendEmailRequest)

Sends a single email.

result = client.emails.send({
    "from": "noreply@yourdomain.com",  # You can also use "from_" internally
    "to": ["user@example.com"],
    # Optional fields:
    "cc": ["team@yourdomain.com"],
    "bcc": ["hidden@yourdomain.com"],
    "subject": "Welcome to HiSend!",
    "html": "<h1>Welcome!</h1><p>We are glad to have you.</p>",
    "text": "Welcome! We are glad to have you.",
})

send_batch(data: list[SendEmailRequest])

Sends multiple emails in a single API request, useful for bulk messaging/newsletters.

batch = [
    {"from": "sales@test.com", "to": ["a@test.com"]},
    {"from": "sales@test.com", "to": ["b@test.com"]},
]

result = client.emails.send_batch(batch)

list()

Returns a list of all emails (inbound and outbound) belonging to your project.

emails = client.emails.list()
print(f"You have {len(emails)} emails.")

get(id: int)

Retrieves the details of a specific email by its ID.

email = client.emails.get(1234)
print(email.get("subject"))

Threads (client.threads)

The threads resource handles email conversations, grouping inbound and outbound replies into manageable topics.

list()

Returns all conversation threads for your project, ordered by the latest message time.

threads = client.threads.list()

get_emails(id: int)

Returns all individual emails that belong to a specific Thread ID, in chronological order.

emails_in_thread = client.threads.get_emails(849)
for msg in emails_in_thread:
    print(f"{msg.get('from')}: {msg.get('text_body')}")

Domains (client.domains)

The domains resource manages the sender domains authorized for your project.

list()

Returns all domains registered to your project along with their verification statuses.

domains = client.domains.list()

get(id: int)

Retrieves the details and verification status of a specific domain by its ID.

domain = client.domains.get(101)

add(data: AddDomainRequest)

Registers a new domain to your project. Note that it will remain pending until you verify its DNS records.

domain = client.domains.add({
    "name": "newsletter.example.com",
})

verify(id: int)

Triggers a manual DNS check to verify if the required records (MX, TXT, CNAME) have been added to your registrar.

result = client.domains.verify(domain.get("id"))
print(f"Verification status: {result.get('verification_status')}")

delete(id: int)

Removes a domain from your project.

client.domains.delete(domain.get("id"))

Routing (client.routing)

The routing resource manages how inbound emails are processed, allowing for Catch-All or exact-address routing.

list(domain_id: int)

Returns all inbound email routing rules configured for a specific domain.

routes = client.routing.list(domain_id)

get(domain_id: int, id: int)

Returns the details of a specific routing rule.

route = client.routing.get(domain_id, route_id)

create(domain_id: int, data: CreateRoutingRequest)

Creates a new routing rule on a specific domain.

rule = client.routing.create(domain_id, {
    "type": "specific_address",
    "email_address": "support@yourdomain.com",
    "endpoint_ids": [102, 103],
})

update(domain_id: int, id: int, data: UpdateRoutingRequest)

Updates an existing routing rule on a specific domain.

updated_rule = client.routing.update(domain_id, rule.get("id"), {
    "endpoint_ids": [102],
})

delete(domain_id: int, id: int)

Deletes an existing inbound routing rule.

client.routing.delete(domain_id, rule.get("id"))

Error Handling

All methods in the SDK will raise a HisendError exception. If the API request is rejected (e.g., HTTP 401 Unauthorized or HTTP 400 Bad Request), a descriptive error containing the status code will be raised.

from hisend import HisendError

try:
    result = client.emails.send(req)
except HisendError as e:
    print(f"Failed to send email: {e} (Status: {e.status_code})")

On this page