Misar IO Docs

Python

Official Python SDK for MisarMail — sync and async clients for Django, FastAPI, Flask, and scripts

Python SDK

The misarmail PyPI package is the official Python SDK for MisarMail. It ships dual sync and async clients built on httpx, with full type hints via TypedDict.

Installation

pip install misarmail
# or
uv add misarmail
# or
poetry add misarmail

Requirements: Python ≥ 3.9, httpx ≥ 0.27

Quick Start

from misarmail import MisarMail

client = MisarMail(api_key="msk_your_key_here")

result = client.send(
    from_={"email": "[email protected]", "name": "Your App"},
    to=[{"email": "[email protected]"}],
    subject="Welcome!",
    html="<p>Welcome aboard!</p>",
)

print(result["message_id"])

Configuration

import os
from misarmail import MisarMail

client = MisarMail(
    api_key=os.environ.get("MISARMAIL_API_KEY", "msk_your_key_here"),
    base_url="https://mail.misar.io",  # Default
    timeout=15.0,                      # Seconds. Default: 30
    headers={"X-App-Version": "2.0"},
)

Available Methods

| Method | Description | |--------|-------------| | client.email.send(request) | Send a transactional email | | client.contacts.list(**params) | List contacts with filters | | client.contacts.create(**params) | Create a contact | | client.contacts.get(id) | Get a single contact | | client.contacts.update(id, **params) | Update contact fields | | client.contacts.delete(id) | Delete a contact | | client.contacts.import_contacts(**params) | Bulk import/upsert contacts | | client.campaigns.list(**params) | List campaigns | | client.campaigns.create(**params) | Create a draft campaign | | client.campaigns.get(id) | Get a campaign | | client.campaigns.update(id, **params) | Update a campaign | | client.campaigns.send(id) | Send/schedule a campaign | | client.campaigns.delete(id) | Delete a campaign | | client.templates.list(**params) | List email templates | | client.templates.create(**params) | Create a template | | client.templates.get(id) | Get a template | | client.templates.update(id, **params) | Update a template | | client.templates.delete(id) | Delete a template | | client.templates.render(id, **params) | Render a template with merge data | | client.automations.list(**params) | List automation workflows | | client.automations.create(**params) | Create an automation | | client.automations.get(id) | Get an automation | | client.automations.update(id, **params) | Update an automation | | client.automations.delete(id) | Delete an automation | | client.automations.activate(id) | Activate/deactivate an automation | | client.domains.list() | List sending domains | | client.domains.create(**params) | Add a sending domain | | client.domains.get(id) | Get a domain | | client.domains.verify(id) | Trigger domain DNS verification | | client.domains.delete(id) | Delete a domain | | client.aliases.list(**params) | List email aliases | | client.aliases.create(**params) | Create an alias | | client.aliases.get(id) | Get an alias | | client.aliases.update(id, **params) | Update an alias | | client.aliases.delete(id) | Delete an alias | | client.dedicated_ips.list() | List dedicated IPs | | client.dedicated_ips.create(**params) | Purchase a dedicated IP | | client.dedicated_ips.update(id, **params) | Update IP pool assignment | | client.dedicated_ips.delete(id) | Release a dedicated IP | | client.channels.send_whatsapp(**params) | Send a WhatsApp message | | client.channels.send_push(**params) | Send a push notification | | client.ab_tests.list(**params) | List A/B tests | | client.ab_tests.create(**params) | Create an A/B test | | client.ab_tests.get(id) | Get an A/B test | | client.ab_tests.set_winner(id, variant) | Manually set the winning variant | | client.sandbox.send(**params) | Send in sandbox mode (no real delivery) | | client.sandbox.list(**params) | List sandbox sent messages | | client.sandbox.delete(id) | Delete a sandbox message | | client.inbound.list(**params) | List inbound routing rules | | client.inbound.create(**params) | Create an inbound route | | client.inbound.get(id) | Get an inbound route | | client.inbound.delete(id) | Delete an inbound route | | client.analytics.overview(**params) | Get send/open/click/bounce analytics | | client.track.event(**params) | Track a custom event | | client.track.purchase(**params) | Track a purchase event | | client.keys.list() | List API keys | | client.keys.create(**params) | Create an API key | | client.keys.get(id) | Get an API key | | client.keys.revoke(id) | Revoke an API key | | client.validate.email(address) | Validate an email address | | client.leads.search(**params) | Start an async lead search job | | client.leads.get_job(job_id) | Get lead search job status | | client.leads.list_jobs(**params) | List all lead search jobs | | client.leads.results(job_id, **params) | Fetch results for a completed job | | client.leads.import_leads(**params) | Import leads directly to contacts | | client.leads.credits() | Get lead finder credits balance | | client.autopilot.start(**params) | Start an AI Autopilot campaign run | | client.autopilot.get(id) | Get Autopilot run status | | client.autopilot.list(**params) | List Autopilot runs | | client.autopilot.daily_plan(**params) | Get today's AI-suggested outreach plan | | client.sales_agent.get_config() | Get Sales Agent AI configuration | | client.sales_agent.update_config(**params) | Update Sales Agent configuration | | client.sales_agent.get_actions(**params) | List Sales Agent actions taken | | client.crm.list_conversations(**params) | List CRM conversations | | client.crm.get_conversation(id) | Get a CRM conversation | | client.crm.update_conversation(id, **params) | Update conversation status/notes | | client.crm.list_messages(conversation_id, **params) | List messages in a conversation | | client.crm.list_deals(**params) | List deals in pipeline | | client.crm.create_deal(**params) | Create a new deal | | client.crm.get_deal(id) | Get a deal | | client.crm.update_deal(id, **params) | Update a deal | | client.crm.delete_deal(id) | Delete a deal | | client.crm.list_clients(**params) | List CRM clients/accounts | | client.crm.create_client(**params) | Create a CRM client | | client.webhooks.list(**params) | List webhooks | | client.webhooks.create(**params) | Create a webhook endpoint | | client.webhooks.get(id) | Get a webhook | | client.webhooks.update(id, **params) | Update a webhook | | client.webhooks.delete(id) | Delete a webhook | | client.webhooks.test(id) | Send a test event to a webhook | | client.usage.get(**params) | Get API usage stats | | client.billing.subscription() | Get current subscription details | | client.billing.checkout(**params) | Create a billing checkout session | | client.workspaces.list() | List workspaces | | client.workspaces.create(**params) | Create a workspace | | client.workspaces.get(id) | Get a workspace | | client.workspaces.update(id, **params) | Update a workspace | | client.workspaces.delete(id) | Delete a workspace | | client.workspaces.list_members(id) | List workspace members | | client.workspaces.invite_member(id, **params) | Invite a member to workspace | | client.workspaces.update_member(id, user_id, **params) | Update member role | | client.workspaces.remove_member(id, user_id) | Remove a member from workspace |


