Catalog PyPI
PACKAGE EXPLORERView in registry

AD-SearchAPI

PyPI

A comprehensive Python client library for the Search API with enhanced error handling and balance management

api-clientbalance-managementdomain-searchemail-searchpeople-searchphone-searchsearch-api
Versions collected1
Direct dependencies11From release 2.0.5
Last observed20 Oct, 19:53 UTC

README

Version 2.0.5 documentation

Search API Python Client v2.0

A comprehensive Python client library for the Search API with enhanced error handling, balance management, and improved data processing. Acquire your API key through @ADSearchEngine_bot on Telegram.

🚀 New in v2.0

  • Enhanced Balance Management: Manual balance checking capabilities
  • Access Logs Integration: Retrieve and analyze API access logs
  • Improved Error Handling: Comprehensive exception hierarchy with detailed error messages
  • Better Data Models: Enhanced data structures with metadata and cost tracking
  • Context Manager Support: Automatic resource cleanup
  • Comprehensive Validation: Input validation for all search types
  • Multiple Phone Formats: Support for international, national, and E164 formats
  • Batch Operations: Efficient handling of multiple searches
  • Debug Mode: Detailed logging for troubleshooting
  • URL Encoding Fix: Proper handling of phone numbers with + prefix
  • Response Parsing: Robust handling of both list and dictionary API responses
  • Phone Recovery Verification: Email search option via recovery_check, recovery_modules; retrieve available modules with get_recovery_modules()
  • Company Search: search_company(company, country=..., page=..., limit=...) returns CompanySearchResult (same shape as domain)
  • Usage & Cache Stats: get_usage_stats(), get_cache_stats(), get_access_logs(limit=...) with full response models
  • Pricing & Recovery: PricingInfo.recovery_check_cost, EmailSearchResult.recovery_check (RecoveryCheckResult), RecoveryModule, RecoveryModulesResponse, UsageStats
  • Rich result data: All search result types can include TLO/enrichment: addresses_structured, all_names, all_dobs, related_persons, criminal_records, phone_numbers_full, censored_numbers, confirmed_numbers, other_emails, alternative_names

📦 Installation

pip install AD-SearchAPI

⚡ Quick Start

from search_api import SearchAPI, InsufficientBalanceError

client = SearchAPI(api_key="your_api_key")

try:
    balance = client.get_balance()
    print(f"Current balance: {balance}")
    print(f"Cost per search: ${balance.credit_cost_per_search}")
    
    access_logs = client.get_access_logs()
    print(f"Total access log entries: {len(access_logs)}")
    
    result = client.search_email(
        "example@domain.com",
        house_value=True,
        extra_info=True
    )
    
    print(f"Name: {result.person.name if result.person else 'N/A'}")
    print(f"Total results: {result.total_results}")
    print(f"Search cost: ${result.search_cost}")
    
    for addr in result.addresses:
        print(f"Address: {addr}")
        if addr.zestimate:
            print(f"  Zestimate: ${addr.zestimate:,.2f}")
    
except InsufficientBalanceError as e:
    print(f"Insufficient balance: {e}")
    print(f"Current: {e.current_balance}, Required: {e.required_credits}")

🔧 Advanced Configuration

from search_api import SearchAPI, SearchAPIConfig

config = SearchAPIConfig(
    api_key="your_api_key",
    debug_mode=True,           # Enable debug logging
    timeout=120,              # 2 minutes timeout
    max_retries=5,           # Retry failed requests
    proxy={                   # Optional proxy
        "http": "http://proxy:8080",
        "https": "https://proxy:8080"
    }
)

client = SearchAPI(config=config)

💰 Balance Management

The client provides balance checking capabilities, but does not automatically check balance before each search. You should check your balance manually when needed:

from search_api import InsufficientBalanceError

try:
    balance = client.get_balance()
    print(f"Balance: {balance.current_balance} {balance.currency}")
    print(f"Cost per search: {balance.credit_cost_per_search}")
    
    # Calculate required credits based on actual search costs
    email_search_cost = 0.0025
    phone_search_cost = 0.0025
    domain_search_cost = 0.0025
    
    required_credits = 5 * email_search_cost
    if balance.current_balance < required_credits:
        print(f"⚠️  Insufficient balance for {required_credits} searches")
    else:
        print(f"✅ Sufficient balance for {required_credits} searches")
        
except InsufficientBalanceError as e:
    print(f"❌ Insufficient balance: {e}")
    print(f"   Current: {e.current_balance}")
    print(f"   Required: {e.required_credits}")

💵 Pricing Information

Search Costs:

  • Email Search: $0.0025 per search
  • Phone Search: $0.0025 per search
  • Domain Search: $0.0025 per search

