Getting Started with checkboxHQ API Suite
checkboxHQ is an email verification API suite that helps you detect disposable, public, and invalid email addresses. This guide will walk you through integrating checkboxHQ into your application.
Overview
checkboxHQ provides three specialized verification endpoints:
- Disposable Email Verification - Detect temporary/disposable email addresses (1 credit)
- DNS Verification - Check if domains have valid MX and A records (2 credits)
- Public Provider Verification - Identify emails from well-known providers like Gmail, Yahoo, etc. (1 credit)
Each verification type serves different use cases and consumes credits from your quota based on the depth of validation performed.
Quick Start
1. Create Your Account
Register for a checkboxHQ account at https://checkboxhq.com/register.
2. Generate Your API Token
After logging in, you need to create an API token to authenticate your requests.
Using the Dashboard: Navigate to your dashboard and create a new API token with a descriptive name.
Using the API:
# First, login to get your access tokencurl -X POST "https://api.checkboxhq.com/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]", "password": "your-password" }'
# Response includes access_token# {# "access_token": "eyJhbGc...",# "token_type": "bearer"# }
# Then create an API tokencurl -X POST "https://api.checkboxhq.com/api/v1/tokens/" \ -H "Authorization: Bearer eyJhbGc..." \ -H "Content-Type: application/json" \ -d '{ "name": "Production API Token" }'
# Response includes the API token# {# "id": 1,# "name": "Production API Token",# "token": "cbhq_abc123...",# "is_active": true,# "created_at": "2024-01-15T10:30:00Z",# "last_used_at": null# }Security Note: Save the token from the response immediately - you won’t be able to see it again. Store it securely in your environment variables.
3. Make Your First Verification
checkboxHQ offers three verification endpoints. Choose based on your needs:
Verification Endpoints
1. Disposable Email Verification (1 Credit)
Detects if an email domain is from a disposable/temporary email service. Use this to block throwaway emails during registration.
Endpoint: POST /api/v1/verify_disposable/
Example Request:
curl -X POST "https://api.checkboxhq.com/api/v1/verify_disposable/" \ -H "x-api-key: cbhq_your_token_here" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]" }'Response:
{ "is_disposable": true, "is_valid_format": true, "domain": "tempmail.com", "provider": null}Response Fields:
is_disposable- Whether the domain is a known disposable email provideris_valid_format- Whether the email format is syntactically validdomain- The extracted domain from the emailprovider- Email provider name if recognized (null otherwise)
Python Example:
import requests
def verify_disposable(email, api_key): """Check if email is from a disposable provider""" response = requests.post( "https://api.checkboxhq.com/api/v1/verify_disposable/", headers={ "x-api-key": api_key, "Content-Type": "application/json" }, json={"email": email} ) return response.json()
print(f"Disposable: {result['is_disposable']}")2. DNS Verification (2 Credits)
Verifies that the email domain has valid MX records (can receive email) and A records (has an IP address). This is a deeper validation that confirms the domain is properly configured.
Endpoint: POST /api/v1/verify_dns/
Example Request:
curl -X POST "https://api.checkboxhq.com/api/v1/verify_dns/" \ -H "x-api-key: cbhq_your_token_here" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]" }'Response:
{ "has_mx_record": true, "mx_records": [ "mx1.example.com", "mx2.example.com" ], "has_a_record": true, "a_records": [ "93.184.216.34" ], "provider": "Example Provider"}Response Fields:
has_mx_record- Whether the domain has MX records configuredmx_records- List of MX record hostnames (null if none found)has_a_record- Whether the domain has A recordsa_records- List of IP addresses (null if none found)provider- Email provider name if recognized
Python Example:
def verify_dns(email, api_key): """Verify email domain DNS configuration""" response = requests.post( "https://api.checkboxhq.com/api/v1/verify_dns/", headers={ "x-api-key": api_key, "Content-Type": "application/json" }, json={"email": email} ) return response.json()
if result['has_mx_record'] and result['has_a_record']: print("Domain is properly configured for email")else: print("Domain cannot receive email")3. Public Provider Verification (1 Credit)
Identifies if an email is from a well-known public email service (Gmail, Yahoo, Outlook, etc.). Useful for identifying personal vs. business emails.
Endpoint: POST /api/v1/verify_public_provider/
Example Request:
curl -X POST "https://api.checkboxhq.com/api/v1/verify_public_provider/" \ -H "x-api-key: cbhq_your_token_here" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]" }'Response:
{ "is_public_provider": true, "provider": "Gmail"}Response Fields:
is_public_provider- Whether the email is from a known public providerprovider- Name of the public provider (null if not recognized)
Python Example:
def verify_public_provider(email, api_key): """Check if email is from a public provider""" response = requests.post( "https://api.checkboxhq.com/api/v1/verify_public_provider/", headers={ "x-api-key": api_key, "Content-Type": "application/json" }, json={"email": email} ) return response.json()
if result['is_public_provider']: print(f"Personal email from {result['provider']}")else: print("Business or private email domain")Production Integration Patterns
Comprehensive Email Validation Function
Combine multiple endpoints for thorough validation:
import requestsfrom typing import Dict, Tuple
class CheckboxHQClient: def __init__(self, api_key: str): self.api_key = api_key self.base_url = "https://api.checkboxhq.com" self.headers = { "x-api-key": api_key, "Content-Type": "application/json" }
def verify_disposable(self, email: str) -> Dict: """Check if email is disposable (1 credit)""" response = requests.post( f"{self.base_url}/api/v1/verify_disposable/", headers=self.headers, json={"email": email}, timeout=10 ) response.raise_for_status() return response.json()
def verify_dns(self, email: str) -> Dict: """Verify DNS records (2 credits)""" response = requests.post( f"{self.base_url}/api/v1/verify_dns/", headers=self.headers, json={"email": email}, timeout=10 ) response.raise_for_status() return response.json()
def verify_public_provider(self, email: str) -> Dict: """Check if public provider (1 credit)""" response = requests.post( f"{self.base_url}/api/v1/verify_public_provider/", headers=self.headers, json={"email": email}, timeout=10 ) response.raise_for_status() return response.json()
def comprehensive_verify(self, email: str, check_disposable: bool = True, check_dns: bool = True, check_public: bool = False) -> Tuple[bool, Dict, str]: """ Comprehensive email validation with configurable checks.
Returns: (is_valid, results_dict, reason_if_invalid) """ results = {"email": email}
try: # Basic disposable check (1 credit) if check_disposable: disp_result = self.verify_disposable(email) results['disposable_check'] = disp_result
if not disp_result['is_valid_format']: return (False, results, "Invalid email format")
if disp_result['is_disposable']: return (False, results, "Disposable email not allowed")
# DNS validation (2 credits) if check_dns: dns_result = self.verify_dns(email) results['dns_check'] = dns_result
if not dns_result['has_mx_record']: return (False, results, "Domain cannot receive email (no MX records)")
if not dns_result['has_a_record']: return (False, results, "Domain does not exist (no A records)")
# Public provider check (1 credit) if check_public: public_result = self.verify_public_provider(email) results['public_check'] = public_result
return (True, results, "")
except requests.exceptions.RequestException as e: return (False, results, f"Verification failed: {str(e)}")
# Usageclient = CheckboxHQClient("cbhq_your_token")
# Quick validation (3 credits total: 1 for disposable + 2 for DNS)
if is_valid: print("Email passed all validations")else: print(f"Email rejected: {reason}")
# Custom validation (only check disposable - 1 credit)is_valid, results, reason = client.comprehensive_verify( check_dns=False, check_public=False)Error Handling
Always implement proper error handling:
def safe_verify(email, api_key): """Verify email with comprehensive error handling""" try: response = requests.post( "https://api.checkboxhq.com/api/v1/verify_disposable/", headers={ "x-api-key": api_key, "Content-Type": "application/json" }, json={"email": email}, timeout=10 )
# Handle specific HTTP errors if response.status_code == 401: return {"error": "Invalid API key"} elif response.status_code == 403: return {"error": "API key revoked or inactive"} elif response.status_code == 429: return {"error": "Rate limit exceeded"} elif response.status_code == 402: return {"error": "Insufficient credits"} elif response.status_code == 422: error_detail = response.json() return {"error": f"Validation error: {error_detail}"}
response.raise_for_status() return response.json()
except requests.exceptions.Timeout: return {"error": "Request timeout"} except requests.exceptions.ConnectionError: return {"error": "Connection failed"} except requests.exceptions.RequestException as e: return {"error": f"Request failed: {str(e)}"}Usage Monitoring
Monitor your credit usage to avoid unexpected service interruptions:
def get_usage_stats(access_token: str) -> Dict: """Get current billing period usage statistics""" response = requests.get( "https://api.checkboxhq.com/api/v1/billing/usage", headers={"Authorization": f"Bearer {access_token}"} ) response.raise_for_status() return response.json()
# Example usageusage = get_usage_stats("your_jwt_access_token")print(f"Credits used: {usage['credits_used']} / {usage['credits_limit']}")print(f"Usage: {usage['percentage_used']:.1f}%")print(f"Period: {usage['period']}")
# Alert if approaching limitif usage['percentage_used'] > 80: print("WARNING: Approaching credit limit!")Token Management
List All API Tokens
def list_tokens(access_token: str): """List all API tokens for your account""" response = requests.get( "https://api.checkboxhq.com/api/v1/tokens/", headers={"Authorization": f"Bearer {access_token}"} ) return response.json()
tokens = list_tokens("your_jwt_access_token")for token in tokens: print(f"ID: {token['id']}, Name: {token['name']}, Active: {token['is_active']}")Regenerate Token
If a token is compromised, regenerate it:
def regenerate_token(access_token: str, token_id: int): """Regenerate an existing API token""" response = requests.post( f"https://api.checkboxhq.com/api/v1/tokens/{token_id}/regenerate", headers={"Authorization": f"Bearer {access_token}"} ) return response.json()
# Returns new token - update your environment variables immediatelynew_token_data = regenerate_token("your_jwt_access_token", 1)print(f"New token: {new_token_data['token']}")Revoke Token
def revoke_token(access_token: str, token_id: int): """Revoke/delete an API token""" response = requests.delete( f"https://api.checkboxhq.com/api/v1/tokens/{token_id}", headers={"Authorization": f"Bearer {access_token}"} ) return response.status_code == 200Common Use Cases
1. User Registration - Block Disposable Emails
def validate_registration_email(email: str, api_key: str) -> Dict: """Validate email during user registration""" client = CheckboxHQClient(api_key)
# Check if disposable (1 credit) result = client.verify_disposable(email)
if not result['is_valid_format']: return { "valid": False, "message": "Please enter a valid email address" }
if result['is_disposable']: return { "valid": False, "message": "Temporary/disposable email addresses are not allowed" }
return { "valid": True, "message": "Email validated successfully" }2. B2B SaaS - Require Business Emails
def validate_business_email(email: str, api_key: str) -> Dict: """Ensure users register with business emails, not personal""" client = CheckboxHQClient(api_key)
# Check if public provider (1 credit) result = client.verify_public_provider(email)
if result['is_public_provider']: return { "valid": False, "message": f"Please use your business email. {result['provider']} addresses are not allowed." }
# Verify DNS to ensure domain exists (2 credits) dns_result = client.verify_dns(email)
if not dns_result['has_mx_record']: return { "valid": False, "message": "This domain cannot receive emails" }
return { "valid": True, "message": "Business email verified" }3. Email List Cleaning
def clean_email_list(emails: list, api_key: str) -> Dict: """Clean a list of emails before sending campaigns""" client = CheckboxHQClient(api_key)
valid_emails = [] invalid_emails = []
for email in emails: try: # Use DNS check for deliverability (2 credits per email) dns_result = client.verify_dns(email)
if dns_result['has_mx_record'] and dns_result['has_a_record']: valid_emails.append(email) else: invalid_emails.append({ "email": email, "reason": "Cannot receive email" }) except Exception as e: invalid_emails.append({ "email": email, "reason": str(e) })
return { "valid": valid_emails, "invalid": invalid_emails, "valid_count": len(valid_emails), "invalid_count": len(invalid_emails), "credits_used": len(emails) * 2 # DNS check costs 2 credits }4. Real-time Form Validation (Frontend + Backend)
Backend API Endpoint:
from flask import Flask, request, jsonify
app = Flask(__name__)CHECKBOX_API_KEY = "cbhq_your_token"
@app.route('/api/validate-email', methods=['POST'])def validate_email(): """Backend endpoint for frontend email validation""" email = request.json.get('email')
if not email: return jsonify({"valid": False, "message": "Email required"}), 400
client = CheckboxHQClient(CHECKBOX_API_KEY)
# Quick disposable check (1 credit) result = client.verify_disposable(email)
return jsonify({ "valid": result['is_valid_format'] and not result['is_disposable'], "is_disposable": result['is_disposable'], "message": "Disposable email not allowed" if result['is_disposable'] else "" })Frontend JavaScript:
async function validateEmail(email) { try { const response = await fetch('/api/validate-email', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ email: email }) });
const result = await response.json(); return result; } catch (error) { console.error('Validation error:', error); return { valid: false, message: 'Validation service unavailable' }; }}
// Use in formdocument.getElementById('email').addEventListener('blur', async function() { const result = await validateEmail(this.value);
if (!result.valid) { showError(result.message || 'Invalid email'); } else { clearError(); }});Credit Costs Summary
| Endpoint | Credits | Use Case |
|---|---|---|
/api/v1/verify_disposable/ | 1 | Block temporary emails |
/api/v1/verify_dns/ | 2 | Verify domain can receive email |
/api/v1/verify_public_provider/ | 1 | Identify personal vs. business emails |
Optimization Tips:
- Use disposable check (1 credit) for basic user registration
- Add DNS check (2 credits) for critical flows like password reset
- Use public provider check (1 credit) only when you need to distinguish business emails
- Cache results to avoid redundant API calls for the same email
Best Practices
1. Environment Variables
Store your API key securely:
# .env fileCHECKBOXHQ_API_KEY=cbhq_your_token_hereimport osfrom dotenv import load_dotenv
load_dotenv()API_KEY = os.getenv('CHECKBOXHQ_API_KEY')2. Caching
Implement caching to reduce API costs:
from datetime import datetime, timedeltaimport hashlib
class EmailVerificationCache: def __init__(self, ttl_days=30): self.cache = {} self.ttl = timedelta(days=ttl_days)
def _get_key(self, email: str) -> str: return hashlib.sha256(email.lower().encode()).hexdigest()
def get(self, email: str): key = self._get_key(email) if key in self.cache: result, timestamp = self.cache[key] if datetime.now() - timestamp < self.ttl: return result return None
def set(self, email: str, result: dict): key = self._get_key(email) self.cache[key] = (result, datetime.now())
# Usagecache = EmailVerificationCache(ttl_days=30)
def verify_with_cache(email: str, api_key: str): # Check cache first cached = cache.get(email) if cached: return cached
# Make API call client = CheckboxHQClient(api_key) result = client.verify_disposable(email)
# Cache result cache.set(email, result) return result3. Async/Bulk Processing
For bulk email validation:
import asyncioimport aiohttp
async def verify_email_async(session, email, api_key): """Async email verification""" async with session.post( "https://api.checkboxhq.com/api/v1/verify_disposable/", headers={ "x-api-key": api_key, "Content-Type": "application/json" }, json={"email": email} ) as response: return await response.json()
async def verify_bulk(emails, api_key): """Verify multiple emails concurrently""" async with aiohttp.ClientSession() as session: tasks = [verify_email_async(session, email, api_key) for email in emails] results = await asyncio.gather(*tasks, return_exceptions=True) return results
# Usageresults = asyncio.run(verify_bulk(emails, "cbhq_your_token"))4. Rate Limiting
Implement client-side rate limiting to prevent overwhelming the API:
import timefrom collections import deque
class RateLimiter: def __init__(self, max_requests=100, time_window=60): """ max_requests: Maximum requests allowed time_window: Time window in seconds """ self.max_requests = max_requests self.time_window = time_window self.requests = deque()
def wait_if_needed(self): now = time.time()
# Remove old requests outside time window while self.requests and self.requests[0] < now - self.time_window: self.requests.popleft()
# If at limit, wait if len(self.requests) >= self.max_requests: sleep_time = self.requests[0] + self.time_window - now if sleep_time > 0: time.sleep(sleep_time) self.wait_if_needed()
self.requests.append(now)
# Usagelimiter = RateLimiter(max_requests=100, time_window=60)
for email in email_list: limiter.wait_if_needed() result = verify_disposable(email, api_key)Next Steps
- Complete API Documentation: Visit https://api.checkboxhq.com/docs for the interactive API reference
- Choose Your Plan: Check https://checkboxhq.com/pricing for credit packages and pricing
- Monitor Usage: Regularly check your credit usage via the billing endpoint
- Integrate: Start with the disposable check endpoint and add DNS verification for critical flows
Support
For questions or issues:
- Interactive API docs: https://api.checkboxhq.com/docs
- Email support: [email protected]
- Website: https://checkboxhq.com
Security Checklist
- ✅ Store API tokens in environment variables, never in code
- ✅ Use HTTPS for all API calls (enforced by checkboxHQ)
- ✅ Implement proper error handling for all API calls
- ✅ Set reasonable timeout values (10 seconds recommended)
- ✅ Monitor credit usage to avoid service interruptions
- ✅ Rotate API tokens regularly (use regenerate endpoint)
- ✅ Revoke unused tokens
- ✅ Cache validation results to reduce costs
- ✅ Implement rate limiting on your end
You’re now ready to integrate checkboxHQ and start validating emails effectively!