vaartix
Official Python SDK for Vaartix, the email API for Indian developers.
Vaartix is in private beta. Request early access.
pip install vaartix
Python 3.10 or newer. No dependencies.
Send an email
from vaartix import Vaartix
vaartix = Vaartix() # reads the VAARTIX_API_KEY environment variable
email = vaartix.emails.send(
{
"from": "Acme <onboarding@acme.in>",
"to": ["priya@example.com"],
"subject": "Hello from Vaartix",
"html": "<strong>It works!</strong>",
}
)
print(email["id"]) # em_...
Emails are plain dicts because from is a Python keyword. Keys can be snake_case
(reply_to, scheduled_at) or the API's camelCase (replyTo, scheduledAt). Responses are the
API's JSON as dicts, exactly as in the API reference.
# Retry safely: the same key within 24 hours returns the first email instead of sending twice.
vaartix.emails.send(email, idempotency_key=f"welcome-{user.id}")
# Send later (up to 30 days ahead), and cancel if plans change.
scheduled = vaartix.emails.send({**email, "scheduled_at": "2026-11-01T09:00:00+05:30"})
vaartix.emails.cancel(scheduled["id"])
# Up to 100 emails in one request.
vaartix.batch.send([email_1, email_2])
# Look up an email and its delivery events, or list recent bounces.
vaartix.emails.get("em_...")
vaartix.emails.list(status="bounced", days=7)
# Try it without a domain: test addresses simulate delivery, bounces and complaints.
vaartix.emails.send(
{
"from": "onboarding@test.vaartix.com",
"to": "delivered@test.vaartix.com",
"subject": "Hello",
"text": "It works!",
}
)
Django
Send all of Django's email through Vaartix, including send_mail, EmailMessage and built-in
emails such as password resets:
pip install "vaartix[django]"
# settings.py
VAARTIX_API_KEY = os.environ["VAARTIX_API_KEY"]
DEFAULT_FROM_EMAIL = "Acme <noreply@acme.in>" # on a domain verified in Vaartix
# Django 6.1 and newer
MAILERS = {"default": {"BACKEND": "vaartix.django.EmailBackend"}}
# Django 4.2 to 6.0
EMAIL_BACKEND = "vaartix.django.EmailBackend"
With MAILERS you can also pass the key as an option instead:
{"BACKEND": "vaartix.django.EmailBackend", "OPTIONS": {"api_key": "vx_live_..."}}.
from django.core.mail import EmailMultiAlternatives
message = EmailMultiAlternatives("Order confirmed", "Thanks!", to=["priya@example.com"])
message.attach_alternative("<p>Thanks!</p>", "text/html")
message.tags = [{"name": "type", "value": "order"}] # optional
message.send()
print(message.vaartix_id) # em_...
HTML alternatives, attachments, inline images (Content-ID), cc, bcc, reply-to and custom
headers are all supported. Errors raise VaartixError unless you pass fail_silently=True.
Open and click tracking
Tracking is off unless you turn it on, for a whole domain or for one email. Only HTML emails are tracked. Keep click tracking off for password-reset, magic-link and OTP emails.
# Default for every email from a domain (needs a full-access key from an owner or admin).
# domain_id is the domain's ID from the dashboard or the API.
vaartix.domains.update(domain_id, open_tracking=True, click_tracking=True)
# Override for one email
vaartix.emails.send(
{
"from": "Acme <orders@acme.in>",
"to": "priya@example.com",
"subject": "Your order has shipped",
"html": '<p>Track it <a href="https://acme.in/orders/123">here</a></p>',
"tracking": {"opens": True, "clicks": True},
}
)
With Django, set message.tracking = {"opens": True} before message.send().
Errors
API and network errors raise VaartixError:
from vaartix import VaartixError
try:
vaartix.emails.send(email)
except VaartixError as err:
print(err.type, err.status_code, err.message) # e.g. rate_limited 429 Too many requests...
err.type is a stable code; the full list is in Errors.
Network failures have type == "network_error" and status_code is None.
Webhooks
Check that a webhook request really came from Vaartix before trusting it. Pass the raw body.
import os
from flask import Flask, request
from vaartix import verify_webhook, WebhookVerificationError
app = Flask(__name__)
@app.post("/webhooks/vaartix")
def vaartix_webhook():
try:
event = verify_webhook(
request.get_data(), # raw bytes, not request.json
request.headers,
os.environ["VAARTIX_WEBHOOK_SECRET"],
)
except WebhookVerificationError:
return "", 400
if event["type"] == "email.bounced":
... # stop emailing event["data"]["recipient"]
if event["type"] == "email.clicked" and not event["data"]["details"]["machine"]:
... # a person clicked event["data"]["details"]["link"]
return "", 200
Endpoints receive email.opened and email.clicked only if they subscribe to them. Their
details include machine, which is True when the open or click was most likely not a person
(an image proxy, Apple Mail Privacy Protection or a link scanner), with the reason in
machineReason. For type checkers, WebhookPayload, OpenedEventDetails and
ClickedEventDetails describe these shapes; use typing.cast on the result of verify_webhook.
In Django use request.body and request.headers. Signatures follow the
Standard Webhooks spec.
Manage endpoints with vaartix.webhooks.create(url=..., events=[...]), list(), get(),
update(), remove(), rotate_secret(), deliveries() and retry_delivery().
Docs
Full API reference and guides: vaartix.com/docs.
Contributing and security
Issues and pull requests are welcome: see CONTRIBUTING.md. Please report security problems privately as described in SECURITY.md.
License
MIT
Metadata
Release files for vaartix 0.3.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 | Provenance | Actions |
|---|---|---|---|---|
| vaartix-0.3.0.tar.gz | 16.2 kB | With provenance | Details for vaartix-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| vaartix-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for vaartix-0.3.0-py3-none-any.whl |
Total release size: 30.7 kB
Release files / vaartix-0.3.0.tar.gz
| Download URL | vaartix-0.3.0.tar.gz |
|---|---|
| Size | 16.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
64893db7d9241581a8fb969d7d712d8d5e82ccf4d96ab6aa7da28af54a2fa626
|
|
BLAKE2b-256 checksum How to use checksums |
a96c8b4c872987fc25f194d074ff81183e12f3f43fe93ad941ab543fb1991ad4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.
Transparency logRelease files / vaartix-0.3.0-py3-none-any.whl
| Download URL | vaartix-0.3.0-py3-none-any.whl |
|---|---|
| Size | 14.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be51f8e1ad9df5cd0c84d06add6e542bbd3c33d15ce4970ddca59b975dc8e64c
|
|
BLAKE2b-256 checksum How to use checksums |
b01aefb70fd560095d9a27f8c5b4b1bd2b67d77541baaecf52a31938f0b855dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.
Transparency logSecurity for vaartix 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for vaartix-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.