Optional Parameters:

  • House Value (Zestimate): Additional $0.0015 per successful lookup
  • Extra Info: Additional $0.0015 per successful lookup
  • Carrier Info: Additional $0.0005 per successful lookup
  • TLO Enrichment: Additional $0.0025 per successful lookup
  • Phone Recovery Verification: Variable per module ($0.001–$0.003); only for email search

📊 Access Logs & Usage

Retrieve access logs (optional limit), usage stats, and cache stats:

# Get access logs (optional limit, default 100, max 1000)
access_logs = client.get_access_logs(limit=50)

print(f"Total access log entries: {len(access_logs)}")

# Show recent activity
for log in access_logs[:5]:
    print(f"IP: {log.ip_address}")
    print(f"Last accessed: {log.last_accessed}")
    print(f"Search type: {log.search_type}, Cost: {log.search_cost}")
    print("---")

# Usage statistics (today and total)
stats = client.get_usage_stats()
print(f"Today: {stats.today_searches} searches, ${stats.today_cost:.4f}")
print(f"Total: {stats.total_searches} searches, ${stats.total_cost:.4f}")

# Cache statistics
cache_stats = client.get_cache_stats()
print("Cache:", cache_stats)

# Available recovery modules (for email recovery verification)
recovery = client.get_recovery_modules()
print("Recovery modules:", [m.module_name for m in recovery.modules])
print("Pricing:", recovery.pricing)
# Use in search_email(..., recovery_check=True, recovery_modules={"module_order": [...], "enabled_modules": [...]})

# Analyze access patterns
unique_ips = set(log.ip_address for log in access_logs)
print(f"Unique IP addresses: {len(unique_ips)}")

# Find most active IP
ip_counts = {}
for log in access_logs:
    ip_counts[log.ip_address] = ip_counts.get(log.ip_address, 0) + 1

most_active_ip = max(ip_counts.items(), key=lambda x: x[1])
print(f"Most active IP: {most_active_ip[0]} ({most_active_ip[1]} accesses)")

🔍 Search Operations

result = client.search_email(
    "john.doe@example.com",
    house_value=True,
    extra_info=True,
    carrier_info=True,
    tlo_enrichment=True,
    recovery_check=True,  # Phone Recovery Verification (email only)
    recovery_modules={"module_order": ["yahoo", "outlook"], "enabled_modules": ["yahoo", "outlook"]},  # optional
    phone_format="international"  # or "national", "e164"
)

print(f"Email: {result.email}")
print(f"Valid: {result.email_valid}")
print(f"Type: {result.email_type}")
print(f"Search Cost: ${result.search_cost}")

# Access detailed pricing breakdown
if result.pricing:
    print(f"Pricing Breakdown:")
    print(f"  Base Search: ${result.pricing.search_cost:.4f}")
    print(f"  Extra Info: ${result.pricing.extra_info_cost:.4f}")
    print(f"  Zestimate: ${result.pricing.zestimate_cost:.4f}")
    print(f"  Carrier: ${result.pricing.carrier_cost:.4f}")
    print(f"  TLO Enrichment: ${result.pricing.tlo_enrichment_cost:.4f}")
    if result.pricing.recovery_check_cost:
        print(f"  Recovery Check: ${result.pricing.recovery_check_cost:.4f}")
    print(f"  Total Cost: ${result.pricing.total_cost:.4f}")

# Phone Recovery Verification result (when recovery_check=True)
if result.recovery_check:
    print(f"Recovery matched: {result.recovery_check.matched}")
    print(f"Matched number: {result.recovery_check.matched_number}")
    print(f"Modules used: {result.recovery_check.modules_used}")

if result.person:
    print(f"Name: {result.person.name}")
    print(f"DOB: {result.person.dob}")
    print(f"Age: {result.person.age}")

for addr in result.addresses:
    print(f"Address: {addr}")
    if addr.zestimate:
        print(f"  Zestimate: ${addr.zestimate:,.2f}")

for phone in result.phone_numbers:
    print(f"Phone: {phone.number}")
results = client.search_phone(
    "+1234567890",
    house_value=True,
    extra_info=True,
    carrier_info=True,
    tlo_enrichment=True,
    phone_format="international"
)

for result in results:
    print(f"Phone: {result.phone.number}")
    print(f"Search Cost: ${result.search_cost}")
    
    # Access detailed pricing breakdown
    if result.pricing:
        print(f"  Total Cost: ${result.pricing.total_cost:.4f}")
        print(f"  Breakdown: {result.pricing}")
    
    if result.person:
        print(f"Name: {result.person.name}")
        print(f"DOB: {result.person.dob}")
    
    print(f"Total results: {result.total_results}")
result = client.search_domain("example.com", page=1, limit=100)

print(f"Domain: {result.domain}")
print(f"Valid: {result.domain_valid}")
print(f"Total results: {result.total_results}")
print(f"Search Cost: ${result.search_cost}")
if result.pagination:
    print(f"Pagination: {result.pagination}")

