Skip to main content
POST
/
api
/
v1
/
master-inbox
/
inbox-replies
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/inbox-replies?api_key=YOUR_KEY&fetch_message_history=false" \
  -H "Content-Type: application/json" \
  -d '{
    "offset": 0,
    "limit": 20,
    "filters": {
      "emailStatus": "Replied",
      "campaignId": [12345, 12346],
      "leadCategories": {
        "categoryIdsIn": [1]
      }
    },
    "sortBy": "REPLY_TIME_DESC"
  }'
{
  "messages": [
    {
      "id": "msg_xyz789",
      "campaign_lead_map_id": "2433664091",
      "lead": {
        "email": "sarah@startup.io",
        "first_name": "Sarah",
        "last_name": "Johnson",
        "company": "Startup Inc",
        "phone": "+1-555-0100"
      },
      "campaign": {
        "id": 12345,
        "name": "Q1 2025 SaaS Outreach"
      },
      "email_account": {
        "id": 789,
        "email": "sales@yourcompany.com",
        "name": "Sales Team"
      },
      "last_message": {
        "id": "email_abc123",
        "subject": "Re: Partnership Opportunity",
        "body": "Thanks for reaching out! I'm interested in learning more about your solution...",
        "received_at": "2025-01-20T14:30:00Z",
        "sent_from": "sarah@startup.io",
        "sent_to": "sales@yourcompany.com"
      },
      "email_status": "Replied",
      "category": {
        "id": 1,
        "name": "Interested"
      },
      "assigned_to": {
        "id": 456,
        "name": "Jane Smith",
        "email": "jane@yourcompany.com"
      },
      "stats": {
        "total_sent": 3,
        "total_opened": 2,
        "total_clicked": 1,
        "total_replied": 1,
        "last_activity": "2025-01-20T14:30:00Z"
      },
      "is_read": false,
      "is_important": false,
      "is_archived": false,
      "tags": ["hot-lead", "enterprise"]
    }
  ],
  "total_count": 1,
  "offset": 0,
  "limit": 20
}
Your central hub for all lead responses across campaigns. Essential for managing conversations, tracking engagement, and ensuring no reply goes unnoticed.

Overview

Retrieves all replies from leads across all campaigns in your unified inbox. This is the primary endpoint for managing all incoming responses from your outreach efforts. Key Features:
  • Unified view of all replies across campaigns
  • Optional full message history retrieval
  • Comprehensive filtering by campaign, account, team, tags, clients
  • Lead category filtering
  • Date range and engagement status filtering
  • Flexible sorting options
Use Cases:
  • Response management: Central inbox for all campaign replies
  • Team collaboration: Filter by assigned team members
  • Performance tracking: Monitor reply rates and patterns
  • Lead qualification: Filter by category and engagement
  • Client reporting: Segment replies by client
  • Follow-up workflows: Identify leads needing attention

Query Parameters

api_key
string
required
Your SmartLead API key
fetch_message_history
boolean
default:"false"
Include full email thread history.
  • true: Returns complete conversation thread (slower, more data)
  • false: Returns only latest message (faster, recommended for list views)
Performance tip: Use false for list views, true only when viewing individual conversations.

Request Body

offset
number
default:"0"
Number of records to skip for pagination. Must be non-negative.
limit
number
default:"20"
Number of records to return per page. Must be between 1 and 20.
filters
object
Advanced filtering options
sortBy
string
default:"REPLY_TIME_DESC"
Sort order for results
  • REPLY_TIME_DESC: Most recent replies first (default)
  • SENT_TIME_DESC: Most recently sent emails first
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/inbox-replies?api_key=YOUR_KEY&fetch_message_history=false" \
  -H "Content-Type: application/json" \
  -d '{
    "offset": 0,
    "limit": 20,
    "filters": {
      "emailStatus": "Replied",
      "campaignId": [12345, 12346],
      "leadCategories": {
        "categoryIdsIn": [1]
      }
    },
    "sortBy": "REPLY_TIME_DESC"
  }'

Response Codes

