Tutorials
Sending emails with Python
The same walkthrough in Python with httpx.
There is no official Notideus SDK for Python — the API is plain JSON over HTTPS. This walkthrough uses httpx (pip install httpx); the same shape works with requests.
The send function
raise_for_status catches HTTP errors; the wrapper lifts the API's machine-readable code out of the error envelope so callers can branch on it.
import os
import httpx
API_KEY = os.environ["NT_KEY"] # "nt_live_…"
class ApiError(Exception):
"""HTTP status plus the API's machine-readable error code."""
def __init__(self, status: int, code: str, message: str):
self.status = status
self.code = code
super().__init__(f"{status} {code}: {message}")
def send(payload: dict) -> dict:
with httpx.Client(
base_url="https://api.notideus.io/v1",
headers={"Authorization": f"Bearer {API_KEY}"},
) as client:
r = client.post("/emails", json=payload)
try:
r.raise_for_status()
except httpx.HTTPStatusError as exc:
error = exc.response.json().get("error", {})
raise ApiError(
exc.response.status_code, error.get("code"), error.get("message")
) from exc
return r.json()
email = send({
"from": "Notideus <noreply@demo.dev>",
"to": ["jane@example.com"],
"subject": "Welcome to Notideus",
"html": "<p>Hi Jane,</p><p>Your account is ready.</p>",
})
print(email["id"], email["status"])
Expected output
send returns the stored email row (201 Created). Response abbreviated to id, status, from, to and subject:
{
"id": "01a0a11c-188e-7c9e-9b69-753fcb4c8d0d",
"status": "queued",
"from_address": "Notideus <noreply@demo.dev>",
"to_emails": ["jane@example.com"],
"subject": "Welcome to Notideus"
}
id uniquely identifies this email; status is queued — it is picked up for delivery from there.
Error handling
Catch ApiError and branch on exc.code:
unauthorized(401) — missing, invalid or revoked key; checkNT_KEY.insufficient_scope(403) — the key lacksemails:send; create a key with the right scope.quota_exceeded(402) — monthly allowance reached; back off and retry later. See Quotas and limits.from_domain_not_verified(422) — the From domain matches no verified team domain; verify it in the dashboard first.
Retry safely: send every request with an
idempotency_key derived from your own data (for example order-12345-welcome). A timed-out request can be re-sent with the same key without double-sending or double-charging your quota. See Idempotency for key choice and scope rules.