Overview
We've released the official FoxReach Python SDK — a typed, ergonomic client for the FoxReach API. Whether you're building a custom CRM integration, automating lead imports, or scripting campaign management, the SDK handles authentication, pagination, and error handling so you can focus on your logic.
Install it with pip:
pip install foxreach
Quick Start
from foxreach import FoxReach
client = FoxReach(api_key="otr_your_key")
# List all active leads
leads = client.leads.list(status="active")
for lead in leads:
print(f"{lead.email} — {lead.company}")
# Create a new lead
from foxreach import LeadCreate
lead = client.leads.create(LeadCreate(
email="jane@example.com",
first_name="Jane",
last_name="Smith",
company="TechCorp",
))
print(f"Created lead: {lead.id}")
What's Included
The SDK covers every FoxReach API endpoint:
- Leads —
client.leads.list(),create(),get(),update(),delete() - Campaigns — Full lifecycle:
create(),start(),pause(),resume(),delete() - Sequences —
client.campaigns.sequences.create(),update(),delete() - Templates —
client.templates.list(),create(),update(),delete() - Email Accounts —
client.email_accounts.list(),get(),delete() - Inbox —
client.inbox.list(),get(),update(),reply() - Analytics —
client.analytics.overview(),campaign() - Webhooks —
client.webhooks.list(),create(),update(),delete()
Typed Models
Every request and response uses typed dataclasses. Your IDE gives you autocomplete and type checking out of the box:
from foxreach import CampaignCreate
campaign = client.campaigns.create(CampaignCreate(
name="Q1 Enterprise Outreach",
timezone="America/New_York",
sending_days=[1, 2, 3, 4, 5],
sending_start_hour=9,
sending_end_hour=17,
daily_limit=50,
))
Auto-Pagination
List endpoints return paginated results. The SDK handles pagination automatically — just iterate:
# Fetches all pages automatically
for lead in client.leads.list(status="active"):
process_lead(lead)
Or get a single page:
page = client.leads.list(page=1, limit=50)
print(f"Total: {page.total}, Page: {page.page}")
for lead in page.data:
print(lead.email)
Async Support
The SDK ships with a fully async client for use with asyncio:
from foxreach import AsyncFoxReach
client = AsyncFoxReach(api_key="otr_your_key")
leads = await client.leads.list(status="active")
for lead in leads:
print(lead.email)
await client.close()
Error Handling
API errors are raised as typed exceptions with status codes and messages:
from foxreach import FoxReachError, NotFoundError, ValidationError
try:
lead = client.leads.get("cld_nonexistent")
except NotFoundError:
print("Lead not found")
except ValidationError as e:
print(f"Invalid request: {e.message}")
except FoxReachError as e:
print(f"API error {e.status_code}: {e.message}")
End-to-End Example: Import Leads and Launch a Campaign
Here's a complete script that creates leads, builds a campaign with a sequence, and starts it:
from foxreach import FoxReach, LeadCreate, CampaignCreate, SequenceCreate
client = FoxReach(api_key="otr_your_key")
# 1. Create leads
leads = []
contacts = [
("sarah@techcorp.io", "Sarah", "Chen", "TechCorp"),
("mike@startupco.com", "Mike", "Johnson", "StartupCo"),
("lisa@enterprise.com", "Lisa", "Wang", "Enterprise Ltd"),
]
for email, first, last, company in contacts:
lead = client.leads.create(LeadCreate(
email=email,
first_name=first,
last_name=last,
company=company,
))
leads.append(lead)
print(f"Created lead: {lead.email}")
# 2. Create a campaign
campaign = client.campaigns.create(CampaignCreate(
name="Q1 Outreach",
timezone="America/New_York",
sending_days=[1, 2, 3, 4, 5],
sending_start_hour=9,
sending_end_hour=17,
daily_limit=50,
))
# 3. Add sequence steps
client.campaigns.sequences.create(campaign.id, SequenceCreate(
subject="Quick question about {{company}}",
body="Hi {{firstName}},\n\nI noticed {{company}} is growing fast...",
delay_days=0,
))
client.campaigns.sequences.create(campaign.id, SequenceCreate(
subject="Re: Quick question about {{company}}",
body="Hi {{firstName}},\n\nJust following up...",
delay_days=3,
))
# 4. Add leads to campaign
lead_ids = [lead.id for lead in leads]
client.campaigns.add_leads(campaign.id, lead_ids)
# 5. Assign email account
accounts = client.email_accounts.list()
client.campaigns.add_accounts(campaign.id, [accounts[0].id])
# 6. Start the campaign
client.campaigns.start(campaign.id)
print(f"Campaign '{campaign.name}' is now active!")
client.close()