Metadata-Version: 2.4
Name: mailfloss
Version: 0.1.0
Summary: Official Mailfloss Python SDK — email verification API client (zero dependencies)
Author-email: Mailfloss <support@mailfloss.com>
License: MIT
Project-URL: Homepage, https://github.com/mailfloss/mailfloss-python
Project-URL: Repository, https://github.com/mailfloss/mailfloss-python
Project-URL: Documentation, https://developers.mailfloss.com
Project-URL: Changelog, https://github.com/mailfloss/mailfloss-python/blob/main/CHANGELOG.md
Keywords: mailfloss,email,verification,email-verification,api,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Mailfloss Python SDK

The official Python SDK for the [Mailfloss](https://mailfloss.com) email
verification API. Zero runtime dependencies — standard library only.

- Full coverage of the Mailfloss v1 public API
- Automatic retries (429/5xx, `Retry-After` aware, exponential backoff + jitter)
- Automatic `Idempotency-Key` on every POST
- Fully typed (`TypedDict` models, ships `py.typed`)
- Python 3.9+

## Installation

```bash
pip install mailfloss
```

## Authentication

Get your API key from the Mailfloss dashboard, then either pass it directly:

```python
from mailfloss import Mailfloss

client = Mailfloss(api_key="mf_rk_your_key_here")
```

or set it in the environment and construct the client with no arguments:

```bash
export MAILFLOSS_API_KEY="mf_rk_your_key_here"
```

```python
from mailfloss import Mailfloss

client = Mailfloss()
```

Every request is sent with `Authorization: Bearer <key>`. If no key is
available, the constructor raises `MailflossConfigError`.

## Quickstart

### Verify a single email — `GET /v1/verify`

```python
from mailfloss import Mailfloss

client = Mailfloss()

result = client.verify("jane@example.com")
print(result["status"])   # "passed" | "undeliverable" | "risky" | "unknown"
print(result["passed"])   # True if safe to send
print(result["reason"])   # e.g. "available", "nonexistent", ...
if result.get("suggestion"):
    print("Did you mean:", result["suggestion"])
```

### Verify a batch — `POST /v1/batch-verify`

```python
job = client.batch_verify.create(
    emails=["jane@example.com", "joe@exmaple.com"],
    webhook_url="https://example.com/hooks/mailfloss",  # optional callback
)
job_id = job["id"]

# Poll progress...
status = client.batch_verify.status(job_id)
print(status["status"], status.get("progress"))

# ...then page through results
page = client.batch_verify.results(job_id, per_page=500)
for row in page.get("results", []):
    print(row)
```

## Error handling

Non-2xx responses raise `MailflossError` with structured fields:

```python
from mailfloss import Mailfloss, MailflossError

client = Mailfloss()
try:
    client.jobs.get("does-not-exist")
except MailflossError as err:
    print(err.status)      # 404
    print(err.code)        # stable machine-readable code
    print(err.message)     # human-readable message
    print(err.type)        # e.g. "not_found_error"
    print(err.request_id)  # for support correlation
```

Requests failing with 429 or 5xx (and connection errors) are retried
automatically up to `max_retries` (default 3), honoring the server's
`Retry-After` header when present.

## API surface

| Resource | Methods |
|---|---|
| Single verify | `client.verify(email, timeout=None)` |
| Batch verify | `client.batch_verify.create(emails, webhook_url=None)` / `.status(id)` / `.results(id, per_page=None, next=None)` / `.cancel(id)` |
| Jobs | `client.jobs.list(per_page=None, cursor=None, source=None, status=None)` / `.get(id)` |
| Users | `client.users.list(per_page=None, cursor=None)` / `.get(user_id)` |
| Reports | `client.reports.usage(period=None, connection_id=None)` |
| Key check | `client.check_key()` |
| Account | `client.account.get()` / `.update({...})` |
| Organization | `client.organization.get()` |
| Integrations | `client.integrations.list()` / `.get(type)` |
| Connections | `client.integrations.connections.create(type, credentials, name=None)` / `.get(type, id)` / `.update(type, id, {...})` / `.delete(type, id)` / `.sync(type, id)` / `.test(type, id)` |
| Keyword rules | `client.integrations.keywords.list(type, connection_id, list)` / `.add(type, connection_id, list, rules)` / `.delete(type, connection_id, list, rule_id)` |
| Erasures | `client.erasures.create(emails, webhook_url=None)` |

List endpoints return `{"data": [...], "pagination": {"next_cursor", "has_more"}}`.

## Configuration

```python
client = Mailfloss(
    api_key="mf_rk_...",                        # or MAILFLOSS_API_KEY
    base_url="https://api.mailfloss.com/v1",    # default
    max_retries=3,                              # retries on 429/5xx/conn errors
    timeout=30.0,                               # socket timeout, seconds
    transport=None,                             # injectable low-level transport
)
```

### Idempotency

Every POST automatically carries an `Idempotency-Key` header (UUIDv4),
generated once per call so retries replay the same key. Supply your own when
you want cross-process dedup:

```python
client.batch_verify.create(
    emails=["jane@example.com"],
    idempotency_key="order-12345-verify",  # gitleaks:allow — docs example, not a secret
)
```

## Development

```bash
cd sdks/python
PYTHONPATH=src python3 -m unittest discover -s tests -v
```

## License

MIT — see [LICENSE](LICENSE).