200
Success
Request successful - inbox replies retrieved
401
Unauthorized
Invalid or missing API key
422
Validation Error
Request validation failed. Common issues:
  • limit > 20
  • More than 5 campaign IDs
  • More than 20 email account IDs
  • More than 10 items in other array filters
  • Invalid date format
500
Internal Server Error
Server error occurred
{
  "messages": [
    {
      "id": "msg_xyz789",
      "campaign_lead_map_id": "2433664091",
      "lead": {
        "email": "sarah@startup.io",
        "first_name": "Sarah",
        "last_name": "Johnson",
        "company": "Startup Inc",
        "phone": "+1-555-0100"
      },
      "campaign": {
        "id": 12345,
        "name": "Q1 2025 SaaS Outreach"
      },
      "email_account": {
        "id": 789,
        "email": "sales@yourcompany.com",
        "name": "Sales Team"
      },
      "last_message": {
        "id": "email_abc123",
        "subject": "Re: Partnership Opportunity",
        "body": "Thanks for reaching out! I'm interested in learning more about your solution...",
        "received_at": "2025-01-20T14:30:00Z",
        "sent_from": "sarah@startup.io",
        "sent_to": "sales@yourcompany.com"
      },
      "email_status": "Replied",
      "category": {
        "id": 1,
        "name": "Interested"
      },
      "assigned_to": {
        "id": 456,
        "name": "Jane Smith",
        "email": "jane@yourcompany.com"
      },
      "stats": {
        "total_sent": 3,
        "total_opened": 2,
        "total_clicked": 1,
        "total_replied": 1,
        "last_activity": "2025-01-20T14:30:00Z"
      },
      "is_read": false,
      "is_important": false,
      "is_archived": false,
      "tags": ["hot-lead", "enterprise"]
    }
  ],
  "total_count": 1,
  "offset": 0,
  "limit": 20
}

Common Workflows

Daily Inbox Check

def check_daily_inbox():
    """Get all unread replies from today"""
    today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat() + 'Z'
    now = datetime.now().isoformat() + 'Z'
    
    payload = {
        "filters": {
            "emailStatus": "Replied",
            "replyTimeBetween": [today_start, now]
        },
        "sortBy": "REPLY_TIME_DESC",
        "limit": 20
    }
    
    response = get_inbox_replies(payload, fetch_history=False)
    
    unread = [msg for msg in response['messages'] if not msg['is_read']]
    print(f"{len(unread)} unread replies today")
    
    return unread

Priority Lead Follow-up

def get_hot_leads():
    """Get interested leads that replied recently"""
    three_days_ago = (datetime.now() - timedelta(days=3)).isoformat() + 'Z'
    
    payload = {
        "filters": {
            "leadCategories": {
                "categoryIdsIn": [1, 2]  # Interested, Meeting Request
            },
            "replyTimeBetween": [three_days_ago, datetime.now().isoformat() + 'Z']
        },
        "sortBy": "REPLY_TIME_DESC"
    }
    
    return get_inbox_replies(payload)

Team Workload Distribution

def get_team_workload(team_member_ids):
    """Check reply counts for each team member"""
    workload = {}
    
    for member_id in team_member_ids:
        payload = {
            "filters": {
                "campaignTeamMemberId": member_id,
                "emailStatus": "Replied"
            },
            "limit": 1  # Just need count
        }
        
        response = get_inbox_replies(payload)
        workload[member_id] = response.get('total_count', 0)
    
    return workload

Campaign Performance Monitor

def monitor_campaign_replies(campaign_ids, start_date, end_date):
    """Track reply metrics across campaigns"""
    payload = {
        "filters": {
            "campaignId": campaign_ids[:5],  # Max 5
            "replyTimeBetween": [start_date, end_date]
        },
        "limit": 20
    }
    
    response = get_inbox_replies(payload)
    messages = response.get('messages', [])
    
    # Calculate metrics
    metrics = {
        'total_replies': len(messages),
        'interested': len([m for m in messages 
                          if m.get('category', {}).get('id') == 1]),
        'by_campaign': {}
    }
    
    for msg in messages:
        campaign_id = msg['campaign']['id']
        if campaign_id not in metrics['by_campaign']:
            metrics['by_campaign'][campaign_id] = 0
        metrics['by_campaign'][campaign_id] += 1
    
    return metrics

