mailcheck-dev 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 MailCheck.dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,365 @@
1
+ Metadata-Version: 2.4
2
+ Name: mailcheck-dev
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for the MailCheck.dev email verification API. Verify emails, detect disposable addresses, check DNS/SPF/DKIM/DMARC, and bulk verify lists.
5
+ Home-page: https://mailcheck.dev
6
+ Author: MailCheck.dev
7
+ License: MIT
8
+ Project-URL: Homepage, https://mailcheck.dev
9
+ Project-URL: Repository, https://github.com/bnuyts/mailcheck-python
10
+ Project-URL: Documentation, https://mailcheck.dev/docs
11
+ Project-URL: Bug Reports, https://github.com/bnuyts/mailcheck-python/issues
12
+ Keywords: email,verification,validate,mailcheck,disposable,email-validation,email-verification,bulk-verify,spf,dkim,dmarc,mx,dns,api,sdk
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Communications :: Email
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: requests>=2.25.0
30
+ Requires-Dist: typing_extensions>=4.0.0; python_version < "3.11"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=6.0.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
34
+ Requires-Dist: responses>=0.18.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # MailCheck Python SDK
38
+
39
+ [![PyPI version](https://badge.fury.io/py/mailcheck-dev.svg)](https://badge.fury.io/py/mailcheck-dev)
40
+ [![Python version](https://img.shields.io/pypi/pyversions/mailcheck-dev.svg)](https://pypi.org/project/mailcheck-dev/)
41
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
42
+
43
+ Official Python SDK for the [MailCheck.dev](https://mailcheck.dev) email verification API. Verify email addresses, detect disposable addresses, check DNS/SPF/DKIM/DMARC authentication, and bulk verify email lists with high accuracy.
44
+
45
+ ## Features
46
+
47
+ - ✅ **Single Email Verification** - Verify individual email addresses
48
+ - 🔄 **Bulk Email Verification** - Verify up to 100 emails in one request
49
+ - 🔐 **Email Authentication** - Check SPF, DKIM, and DMARC records
50
+ - 🚫 **Disposable Email Detection** - Identify temporary email services
51
+ - 📊 **Detailed Results** - Get comprehensive verification data
52
+ - ⚡ **Fast & Reliable** - Built on proven infrastructure
53
+ - 🛡️ **Type Safe** - Full type hints for better development experience
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install mailcheck-dev
59
+ ```
60
+
61
+ ## Quick Start
62
+
63
+ ```python
64
+ from mailcheck import MailCheck, MailCheckError
65
+
66
+ # Initialize client
67
+ mc = MailCheck("sk_live_your_api_key")
68
+
69
+ try:
70
+ # Verify a single email
71
+ result = mc.verify("user@example.com")
72
+ print(f"Email: {result['email']}")
73
+ print(f"Valid: {result['valid']}")
74
+ print(f"Score: {result['score']}")
75
+ print(f"Credits remaining: {result['credits_remaining']}")
76
+
77
+ except MailCheckError as e:
78
+ print(f"Error: {e}")
79
+ ```
80
+
81
+ ## Authentication
82
+
83
+ Get your API key from the [MailCheck.dev dashboard](https://mailcheck.dev/dashboard). The SDK supports both test and live keys:
84
+
85
+ - Secret keys: `sk_live_...` (for server-side use)
86
+ - Public keys: `pk_live_...` (for client-side widget use, domain-restricted)
87
+
88
+ ## Configuration
89
+
90
+ ```python
91
+ from mailcheck import MailCheck
92
+
93
+ # Basic configuration
94
+ mc = MailCheck("sk_live_your_api_key")
95
+
96
+ # Custom configuration
97
+ mc = MailCheck("sk_live_your_api_key", {
98
+ "base_url": "https://api.mailcheck.dev", # Custom API endpoint
99
+ "timeout": 30 # Request timeout in seconds (default: 30)
100
+ })
101
+ ```
102
+
103
+ ## API Reference
104
+
105
+ ### Single Email Verification
106
+
107
+ Verify individual email addresses with detailed analysis:
108
+
109
+ ```python
110
+ result = mc.verify("user@example.com")
111
+
112
+ # Response structure
113
+ {
114
+ "email": "user@example.com",
115
+ "valid": True,
116
+ "score": 85, # 0-100 confidence score
117
+ "reason": "Valid email address",
118
+ "checks": {
119
+ "syntax": "pass", # Email format validation
120
+ "disposable": "pass", # Disposable email detection
121
+ "mx": "pass", # MX record check
122
+ "smtp": "pass", # SMTP server validation
123
+ "role": "skip", # Role account detection
124
+ "free_provider": False # Free email provider flag
125
+ },
126
+ "details": {
127
+ "mxHost": "mail.example.com",
128
+ "isDisposable": False,
129
+ "catchAll": None,
130
+ "risk_level": "low",
131
+ "is_role": False,
132
+ "is_free_provider": False,
133
+ # ... additional details
134
+ },
135
+ "cached": False,
136
+ "credits_remaining": 99
137
+ }
138
+ ```
139
+
140
+ ### Bulk Email Verification
141
+
142
+ Verify multiple email addresses in a single request:
143
+
144
+ ```python
145
+ emails = [
146
+ "user1@example.com",
147
+ "user2@example.com",
148
+ "invalid@nonexistent.com"
149
+ ]
150
+
151
+ # Basic bulk verification
152
+ job = mc.bulk.verify(emails)
153
+
154
+ # With webhook notification
155
+ job = mc.bulk.verify(emails, {
156
+ "webhook_url": "https://your-site.com/webhook"
157
+ })
158
+
159
+ print(f"Job ID: {job['job_id']}")
160
+ print(f"Results: {len(job['results'])}")
161
+ print(f"Credits remaining: {job['credits_remaining']}")
162
+ ```
163
+
164
+ ### Email Authentication Verification
165
+
166
+ Check SPF, DKIM, and DMARC authentication for email security:
167
+
168
+ ```python
169
+ # From email headers
170
+ auth_result = mc.verify_auth({
171
+ "headers": "From: sender@example.com\nTo: recipient@test.com\n..."
172
+ })
173
+
174
+ # From raw email content
175
+ auth_result = mc.verify_auth({
176
+ "raw_email": "Full email content including headers and body"
177
+ })
178
+
179
+ # With trusted domains (won't flag as suspicious)
180
+ auth_result = mc.verify_auth({
181
+ "headers": "From: sender@example.com\n...",
182
+ "trusted_domains": ["example.com", "yourcompany.com"]
183
+ })
184
+
185
+ # Response structure
186
+ {
187
+ "trust_score": 85, # 0-100 trust score
188
+ "verdict": "trusted", # "trusted", "suspicious", or "dangerous"
189
+ "from_": {
190
+ "address": "sender@example.com",
191
+ "display_name": "John Doe",
192
+ "domain": "example.com"
193
+ },
194
+ "authentication": {
195
+ "spf": {
196
+ "result": "pass",
197
+ "domain": "example.com"
198
+ },
199
+ "dkim": {
200
+ "result": "present",
201
+ "has_public_key": True
202
+ },
203
+ "dmarc": {
204
+ "has_policy": True,
205
+ "policy": "quarantine"
206
+ }
207
+ },
208
+ "anomalies": [],
209
+ "lookalike": {
210
+ "is_lookalike": False
211
+ },
212
+ "privacy": {
213
+ "body_processed": False,
214
+ "headers_only": True
215
+ },
216
+ "credits_remaining": 98
217
+ }
218
+ ```
219
+
220
+ ## Error Handling
221
+
222
+ The SDK raises `MailCheckError` for API-related errors:
223
+
224
+ ```python
225
+ from mailcheck import MailCheck, MailCheckError
226
+
227
+ mc = MailCheck("sk_live_your_api_key")
228
+
229
+ try:
230
+ result = mc.verify("invalid-email")
231
+ except MailCheckError as e:
232
+ print(f"Status: {e.status}") # HTTP status code
233
+ print(f"Code: {e.code}") # Error code from API
234
+ print(f"Message: {str(e)}") # Human-readable message
235
+
236
+ # Handle specific error types
237
+ if e.status == 401:
238
+ print("Invalid API key")
239
+ elif e.status == 429:
240
+ print("Rate limit exceeded")
241
+ elif e.code == "insufficient_credits":
242
+ print("Not enough credits")
243
+ ```
244
+
245
+ Common error codes:
246
+ - `invalid_email` - Email format is invalid
247
+ - `insufficient_credits` - Account has no remaining credits
248
+ - `rate_limit_exceeded` - Too many requests
249
+ - `timeout` - Request timed out
250
+
251
+ ## Rate Limits
252
+
253
+ The API has built-in rate limiting. The SDK will automatically raise a `MailCheckError` if you exceed your rate limit. Consider implementing exponential backoff for production applications:
254
+
255
+ ```python
256
+ import time
257
+ from mailcheck import MailCheckError
258
+
259
+ def verify_with_retry(mc, email, max_retries=3):
260
+ for attempt in range(max_retries):
261
+ try:
262
+ return mc.verify(email)
263
+ except MailCheckError as e:
264
+ if e.status == 429 and attempt < max_retries - 1:
265
+ # Exponential backoff: 1s, 2s, 4s
266
+ wait_time = 2 ** attempt
267
+ time.sleep(wait_time)
268
+ continue
269
+ raise
270
+ ```
271
+
272
+ ## Type Safety
273
+
274
+ The SDK includes comprehensive type hints for better IDE support and error prevention:
275
+
276
+ ```python
277
+ from mailcheck import MailCheck
278
+ from mailcheck.types import VerifyResult, MailCheckOptions
279
+
280
+ options: MailCheckOptions = {
281
+ "timeout": 60
282
+ }
283
+
284
+ mc = MailCheck("sk_live_your_api_key", options)
285
+ result: VerifyResult = mc.verify("test@example.com")
286
+
287
+ # Your IDE will provide full autocomplete and type checking
288
+ print(result["score"]) # Type: int
289
+ print(result["valid"]) # Type: bool
290
+ ```
291
+
292
+ ## Examples
293
+
294
+ ### Validating User Signups
295
+
296
+ ```python
297
+ from mailcheck import MailCheck, MailCheckError
298
+
299
+ def validate_signup_email(email: str) -> bool:
300
+ mc = MailCheck("sk_live_your_api_key")
301
+
302
+ try:
303
+ result = mc.verify(email)
304
+
305
+ # Reject disposable emails and low-quality addresses
306
+ if result["details"].get("isDisposable"):
307
+ print("Disposable email not allowed")
308
+ return False
309
+
310
+ if result["score"] < 70: # Adjust threshold as needed
311
+ print("Email quality too low")
312
+ return False
313
+
314
+ return result["valid"]
315
+
316
+ except MailCheckError as e:
317
+ print(f"Verification failed: {e}")
318
+ return False
319
+ ```
320
+
321
+ ### Cleaning an Email List
322
+
323
+ ```python
324
+ def clean_email_list(emails: list) -> dict:
325
+ mc = MailCheck("sk_live_your_api_key")
326
+
327
+ # Process in batches of 100
328
+ batch_size = 100
329
+ all_results = []
330
+
331
+ for i in range(0, len(emails), batch_size):
332
+ batch = emails[i:i + batch_size]
333
+
334
+ try:
335
+ job = mc.bulk.verify(batch)
336
+ all_results.extend(job["results"])
337
+ except MailCheckError as e:
338
+ print(f"Batch failed: {e}")
339
+ continue
340
+
341
+ # Categorize results
342
+ valid_emails = [r["email"] for r in all_results if r["valid"]]
343
+ invalid_emails = [r["email"] for r in all_results if not r["valid"]]
344
+
345
+ return {
346
+ "valid": valid_emails,
347
+ "invalid": invalid_emails,
348
+ "total_processed": len(all_results)
349
+ }
350
+ ```
351
+
352
+ ## Requirements
353
+
354
+ - Python 3.8+
355
+ - `requests` library (automatically installed)
356
+
357
+ ## Support
358
+
359
+ - 📖 [Documentation](https://mailcheck.dev/docs)
360
+ - 💬 [Support](https://mailcheck.dev/support)
361
+ - 🐛 [Bug Reports](https://github.com/bnuyts/mailcheck-python/issues)
362
+
363
+ ## License
364
+
365
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,329 @@
1
+ # MailCheck Python SDK
2
+
3
+ [![PyPI version](https://badge.fury.io/py/mailcheck-dev.svg)](https://badge.fury.io/py/mailcheck-dev)
4
+ [![Python version](https://img.shields.io/pypi/pyversions/mailcheck-dev.svg)](https://pypi.org/project/mailcheck-dev/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Official Python SDK for the [MailCheck.dev](https://mailcheck.dev) email verification API. Verify email addresses, detect disposable addresses, check DNS/SPF/DKIM/DMARC authentication, and bulk verify email lists with high accuracy.
8
+
9
+ ## Features
10
+
11
+ - ✅ **Single Email Verification** - Verify individual email addresses
12
+ - 🔄 **Bulk Email Verification** - Verify up to 100 emails in one request
13
+ - 🔐 **Email Authentication** - Check SPF, DKIM, and DMARC records
14
+ - 🚫 **Disposable Email Detection** - Identify temporary email services
15
+ - 📊 **Detailed Results** - Get comprehensive verification data
16
+ - ⚡ **Fast & Reliable** - Built on proven infrastructure
17
+ - 🛡️ **Type Safe** - Full type hints for better development experience
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install mailcheck-dev
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```python
28
+ from mailcheck import MailCheck, MailCheckError
29
+
30
+ # Initialize client
31
+ mc = MailCheck("sk_live_your_api_key")
32
+
33
+ try:
34
+ # Verify a single email
35
+ result = mc.verify("user@example.com")
36
+ print(f"Email: {result['email']}")
37
+ print(f"Valid: {result['valid']}")
38
+ print(f"Score: {result['score']}")
39
+ print(f"Credits remaining: {result['credits_remaining']}")
40
+
41
+ except MailCheckError as e:
42
+ print(f"Error: {e}")
43
+ ```
44
+
45
+ ## Authentication
46
+
47
+ Get your API key from the [MailCheck.dev dashboard](https://mailcheck.dev/dashboard). The SDK supports both test and live keys:
48
+
49
+ - Secret keys: `sk_live_...` (for server-side use)
50
+ - Public keys: `pk_live_...` (for client-side widget use, domain-restricted)
51
+
52
+ ## Configuration
53
+
54
+ ```python
55
+ from mailcheck import MailCheck
56
+
57
+ # Basic configuration
58
+ mc = MailCheck("sk_live_your_api_key")
59
+
60
+ # Custom configuration
61
+ mc = MailCheck("sk_live_your_api_key", {
62
+ "base_url": "https://api.mailcheck.dev", # Custom API endpoint
63
+ "timeout": 30 # Request timeout in seconds (default: 30)
64
+ })
65
+ ```
66
+
67
+ ## API Reference
68
+
69
+ ### Single Email Verification
70
+
71
+ Verify individual email addresses with detailed analysis:
72
+
73
+ ```python
74
+ result = mc.verify("user@example.com")
75
+
76
+ # Response structure
77
+ {
78
+ "email": "user@example.com",
79
+ "valid": True,
80
+ "score": 85, # 0-100 confidence score
81
+ "reason": "Valid email address",
82
+ "checks": {
83
+ "syntax": "pass", # Email format validation
84
+ "disposable": "pass", # Disposable email detection
85
+ "mx": "pass", # MX record check
86
+ "smtp": "pass", # SMTP server validation
87
+ "role": "skip", # Role account detection
88
+ "free_provider": False # Free email provider flag
89
+ },
90
+ "details": {
91
+ "mxHost": "mail.example.com",
92
+ "isDisposable": False,
93
+ "catchAll": None,
94
+ "risk_level": "low",
95
+ "is_role": False,
96
+ "is_free_provider": False,
97
+ # ... additional details
98
+ },
99
+ "cached": False,
100
+ "credits_remaining": 99
101
+ }
102
+ ```
103
+
104
+ ### Bulk Email Verification
105
+
106
+ Verify multiple email addresses in a single request:
107
+
108
+ ```python
109
+ emails = [
110
+ "user1@example.com",
111
+ "user2@example.com",
112
+ "invalid@nonexistent.com"
113
+ ]
114
+
115
+ # Basic bulk verification
116
+ job = mc.bulk.verify(emails)
117
+
118
+ # With webhook notification
119
+ job = mc.bulk.verify(emails, {
120
+ "webhook_url": "https://your-site.com/webhook"
121
+ })
122
+
123
+ print(f"Job ID: {job['job_id']}")
124
+ print(f"Results: {len(job['results'])}")
125
+ print(f"Credits remaining: {job['credits_remaining']}")
126
+ ```
127
+
128
+ ### Email Authentication Verification
129
+
130
+ Check SPF, DKIM, and DMARC authentication for email security:
131
+
132
+ ```python
133
+ # From email headers
134
+ auth_result = mc.verify_auth({
135
+ "headers": "From: sender@example.com\nTo: recipient@test.com\n..."
136
+ })
137
+
138
+ # From raw email content
139
+ auth_result = mc.verify_auth({
140
+ "raw_email": "Full email content including headers and body"
141
+ })
142
+
143
+ # With trusted domains (won't flag as suspicious)
144
+ auth_result = mc.verify_auth({
145
+ "headers": "From: sender@example.com\n...",
146
+ "trusted_domains": ["example.com", "yourcompany.com"]
147
+ })
148
+
149
+ # Response structure
150
+ {
151
+ "trust_score": 85, # 0-100 trust score
152
+ "verdict": "trusted", # "trusted", "suspicious", or "dangerous"
153
+ "from_": {
154
+ "address": "sender@example.com",
155
+ "display_name": "John Doe",
156
+ "domain": "example.com"
157
+ },
158
+ "authentication": {
159
+ "spf": {
160
+ "result": "pass",
161
+ "domain": "example.com"
162
+ },
163
+ "dkim": {
164
+ "result": "present",
165
+ "has_public_key": True
166
+ },
167
+ "dmarc": {
168
+ "has_policy": True,
169
+ "policy": "quarantine"
170
+ }
171
+ },
172
+ "anomalies": [],
173
+ "lookalike": {
174
+ "is_lookalike": False
175
+ },
176
+ "privacy": {
177
+ "body_processed": False,
178
+ "headers_only": True
179
+ },
180
+ "credits_remaining": 98
181
+ }
182
+ ```
183
+
184
+ ## Error Handling
185
+
186
+ The SDK raises `MailCheckError` for API-related errors:
187
+
188
+ ```python
189
+ from mailcheck import MailCheck, MailCheckError
190
+
191
+ mc = MailCheck("sk_live_your_api_key")
192
+
193
+ try:
194
+ result = mc.verify("invalid-email")
195
+ except MailCheckError as e:
196
+ print(f"Status: {e.status}") # HTTP status code
197
+ print(f"Code: {e.code}") # Error code from API
198
+ print(f"Message: {str(e)}") # Human-readable message
199
+
200
+ # Handle specific error types
201
+ if e.status == 401:
202
+ print("Invalid API key")
203
+ elif e.status == 429:
204
+ print("Rate limit exceeded")
205
+ elif e.code == "insufficient_credits":
206
+ print("Not enough credits")
207
+ ```
208
+
209
+ Common error codes:
210
+ - `invalid_email` - Email format is invalid
211
+ - `insufficient_credits` - Account has no remaining credits
212
+ - `rate_limit_exceeded` - Too many requests
213
+ - `timeout` - Request timed out
214
+
215
+ ## Rate Limits
216
+
217
+ The API has built-in rate limiting. The SDK will automatically raise a `MailCheckError` if you exceed your rate limit. Consider implementing exponential backoff for production applications:
218
+
219
+ ```python
220
+ import time
221
+ from mailcheck import MailCheckError
222
+
223
+ def verify_with_retry(mc, email, max_retries=3):
224
+ for attempt in range(max_retries):
225
+ try:
226
+ return mc.verify(email)
227
+ except MailCheckError as e:
228
+ if e.status == 429 and attempt < max_retries - 1:
229
+ # Exponential backoff: 1s, 2s, 4s
230
+ wait_time = 2 ** attempt
231
+ time.sleep(wait_time)
232
+ continue
233
+ raise
234
+ ```
235
+
236
+ ## Type Safety
237
+
238
+ The SDK includes comprehensive type hints for better IDE support and error prevention:
239
+
240
+ ```python
241
+ from mailcheck import MailCheck
242
+ from mailcheck.types import VerifyResult, MailCheckOptions
243
+
244
+ options: MailCheckOptions = {
245
+ "timeout": 60
246
+ }
247
+
248
+ mc = MailCheck("sk_live_your_api_key", options)
249
+ result: VerifyResult = mc.verify("test@example.com")
250
+
251
+ # Your IDE will provide full autocomplete and type checking
252
+ print(result["score"]) # Type: int
253
+ print(result["valid"]) # Type: bool
254
+ ```
255
+
256
+ ## Examples
257
+
258
+ ### Validating User Signups
259
+
260
+ ```python
261
+ from mailcheck import MailCheck, MailCheckError
262
+
263
+ def validate_signup_email(email: str) -> bool:
264
+ mc = MailCheck("sk_live_your_api_key")
265
+
266
+ try:
267
+ result = mc.verify(email)
268
+
269
+ # Reject disposable emails and low-quality addresses
270
+ if result["details"].get("isDisposable"):
271
+ print("Disposable email not allowed")
272
+ return False
273
+
274
+ if result["score"] < 70: # Adjust threshold as needed
275
+ print("Email quality too low")
276
+ return False
277
+
278
+ return result["valid"]
279
+
280
+ except MailCheckError as e:
281
+ print(f"Verification failed: {e}")
282
+ return False
283
+ ```
284
+
285
+ ### Cleaning an Email List
286
+
287
+ ```python
288
+ def clean_email_list(emails: list) -> dict:
289
+ mc = MailCheck("sk_live_your_api_key")
290
+
291
+ # Process in batches of 100
292
+ batch_size = 100
293
+ all_results = []
294
+
295
+ for i in range(0, len(emails), batch_size):
296
+ batch = emails[i:i + batch_size]
297
+
298
+ try:
299
+ job = mc.bulk.verify(batch)
300
+ all_results.extend(job["results"])
301
+ except MailCheckError as e:
302
+ print(f"Batch failed: {e}")
303
+ continue
304
+
305
+ # Categorize results
306
+ valid_emails = [r["email"] for r in all_results if r["valid"]]
307
+ invalid_emails = [r["email"] for r in all_results if not r["valid"]]
308
+
309
+ return {
310
+ "valid": valid_emails,
311
+ "invalid": invalid_emails,
312
+ "total_processed": len(all_results)
313
+ }
314
+ ```
315
+
316
+ ## Requirements
317
+
318
+ - Python 3.8+
319
+ - `requests` library (automatically installed)
320
+
321
+ ## Support
322
+
323
+ - 📖 [Documentation](https://mailcheck.dev/docs)
324
+ - 💬 [Support](https://mailcheck.dev/support)
325
+ - 🐛 [Bug Reports](https://github.com/bnuyts/mailcheck-python/issues)
326
+
327
+ ## License
328
+
329
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.