MisarMail Python SDK
Official Python SDK for the MisarMail API — transactional send, campaigns, contacts, templates, automations, deliverability, warmup, monetization and the two AI streams.
Full reference: misarmail.com/docs.
Install
pip install misarmail
Auth
Use a MisarMail developer key (msk_…), created at
misarmail.com/developers. It is sent as
Authorization: Bearer msk_….
Every call is metered against the subscription attached to that key. There is no client-side limit checking — the server decides, and the SDK surfaces its answer.
Quick start
from misarmail import MisarMailClient, PlanLimitError
mail = MisarMailClient("msk_your_key")
mail.email.send({
"from": {"email": "you@yourdomain.com"},
"to": [{"email": "someone@example.com"}],
"subject": "Hello",
"html": "<p>Hi there</p>",
})
contacts = mail.contacts.list(page=1, limit=50)
campaign = mail.campaigns.create({
"name": "Launch",
"subject": "We just shipped",
"fromName": "Your Name",
"fromEmail": "you@yourdomain.com",
})
Plan limits
Both a spent allowance and a feature that is not on the plan answer 403,
carrying code: "plan_limit_exceeded". The SDK keys on that code rather than
the status, which is why a refusal is typed correctly even though 403 is
otherwise an authorization failure. The SDK raises
PlanLimitError for either, and does not retry it — retrying cannot
help until the allowance resets or the plan changes. Read upgrade_url to
send the user somewhere useful.
GET /plan returns plan, sending (the per-day and per-month email caps),
usage — an array with one entry per metered feature, each carrying used,
limit and remaining — and upgrade, which is null until a quota is tight.
A null limit means unlimited, and remaining is null alongside it rather than
0. Read it before an expensive call rather than discovering the ceiling through
a refusal.
The key needs the read or subscription scope.
plan = mail.plan.get()
print(plan["sending"], plan["usage"]) # usage is a list, one entry per metered feature
try:
mail.campaigns.create({"name": "Blast", "subject": "Hi",
"fromName": "You", "fromEmail": "you@yourdomain.com"})
except PlanLimitError as e:
print(f"{e.feature} exhausted on {e.plan}", e.upgrade_url)
Streaming
Two endpoints stream Server-Sent Events. Both sit outside /v1, which the
SDK handles for you:
| Method | Route |
|---|---|
streaming.generateEmail |
POST /api/ai/generate-email/stream |
streaming.campaignSend |
GET /api/campaigns/{id}/send-stream |
Frames are unnamed (data: {…}) and the stream ends with data: [DONE], which
the SDK consumes rather than handing on. A stream is never retried: replaying one
that failed mid-flight would duplicate whatever you had already read.
for chunk in mail.streaming.generate_email(prompt="a launch email"):
print(chunk.data.get("delta", ""), end="")
for progress in mail.streaming.campaign_send(campaign["id"]):
print(progress.data)
License
MIT — see LICENSE.
Metadata
Release files for misarmail 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| misarmail-1.0.0.tar.gz | 18.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| misarmail-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.7 kB
Release files / misarmail-1.0.0.tar.gz
| Download URL | misarmail-1.0.0.tar.gz |
|---|---|
| Size | 18.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0f0ed6345fbecb11ef77e6f467a5e03ffb279b0aadf7bd69d153f76108b4232
|
|
BLAKE2b-256 checksum How to use checksums |
6340737dd7ca9cd5c4fa8f2ab057e98431805a005f9183891615b9a69c7f3f78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / misarmail-1.0.0-py3-none-any.whl
| Download URL | misarmail-1.0.0-py3-none-any.whl |
|---|---|
| Size | 19.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1655fb90732c341ef3b339962531a02cd665293c1a6a70d2cc43f8746dc2d148
|
|
BLAKE2b-256 checksum How to use checksums |
4e60043f2fe44ffcfb62be9e77809ee674a3a843d0ce31bdc0853baca08af300
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|