Message History vs List View

  • List views: Displaying inbox overview
  • Counting replies: Just need totals
  • Quick filtering: Finding specific leads
  • Dashboard displays: Overview metrics
  • Mobile apps: Faster loading
  • Pagination: Browsing multiple pages
Performance: ~10x faster, ~90% less data transferred

When to Use fetch_message_history=true

  • Conversation view: Displaying full thread
  • Reply context: Need full conversation history
  • AI analysis: Processing full threads
  • Detailed reporting: Complete interaction data
  • CRM sync: Syncing full conversation history
Trade-off: Slower response, much more data, but complete context
# Fast list view
list_view_response = get_inbox_replies(
    payload,
    fetch_history=False  # Fast
)

# Then fetch details only when user clicks
def view_conversation(message_id):
    detailed_response = get_inbox_replies(
        {"filters": {"messageId": message_id}},
        fetch_history=True  # Full context
    )
    return detailed_response

Filtering Best Practices

1. Use Appropriate Array Limits

# ✅ GOOD: Within limits
filters = {
    "campaignId": [12345, 12346, 12347],  # Max 5 OK
    "emailAccountId": [1, 2, 3, ..., 20],  # Max 20 OK
    "campaignTeamMemberId": [10, 11, 12]  # Max 10 OK
}

# ❌ BAD: Exceeds limits
filters = {
    "campaignId": [1, 2, 3, 4, 5, 6, 7],  # ERROR: Max 5
}

2. Combine Category Filters

# Get engaged leads, exclude uninterested
filters = {
    "leadCategories": {
        "isAssigned": True,  # Has a category
        "categoryIdsNotIn": [3, 4]  # Exclude "Not Interested", "Do Not Contact"
    }
}

3. Smart Date Ranges

# Rolling windows for consistent monitoring
def get_recent_replies(days=7):
    end = datetime.now()
    start = end - timedelta(days=days)
    
    return {
        "replyTimeBetween": [
            start.isoformat() + 'Z',
            end.isoformat() + 'Z'
        ]
    }

4. Progressive Filtering

# Start broad, narrow down based on results
def find_replies_progressive():
    # Step 1: Get all replies
    payload1 = {"filters": {"emailStatus": "Replied"}}
    result1 = get_inbox_replies(payload1)
    
    if result1['total_count'] > 100:
        # Step 2: Add time filter
        payload2 = {
            "filters": {
                "emailStatus": "Replied",
                "replyTimeBetween": get_recent_replies(7)
            }
        }
        result2 = get_inbox_replies(payload2)
        
        if result2['total_count'] > 50:
            # Step 3: Add category filter
            payload3 = payload2.copy()
            payload3["filters"]["leadCategories"] = {"categoryIdsIn": [1]}
            return get_inbox_replies(payload3)
        
        return result2
    
    return result1

Performance Optimization

  1. Disable message history for lists: 10x faster
  2. Use pagination properly: Limit=20 is optimal
  3. Filter by campaign/account: Reduces query scope
  4. Cache frequently accessed data: Store client-side
  5. Batch similar requests: Group by filter criteria
  6. Use appropriate sort orders: Match your use case

Error Handling

def safe_get_inbox_replies(payload, fetch_history=False):
    """Get inbox replies with error handling"""
    try:
        response = requests.post(
            "https://server.smartlead.ai/api/v1/master-inbox/inbox-replies",
            params={
                "api_key": API_KEY,
                "fetch_message_history": fetch_history
            },
            json=payload,
            timeout=30  # 30 second timeout
        )
        
        response.raise_for_status()
        return response.json()
        
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 422:
            print(f"Validation error: {e.response.json()}")
            # Adjust payload and retry
        elif e.response.status_code == 429:
            print("Rate limited - waiting 60 seconds")
            time.sleep(60)
            return safe_get_inbox_replies(payload, fetch_history)
        else:
            print(f"HTTP error: {e}")
            
    except requests.exceptions.Timeout:
        print("Request timed out - try with smaller limit or disable message history")
        
    except Exception as e:
        print(f"Unexpected error: {e}")
    
    return None