Skip to main content

Python SDK for the unsent API

Project description

unsent Python SDK

Prerequisites

Installation

pip

pip install unsent

poetry

poetry add unsent

Usage

Basic Setup

from unsent import unsent

client = unsent("us_12345")

Environment Variables

You can also set your API key using environment variables:

# Set UNSENT_API_KEY or UNSENT_API_KEY in your environment
# Then initialize without passing the key
client = unsent()

Sending Emails

Simple Email

data, error = client.emails.send({
    "to": "hello@acme.com",
    "from": "hello@company.com",
    "subject": "unsent email",
    "html": "<p>unsent is the best open source product to send emails</p>",
    "text": "unsent is the best open source product to send emails",
})

if error:
    print(f"Error: {error}")
else:
    print(f"Email sent! ID: {data['id']}")

Email with Attachments

data, error = client.emails.send({
    "to": "hello@acme.com",
    "from": "hello@company.com",
    "subject": "Email with attachment",
    "html": "<p>Please find the attachment below</p>",
    "attachments": [
        {
            "filename": "document.pdf",
            "content": "base64-encoded-content-here",
        }
    ],
})

Scheduled Email

from datetime import datetime, timedelta

# Schedule email for 1 hour from now
scheduled_time = datetime.now() + timedelta(hours=1)

data, error = client.emails.send({
    "to": "hello@acme.com",
    "from": "hello@company.com",
    "subject": "Scheduled email",
    "html": "<p>This email was scheduled</p>",
    "scheduledAt": scheduled_time,
})

Batch Emails

emails = [
    {
        "to": "user1@example.com",
        "from": "hello@company.com",
        "subject": "Hello User 1",
        "html": "<p>Welcome User 1</p>",
    },
    {
        "to": "user2@example.com",
        "from": "hello@company.com",
        "subject": "Hello User 2",
        "html": "<p>Welcome User 2</p>",
    },
]

data, error = client.emails.batch(emails)

if error:
    print(f"Error: {error}")
else:
    print(f"Sent {len(data['emails'])} emails")

Managing Emails

Get Email Details

data, error = client.emails.get("email_id")

if error:
    print(f"Error: {error}")
else:
    print(f"Email status: {data['status']}")

Update Email

data, error = client.emails.update("email_id", {
    "subject": "Updated subject",
    "html": "<p>Updated content</p>",
})

Cancel Scheduled Email

data, error = client.emails.cancel("email_id")

if error:
    print(f"Error: {error}")
else:
    print("Email cancelled successfully")

Managing Contacts

Create Contact

data, error = client.contacts.create("contact_book_id", {
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "metadata": {
        "company": "Acme Inc",
        "role": "Developer"
    }
})

Get Contact

data, error = client.contacts.get("contact_book_id", "contact_id")

Update Contact

data, error = client.contacts.update("contact_book_id", "contact_id", {
    "firstName": "Jane",
    "metadata": {
        "role": "Senior Developer"
    }
})

Upsert Contact

# Creates if doesn't exist, updates if exists
data, error = client.contacts.upsert("contact_book_id", "contact_id", {
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
})

Delete Contact

data, error = client.contacts.delete(
    book_id="contact_book_id",
    contact_id="contact_id"
)

Managing Campaigns

Create Campaign

from unsent import types

campaign_payload: types.CampaignCreate = {
    "name": "Welcome Series",
    "subject": "Welcome to our service!",
    "html": "<p>Thanks for joining us!</p>",
    "from": "welcome@example.com",
    "contactBookId": "cb_1234567890",
}

campaign_resp, error = client.campaigns.create(payload=campaign_payload)

if error:
    print(f"Error: {error}")
else:
    print(f"Campaign created! ID: {campaign_resp['id']}")

Schedule Campaign

from unsent import types

schedule_payload: types.CampaignSchedule = {
    "scheduledAt": "2024-12-01T10:00:00Z",
}

schedule_resp, error = client.campaigns.schedule(
    campaign_id=campaign_resp["id"],
    payload=schedule_payload
)

if error:
    print(f"Error: {error}")
else:
    print("Campaign scheduled successfully!")

Pause/Resume Campaigns

# Pause a campaign
pause_resp, error = client.campaigns.pause(campaign_id="campaign_123")

if error:
    print(f"Error: {error}")
else:
    print("Campaign paused successfully!")

# Resume a campaign
resume_resp, error = client.campaigns.resume(campaign_id="campaign_123")

if error:
    print(f"Error: {error}")
else:
    print("Campaign resumed successfully!")