Examples

Lead finder

# Start an async search job
job = client.leads.search(
    query="VP of Engineering at fintech companies",
    limit=100,
)

status = client.leads.get_job(job["id"])
if status["state"] == "completed":
    results = client.leads.results(job["id"], limit=50)
    print(results["leads"])

Autopilot

run = client.autopilot.start(
    goal="Book 20 demo calls with HR directors",
    audience="HR directors at companies with 50-500 employees",
    daily_limit=30,
)

status = client.autopilot.get(run["id"])
print(status["state"], status["emails_sent"])

CRM conversations & deals

conversations = client.crm.list_conversations(status="open", limit=20)

deal = client.crm.create_deal(
    title="Enterprise contract",
    amount=25000,
    currency="USD",
    contact_id=conversations["conversations"][0]["contact_id"],
)

Webhooks

webhook = client.webhooks.create(
    url="https://yourapp.com/webhooks/mail",
    events=["email.delivered", "email.opened", "email.bounced"],
)
client.webhooks.test(webhook["id"])

Async Client

import asyncio
from misarmail import AsyncMisarMail

async def main():
    client = AsyncMisarMail(api_key="msk_your_key_here")
    result = await client.email.send(
        from_={"email": "[email protected]"},
        to=[{"email": "[email protected]"}],
        subject="Hello",
        html="<p>Hi!</p>",
    )
    print(result["message_id"])

asyncio.run(main())

Error Handling

from misarmail import MisarMailAPIError

try:
    client.email.send(...)
except MisarMailAPIError as e:
    print(e.status_code, e.message)