Send personalized bulk emails from your own machine, using your own SMTP account. No subscriptions, no third-party servers, no data leaving your computer.
Why bit-by-mail
Most bulk email tools are SaaS platforms, where you upload your recipient list to someone else's server and pay a monthly fee for the privilege. bit-by-mail flips that: it's a lightweight local app that runs on your machine and sends through your own email provider. Your data stays yours, and there's nothing to pay for.
Features
- Local and private — runs entirely on your machine; nothing is uploaded anywhere
- Bring your own SMTP — works with Gmail, Outlook, Yahoo, or a custom domain; supports multiple accounts with a default sender fallback
- Dynamic personalization — one template, personalized per recipient using variables from your CSV (
{{FirstName}},{{InvoiceAmount}}, etc.) - Personalized attachments — send different files to different recipients in the same campaign (certificates, invoices, reports)
- Rich text or raw HTML — use the WYSIWYG editor, or drop into a Monaco-based HTML editor for full control
- Preflight checks — simulates the send beforehand to catch missing variables, missing attachments, or invalid addresses
- Reusable libraries — save recipient databases and templates so you're not rebuilding them every time
- Live analytics — real-time dispatch logs, success/failure tracking, and exportable CSV delivery reports
Getting Started
Install
pip install bit-by-mail
Requires Python 3.9 or later.
Launch
bit-by-mail
# or, for short:
bbm
The app opens automatically in your browser at http://localhost:8888.
Connect your email account
- Go to Settings in the sidebar.
- Click Add Account and enter your SMTP details (e.g.
smtp.gmail.com, port587). - Enter your email and password.
Using Gmail? Google blocks sign-ins with your regular password. Generate an App Password instead and use that.
Prepare your recipient list
Recipients are loaded from a CSV file with a header row.
| Column | Required | Notes |
|---|---|---|
Name |
Yes | Used for personalization |
Email |
Yes | Recipient address |
AttachmentFile |
No | Separate multiple files with ; |
| anything else | No | Any extra column becomes a placeholder automatically |
Example:
| Name | AttachmentFile | TicketType | |
|---|---|---|---|
| John Doe | john@example.com | john_pass.pdf | VIP |
| Jane Smith | jane@example.com | jane_pass.pdf; map.png | Standard |
Run a campaign
- Campaigns → New Campaign
- Upload your CSV, or import a saved database
- Write your subject and body, using placeholders like
{{Name}}or{{TicketType}} - Check the Preview panel to confirm placeholders render correctly
- Run Preflight to catch problems before sending
- Click Start Sending
Advanced
Asset Library — store image URLs (including Google Drive links) and drop them into your templates without re-uploading each time.
Throttling — add a delay (in seconds) between sends in Campaign Settings to stay under provider rate limits and avoid spam filters.
Resume on failure — if a campaign is interrupted, bit-by-mail remembers who's already been sent to. Hit send again and it only processes the recipients still marked PENDING.
Troubleshooting
- Emails aren't sending — double-check your SMTP host and port, and confirm you're using an app password rather than your account password if your provider requires one.
- Placeholder shows up literally in the email (e.g.
{{FirstName}}) — the column name in your CSV doesn't match the placeholder exactly; names are case-sensitive. - Attachment not found errors during Preflight — check that file paths in
AttachmentFileare correct relative to where you're running the app, and that multiple files are separated by;with no typos.
Rich Text/HTML Editor with Live Preview & Placeholders
Template Library with Search, Categories & Visual Email Previews
Contributing
Issues and pull requests are welcome. If you run into a bug or have an idea for a feature, open an issue on GitHub.
License
See the LICENSE file for details.
Metadata
Release files for bit-by-mail 2.6.2
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 | |
|---|---|---|---|---|
| bit_by_mail-2.6.2.tar.gz | 3.9 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bit_by_mail-2.6.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 7.8 MB
Release files / bit_by_mail-2.6.2.tar.gz
| Download URL | bit_by_mail-2.6.2.tar.gz |
|---|---|
| Size | 3.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1c06aef3cbb50f01488d028bf19c6901db9a52f2c39b7bacdaf6991023873cda
|
|
BLAKE2b-256 checksum How to use checksums |
5cfbdd11b598830161acfb04905302f6e67f7316c6b89804d4af9423f4d25a20
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 4, 2026.
Transparency logRelease files / bit_by_mail-2.6.2-py3-none-any.whl
| Download URL | bit_by_mail-2.6.2-py3-none-any.whl |
|---|---|
| Size | 4.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db56b2ca9c166ac8c4a077fba31755f43e00de27154f3cca4397681696874e1f
|
|
BLAKE2b-256 checksum How to use checksums |
5c987f410e0a6b4793da305c34074a394cfda53ea1803c2c27bca3b5f07e5850
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 4, 2026.
Transparency logSecurity for bit-by-mail 2.6.2
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
All 2 files in this release have been uploaded with provenance metadata.
Attestation for bit_by_mail-2.6.2.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 Aug 4, 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.