Get Campaign Details

data, error = client.campaigns.get("campaign_id")

if error:
    print(f"Error: {error}")
else:
    print(f"Campaign status: {data['status']}")
    print(f"Recipients: {data['total']}")
    print(f"Sent: {data['sent']}")

Managing Domains

List Domains

data, error = client.domains.list()

if error:
    print(f"Error: {error}")
else:
    for domain in data:
        print(f"Domain: {domain['domain']}, Status: {domain['status']}")

Create Domain

data, error = client.domains.create({
    "domain": "example.com"
})

Verify Domain

data, error = client.domains.verify(domain_id=123)

if error:
    print(f"Error: {error}")
else:
    print(f"Verification status: {data['status']}")

Get Domain

data, error = client.domains.get(domain_id=123)

Error Handling

By default, the SDK raises exceptions on HTTP errors:

from unsent import unsent, unsentHTTPError

client = unsent("us_12345")

try:
    data, error = client.emails.send({
        "to": "invalid-email",
        "from": "hello@company.com",
        "subject": "Test",
        "html": "<p>Test</p>",
    })
except unsentHTTPError as e:
    print(f"HTTP {e.status_code}: {e.error['message']}")

To disable automatic error raising:

client = unsent("us_12345", raise_on_error=False)

data, error = client.emails.send({
    "to": "hello@acme.com",
    "from": "hello@company.com",
    "subject": "Test",
    "html": "<p>Test</p>",
})

if error:
    print(f"Error: {error['message']}")
else:
    print("Success!")

Custom Session

For advanced use cases, you can provide your own requests.Session:

import requests
from unsent import unsent

session = requests.Session()
session.verify = False  # Not recommended for production!

client = unsent("us_12345", session=session)

API Reference

Client Methods

  • unsent(key, url, raise_on_error=True, session=None) - Initialize the client

Email Methods

  • client.emails.send(payload) - Send an email (alias for create)
  • client.emails.create(payload) - Create and send an email
  • client.emails.batch(emails) - Send multiple emails in batch
  • client.emails.get(email_id) - Get email details
  • client.emails.update(email_id, payload) - Update a scheduled email
  • client.emails.cancel(email_id) - Cancel a scheduled email

Contact Methods

  • client.contacts.create(book_id, payload) - Create a contact
  • client.contacts.get(book_id, contact_id) - Get contact details
  • client.contacts.update(book_id, contact_id, payload) - Update a contact
  • client.contacts.upsert(book_id, contact_id, payload) - Upsert a contact
  • client.contacts.delete(book_id, contact_id) - Delete a contact

Campaign Methods

  • client.campaigns.create(payload) - Create a campaign
  • client.campaigns.get(campaign_id) - Get campaign details
  • client.campaigns.schedule(campaign_id, payload) - Schedule a campaign
  • client.campaigns.pause(campaign_id) - Pause a campaign
  • client.campaigns.resume(campaign_id) - Resume a campaign

Domain Methods

  • client.domains.list() - List all domains
  • client.domains.create(payload) - Create a domain
  • client.domains.verify(domain_id) - Verify a domain
  • client.domains.get(domain_id) - Get domain details

Requirements

  • Python 3.8+
  • requests >= 2.32.0
  • typing_extensions >= 4.7

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

unsent-0.25.5.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

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

unsent-0.25.5-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file unsent-0.25.5.tar.gz.

File metadata

  • Download URL: unsent-0.25.5.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.8 Darwin/25.0.0

File hashes

Hashes for unsent-0.25.5.tar.gz
Algorithm Hash digest
SHA256 af8a858161378a3a982c9769c7aeedae4dac0e5d8340ffd0e6d03bb215f7ca85
MD5 1da36c9b4ef26bb6a8deac19c4866283
BLAKE2b-256 7a801ca33cb6ecfb57613b00fa0c83b097057344194123dcf31df35aa0661e16

See more details on using hashes here.

File details

Details for the file unsent-0.25.5-py3-none-any.whl.

File metadata

  • Download URL: unsent-0.25.5-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.8 Darwin/25.0.0

File hashes

Hashes for unsent-0.25.5-py3-none-any.whl
Algorithm Hash digest
SHA256 18f8433b18609cee5bb0af8fc970987d9363bee3a72d1af6d637113d71580f83
MD5 f8f44e1f5ba6fb8e981ac42abaa91071
BLAKE2b-256 f21aadf31f99e3781129ff79c55e700194a02f60d7baf4d2f67e72e84a63c096

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