for email_result in result.results:
    print(f"Email: {email_result.email}")
    if email_result.person:
        print(f"Name: {email_result.person.name}")
    # Each result can include TLO/enrichment: addresses_structured, all_names, all_dobs,
    # related_persons, criminal_records, phone_numbers_full, censored_numbers, confirmed_numbers, etc.
result = client.search_company("Acme Corp", country="US", page=1, limit=100)

print(f"Company: {result.company}")
print(f"Total results: {result.total_results}")
print(f"Search Cost: ${result.search_cost}")
if result.country:
    print(f"Country filter: {result.country}")

for contact in result.results:
    if contact.person:
        print(f"Name: {contact.person.name}")
    print(f"Emails: {contact.emails}")
    print(f"Phones: {[p.number for p in contact.phone_numbers]}")
    # Same rich fields as domain/email: addresses_structured, related_persons, etc.

🛡️ Error Handling

The library provides comprehensive error handling with specific exception types:

from search_api import (
    SearchAPIError,
    AuthenticationError,
    ValidationError,
    InsufficientBalanceError,
    RateLimitError,
    ServerError,
    NetworkError,
    TimeoutError,
    ConfigurationError
)

try:
    result = client.search_email("test@example.com")
except ValidationError as e:
    print(f"Invalid input: {e}")
except InsufficientBalanceError as e:
    print(f"Insufficient balance: {e}")
    print(f"Current: {e.current_balance}, Required: {e.required_credits}")
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except RateLimitError as e:
    print(f"Rate limit exceeded: {e}")
except ServerError as e:
    print(f"Server error: {e}")
except NetworkError as e:
    print(f"Network error: {e}")
except TimeoutError as e:
    print(f"Request timeout: {e}")
except SearchAPIError as e:
    print(f"API error: {e}")

🧹 Context Manager

Use the client as a context manager for automatic resource cleanup:

with SearchAPI(api_key="your_api_key") as client:
    balance = client.get_balance()
    result = client.search_email("test@example.com")
    # Resources automatically cleaned up when exiting context

📊 Data Models

Address Model

@dataclass
class Address:
    street: str
    city: Optional[str] = None
    state: Optional[str] = None
    postal_code: Optional[str] = None
    country: Optional[str] = None
    zestimate: Optional[Decimal] = None
    zpid: Optional[str] = None
    bedrooms: Optional[int] = None
    bathrooms: Optional[float] = None
    living_area: Optional[int] = None
    home_status: Optional[str] = None
    last_known_date: Optional[date] = None

Person Model

@dataclass
class Person:
    name: Optional[str] = None
    dob: Optional[date] = None
    age: Optional[int] = None

PhoneNumber Model

@dataclass
class PhoneNumber:
    number: str
    country_code: str = "US"
    is_valid: bool = True
    phone_type: Optional[str] = None
    carrier: Optional[str] = None

BalanceInfo Model

@dataclass
class BalanceInfo:
    current_balance: float
    currency: str = "USD"
    last_updated: Optional[datetime] = None
    credit_cost_per_search: Optional[float] = None

AccessLog Model

@dataclass
class AccessLog:
    ip_address: str
    last_accessed: Optional[datetime] = None
    user_agent: Optional[str] = None
    endpoint: Optional[str] = None
    method: Optional[str] = None
    status_code: Optional[int] = None
    response_time: Optional[float] = None

🔧 Configuration Options

SearchAPIConfig

ParameterTypeDefaultDescription
api_keystrRequiredYour API key
base_urlstr"https://search-api.dev/search.php"API base URL
max_retriesint1Maximum retry attempts
timeoutint90Request timeout in seconds
debug_modeboolFalseEnable debug logging
proxyDictNoneProxy configuration
user_agentstrChrome UACustom user agent

📝 Examples

See the examples/ directory for comprehensive usage examples:

  • basic_usage.py – Balance, access logs (with limit), usage stats, cache stats, recovery modules; email search (with recovery_check, extra-info fields: gender, companies, education, LinkedIn, social); phone search; company search; domain search (page/limit); error handling.
  • advanced_usage.py – Balance management, access logs with search_type/cost, usage/cache stats, recovery modules, TLO and extra-info display (gender, location_metro, companies, industry, LinkedIn, social, education), phone formats, error handling, batch email/phone/domain/company, context manager.
  • search.py – Bulk email search from file with configurable options: HOUSE_VALUE, EXTRA_INFO, CARRIER_INFO, TLO_ENRICHMENT, RECOVERY_CHECK, RECOVERY_MODULES; configurable output fields including gender, location_metro, companies, industry, linkedin, social_media, education, recovery_check.

🤝 Contributing

Contributions are welcome! Please submit a Pull Request with your changes or open an issue for discussion.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
2.0.522 Feb 202611

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
antichrist-coder/search_api_library

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:53 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:be6e489fb393bb601c00394a6783ce2005b7e4e706f653ab16decd842bceb9fd