# VeriRoute Intel Python SDK

Official Python SDK for [VeriRoute Intel](https://verirouteintel.com) phone number intelligence API.

Get caller ID (CNAM), carrier info (LRN), spam detection, and messaging provider data for any North American phone number.

## Installation

```bash
pip install verirouteintel
```

## Quick Start

```python
from verirouteintel import VeriRoute

# Initialize client
vri = VeriRoute('your_api_key')

# Look up caller ID
caller = vri.cnam('+15551234567')
print(caller.cnam)  # "JOHN DOE"

# Get carrier info
info = vri.lrn('+15551234567')
print(info.carrier)     # "Verizon Wireless"
print(info.line_type)   # "mobile"

# Check spam status
trust = vri.trust('+15551234567')
print(trust.is_spam)          # False
print(trust.complaint_count)  # 0
```

## Features

- **CNAM Lookup** - Caller ID name for any number
- **LRN/Carrier Lookup** - Carrier, line type (mobile/landline/VoIP)
- **Enhanced Data** - City, state, ZIP, timezone, rate center
- **Spam Detection** - Spam, scam, and robocall identification
- **Messaging Provider** - SMS routing information
- **Bulk Operations** - Process up to 1000 numbers per request
- **Full Type Hints** - Complete type annotations for IDE support
- **Automatic Retries** - Built-in retry logic with exponential backoff

## API Reference

### CNAM (Caller ID)

```python
from verirouteintel import VeriRoute

vri = VeriRoute('your_api_key')

# Basic CNAM lookup
result = vri.cnam('+15551234567')
print(result.number)  # "+15551234567"
print(result.cnam)    # "JOHN DOE"

# With spam detection
result = vri.cnam('+15551234567', include_spam=True)
print(result.spam_type)  # "NONE", "SPAM", "SCAM", or "ROBOCALL"
```

### LRN (Carrier & Line Type)

```python
# Basic LRN lookup
info = vri.lrn('+15551234567')
print(info.carrier)    # "Verizon Wireless"
print(info.line_type)  # "mobile", "landline", "voip", or "unknown"
print(info.lrn)        # Local Routing Number

# With enhanced location data
info = vri.lrn('+15551234567', include_enhanced=True)
print(info.enhanced.city)       # "New York"
print(info.enhanced.state)      # "NY"
print(info.enhanced.zip_code)   # "10001"
print(info.enhanced.timezone)   # "America/New_York"
print(info.enhanced.county)     # "New York"
print(info.enhanced.rate_center)  # "NWYRCYZN01"

# With messaging provider
info = vri.lrn('+15551234567', messaging_lookup=True)
print(info.messaging.provider)  # "Verizon Wireless"
print(info.messaging.enabled)   # True

# With CNAM (caller name)
info = vri.lrn('+15551234567', include_cnam=True)
print(info.cnam.caller_name)  # "ACME CORP"

# With trust/reputation data
info = vri.lrn('+15551234567', include_trust=True)
print(info.trust.reputation_score)  # 85 (0-100, higher = more trustworthy)
print(info.trust.trust_level)       # "high", "medium", or "low"
print(info.trust.is_spam)           # False
print(info.trust.last_updated)      # ISO 8601 timestamp

# All options - single API call with everything
info = vri.lrn('+15551234567',
    include_enhanced=True,
    messaging_lookup=True,
    include_cnam=True,
    include_trust=True
)
```

### Trust (Spam/Scam Detection)

```python
# Basic trust check (v1)
trust = vri.trust('+15551234567')

print(trust.is_spam)         # Boolean
print(trust.is_robocall)     # Boolean
print(trust.is_scam)         # Boolean
print(trust.spam_type)       # "NONE", "SPAM", "SCAM", "ROBOCALL", "TELEMARKETER"
print(trust.complaint_count) # Number of complaints
print(trust.subjects)        # List of complaint subjects
print(trust.first_reported)  # First complaint date
print(trust.last_reported)   # Most recent complaint

# Trust v2 - with reputation scoring
trust = vri.trust_v2('+15551234567')

print(trust.reputation_score)  # 0-100, higher = more trustworthy
print(trust.trust_level)       # "high" (>=70), "medium" (40-69), "low" (<40)
print(trust.last_updated)      # ISO 8601 timestamp
print(trust.is_spam)           # Boolean
print(trust.complaint_count)   # Number of complaints
```

### Spam Check (Lightweight)

```python
# Quick spam check (faster than trust)
spam = vri.spam('+15551234567')
print(spam.is_spam)     # Boolean
print(spam.spam_type)   # Spam classification
print(spam.cached)      # Whether result was cached
```

### Report Spam

```python
# Report a spam number
vri.spam_report('+15551234567',
    report_type='robocall',
    details='Automated car warranty scam'
)

# Report types: 'spam', 'robocall', 'scam', 'telemarketing', 'fraud', 'phishing'
```

### Messaging Provider

```python
msg = vri.messaging('+15551234567')
print(msg.messaging_provider)      # "Twilio"
print(msg.messaging_enabled)       # True
print(msg.messaging_country)       # "US"
print(msg.messaging_country_code)  # "1"
```

### Analytics & Usage

```python
# Get analytics
analytics = vri.analytics(preset='30d')
print(analytics.total_lookups)
print(analytics.carrier_type_breakdown)  # {"mobile": 500, "landline": 200, ...}
print(analytics.spam_breakdown)          # {"clean": 650, "spam": 50}

# Custom date range
analytics = vri.analytics(
    start_date='2024-01-01',
    end_date='2024-01-31'
)

# Get usage report - with period parameter
usage = vri.usage(period='week')  # 'day', 'week', or 'month'
print(usage.total_lookups)
print(usage.total_spent)
print(usage.by_product)    # {"cnam": 100, "lrn": 200, "spam": 50, ...}
print(usage.by_interface)  # {"api": 300, "web": 50, "batch": 0}
print(usage.spam_breakdown)  # {"spam": 10, "scam": 5, "robocall": 3}

# Custom date range (overrides period)
usage = vri.usage(
    start_date='2024-12-01',
    end_date='2024-12-31',
    group_by='week'  # Time series grouping
)
for entry in usage.time_series:
    print(f"{entry['date']}: {entry['count']} lookups, ${entry['spent']:.2f}")
```

### Validate API Key

```python
if vri.validate_key():
    print("API key is valid")
else:
    print("Invalid API key")
```

## Bulk Operations

Process up to 1000 numbers in a single request:

```python
numbers = ['+15551234567', '+15559876543', '+15551112222']

# Bulk CNAM
results = vri.cnam_bulk(numbers)
for result in results.results:
    print(f"{result.number}: {result.cnam}")

print(f"Success: {results.successful}/{results.total}")

# Bulk LRN with enhanced data
results = vri.lrn_bulk(numbers, include_enhanced=True)
for result in results.results:
    print(f"{result.phone_number}: {result.carrier} ({result.line_type})")
    if result.enhanced:
        print(f"  Location: {result.enhanced.city}, {result.enhanced.state}")

# Bulk spam check
results = vri.spam_batch(numbers)
for result in results.results:
    if result.is_spam:
        print(f"{result.phone_number}: SPAM ({result.spam_type})")
```

## Error Handling

```python
from verirouteintel import (
    VeriRoute,
    VeriRouteError,
    AuthenticationError,
    RateLimitError,
    InsufficientBalanceError,
    InvalidPhoneError,
    InternationalNotSupportedError,
)

vri = VeriRoute('your_api_key')

try:
    result = vri.cnam('+15551234567')
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after: {e.retry_after}s")
except InsufficientBalanceError:
    print("Add credits at verirouteintel.com/dashboard")
except InvalidPhoneError as e:
    print(f"Invalid phone: {e.phone_number}")
except InternationalNotSupportedError as e:
    print(f"Only NANP numbers supported. Got country code: {e.detected_country_code}")
except VeriRouteError as e:
    print(f"API error [{e.code}]: {e}")
```

## Configuration

```python
vri = VeriRoute(
    'your_api_key',
    base_url='https://api-service.verirouteintel.io',  # Default
    timeout=30.0,   # Request timeout in seconds
    retries=3,      # Retry attempts for failed requests
)
```

## Context Manager

The client supports context managers for automatic cleanup:

```python
with VeriRoute('your_api_key') as vri:
    result = vri.cnam('+15551234567')
    print(result.cnam)
# Client automatically closed
```

## Type Hints

Full type annotations for all methods and return types:

```python
from verirouteintel import VeriRoute, CnamResult, LrnResult

vri = VeriRoute('your_api_key')

# IDE knows result is CnamResult
result: CnamResult = vri.cnam('+15551234567')

# IDE knows info is LrnResult with optional enhanced/messaging
info: LrnResult = vri.lrn('+15551234567', include_enhanced=True)
if info.enhanced:
    city: str = info.enhanced.city
```

## Shorthand Import

```python
from verirouteintel import VRI

# Same as VeriRoute
vri = VRI('your_api_key')
```

## Requirements

- Python 3.8+
- httpx

## Links

- [API Documentation](https://verirouteintel.com/api-docs)
- [Dashboard](https://verirouteintel.com/dashboard)
- [Support](mailto:support@verirouteintel.com)

## License

MIT
