FoxReach API Management Skill
You are managing the FoxReach cold email outreach platform through its Python SDK and CLI. This skill covers all API operations for leads, campaigns, sequences, templates, email accounts, inbox, and analytics.
Setup & Authentication
The Python SDK is at integrations/sdk-python/ and the CLI is at integrations/cli/. Both use API key authentication with keys prefixed otr_.
Check if the SDK is available:
CODEBLOCK0
If not installed, install it:
CODEBLOCK1
Authentication — Always get the API key from the user or environment before making calls. Never hardcode keys. Use environment variable injection:
CODEBLOCK2
Or use the CLI config:
CODEBLOCK3
How to Execute Operations
Write inline Python scripts using the SDK. Always follow this pattern:
CODEBLOCK4
For quick operations, use one-liners:
python -c "
from foxreach import FoxReach
client = FoxReach(api_key='otr_...')
result = client.leads.list(page_size=10)
for lead in result:
print(f'{lead.id} {lead.email} {lead.status}')
print(f'Total: {result.meta.total}')
client.close()
"
Resource Reference
For complete API details, see api-reference.md.
For usage examples of every operation, see examples.md.
Quick Reference — Available Operations
Leads
| Action | Method | Notes |
|---|
| List | INLINECODE3 | Paginated, filterable |
| Get |
client.leads.get(lead_id) | Returns single Lead |
| Create |
client.leads.create(LeadCreate(email=..., first_name=..., ...)) | Deduplicates by email |
| Update |
client.leads.update(lead_id, LeadUpdate(company=..., ...)) | Partial update |
| Delete |
client.leads.delete(lead_id) | Soft-delete |
Campaigns
| Action | Method | Notes |
|---|
| List | INLINECODE8 | Filter by draft/active/paused/completed |
| Get |
client.campaigns.get(campaign_id) | Includes stats |
| Create |
client.campaigns.create(CampaignCreate(name=..., ...)) | Creates in draft |
| Update |
client.campaigns.update(campaign_id, CampaignUpdate(...)) | Can't edit if active |
| Delete |
client.campaigns.delete(campaign_id) | Must be draft |
| Start |
client.campaigns.start(campaign_id) | Transitions to active |
| Pause |
client.campaigns.pause(campaign_id) | Pauses sending |
| Add Leads |
client.campaigns.add_leads(campaign_id, [lead_ids]) | Bulk add |
| Add Accounts |
client.campaigns.add_accounts(campaign_id, [account_ids]) | Assign senders |
Sequences (nested under campaigns)
| Action | Method | Notes |
|---|
| List | INLINECODE17 | All steps |
| Create |
client.campaigns.sequences.create(campaign_id, SequenceCreate(body=..., ...)) | Add step |
| Update |
client.campaigns.sequences.update(campaign_id, seq_id, SequenceUpdate(...)) | Edit step |
| Delete |
client.campaigns.sequences.delete(campaign_id, seq_id) | Remove step |
Templates
| Action | Method | Notes |
|---|
| List | INLINECODE21 | Paginated |
| Get |
client.templates.get(template_id) | Single template |
| Create |
client.templates.create(TemplateCreate(name=..., body=...)) | New template |
| Update |
client.templates.update(template_id, TemplateUpdate(...)) | Partial update |
| Delete |
client.templates.delete(template_id) | Remove |
Email Accounts
| Action | Method | Notes |
|---|
| List | INLINECODE26 | Paginated |
| Get |
client.email_accounts.get(account_id) | With health metrics |
| Delete |
client.email_accounts.delete(account_id) | Remove |
Inbox
| Action | Method | Notes |
|---|
| List Threads | INLINECODE29 | Filterable |
| Get |
client.inbox.get(reply_id) | Full thread |
| Update |
client.inbox.update(reply_id, ThreadUpdate(is_read=..., ...)) | Mark read/starred |
Analytics
| Action | Method | Notes |
|---|
| Overview | INLINECODE32 | Dashboard KPIs |
| Campaign |
client.analytics.campaign(campaign_id) | Metrics + daily stats |
Pagination
List endpoints return PaginatedResponse objects:
CODEBLOCK6
Error Handling
Always wrap API calls in try/except:
CODEBLOCK7
Template Variables & Personalization
Email bodies support variable substitution using {{variable}} syntax:
- -
{{firstName}}, {{lastName}}, INLINECODE38 - INLINECODE39 ,
{{title}}, INLINECODE41 - INLINECODE42 , INLINECODE43
- Custom fields: INLINECODE44
Spintax is also supported: {Hi|Hey|Hello} {{firstName}}
Common Workflows
1. Full Campaign Setup
When the user wants to set up a complete campaign, follow these steps in order:
- 1. Create the campaign with INLINECODE46
- Add sequence steps with
campaigns.sequences.create() for each email in the chain - Add leads with INLINECODE48
- Assign email accounts with INLINECODE49
- Start the campaign with INLINECODE50
2. Check Campaign Performance
- 1. Get campaign analytics with INLINECODE51
- Show sent, delivered, bounced, replied, opened stats
- Show reply rate and bounce rate
- If daily_stats are available, summarize trends
3. Manage Inbox
- 1. List unread threads with INLINECODE52
- Categorize replies by updating with INLINECODE53
- Common categories: interested, notinterested, outofoffice, wrongperson, unsubscribe
4. Bulk Lead Import
For adding multiple leads, create them one by one (the API deduplicates by email):
leads_data = [
{"email": "a@example.com", "first_name": "Alice", "company": "Acme"},
{"email": "b@example.com", "first_name": "Bob", "company": "Beta"},
]
created = []
for data in leads_data:
lead = client.leads.create(LeadCreate(**data))
created.append(lead)
print(f"Created: {lead.id} - {lead.email}")
Important Notes
- - Base URL: INLINECODE54
- Rate limit: 100 requests per minute. The SDK auto-retries on 429.
- ID prefixes: Leads
cld_, Campaigns cmp_, Replies rpl_, Templates INLINECODE58 - Timezone: All datetimes in UTC ISO 8601 format.
- Sending days: Array of integers, 1=Monday through 7=Sunday.
- Sending hours: 0-23 range, in the campaign's timezone.
- Campaign status flow: draft → active → paused → active → completed
- Soft deletes: Leads are soft-deleted and can reappear on re-import.
- Always confirm with the user before destructive operations (delete, start campaign).
- When listing data, default to showing a formatted summary, not raw JSON.
- When creating resources, confirm the details with the user before executing.
FoxReach API 管理技能
您正在通过其 Python SDK 和 CLI 管理 FoxReach 冷邮件外展平台。本技能涵盖线索、活动、序列、模板、邮箱账户、收件箱和分析的所有 API 操作。
设置与认证
Python SDK 位于 integrations/sdk-python/,CLI 位于 integrations/cli/。两者均使用以 otr_ 为前缀的 API 密钥进行认证。
检查 SDK 是否可用:
bash
python -c from foxreach import FoxReach; print(SDK ready)
如果未安装,请安装:
bash
cd integrations/sdk-python && pip install -e .
认证 — 在调用前始终从用户或环境获取 API 密钥。切勿硬编码密钥。使用环境变量注入:
bash
FOXREACHAPIKEY=otr_... python script.py
或使用 CLI 配置:
bash
cd integrations/cli && PYTHONPATH=. python -m foxreachcli.main config set-key --key otr...
如何执行操作
使用 SDK 编写内联 Python 脚本。始终遵循以下模式:
python
import json
from foxreach import FoxReach
client = FoxReach(apikey=otrUSERKEYHERE)
... 执行操作 ...
client.close()
对于快速操作,使用单行命令:
bash
python -c
from foxreach import FoxReach
client = FoxReach(apikey=otr...)
result = client.leads.list(page_size=10)
for lead in result:
print(f{lead.id} {lead.email} {lead.status})
print(fTotal: {result.meta.total})
client.close()
资源参考
有关完整的 API 详情,请参阅 api-reference.md。
有关每个操作的使用示例,请参阅 examples.md。
快速参考 — 可用操作
线索
| 操作 | 方法 | 说明 |
|---|
| 列表 | client.leads.list(page=1, pagesize=50, search=..., status=..., tags=...) | 分页,可筛选 |
| 获取 |
client.leads.get(leadid) | 返回单个线索 |
| 创建 | client.leads.create(LeadCreate(email=..., first_name=..., ...)) | 按邮箱去重 |
| 更新 | client.leads.update(lead_id, LeadUpdate(company=..., ...)) | 部分更新 |
| 删除 | client.leads.delete(lead_id) | 软删除 |
活动
| 操作 | 方法 | 说明 |
|---|
| 列表 | client.campaigns.list(status=...) | 按草稿/进行中/已暂停/已完成筛选 |
| 获取 |
client.campaigns.get(campaign_id) | 包含统计数据 |
| 创建 | client.campaigns.create(CampaignCreate(name=..., ...)) | 创建为草稿 |
| 更新 | client.campaigns.update(campaign_id, CampaignUpdate(...)) | 进行中状态不可编辑 |
| 删除 | client.campaigns.delete(campaign_id) | 必须为草稿状态 |
| 启动 | client.campaigns.start(campaign_id) | 转换为进行中状态 |
| 暂停 | client.campaigns.pause(campaign_id) | 暂停发送 |
| 添加线索 | client.campaigns.add
leads(campaignid, [lead_ids]) | 批量添加 |
| 添加账户 | client.campaigns.add
accounts(campaignid, [account_ids]) | 分配发件人 |
序列(嵌套在活动下)
| 操作 | 方法 | 说明 |
|---|
| 列表 | client.campaigns.sequences.list(campaignid) | 所有步骤 |
| 创建 |
client.campaigns.sequences.create(campaignid, SequenceCreate(body=..., ...)) | 添加步骤 |
| 更新 | client.campaigns.sequences.update(campaign
id, seqid, SequenceUpdate(...)) | 编辑步骤 |
| 删除 | client.campaigns.sequences.delete(campaign
id, seqid) | 移除步骤 |
模板
| 操作 | 方法 | 说明 |
|---|
| 列表 | client.templates.list() | 分页 |
| 获取 |
client.templates.get(template_id) | 单个模板 |
| 创建 | client.templates.create(TemplateCreate(name=..., body=...)) | 新建模板 |
| 更新 | client.templates.update(template_id, TemplateUpdate(...)) | 部分更新 |
| 删除 | client.templates.delete(template_id) | 移除 |
邮箱账户
| 操作 | 方法 | 说明 |
|---|
| 列表 | client.emailaccounts.list() | 分页 |
| 获取 |
client.emailaccounts.get(account_id) | 包含健康指标 |
| 删除 | client.email
accounts.delete(accountid) | 移除 |
收件箱
| 操作 | 方法 | 说明 |
|---|
| 列表线程 | client.inbox.listthreads(category=..., isread=..., ...) | 可筛选 |
| 获取 |
client.inbox.get(reply_id) | 完整线程 |
| 更新 | client.inbox.update(reply
id, ThreadUpdate(isread=..., ...)) | 标记已读/星标 |
分析
| 操作 | 方法 | 说明 |
|---|
| 概览 | client.analytics.overview() | 仪表盘关键指标 |
| 活动 |
client.analytics.campaign(campaign_id) | 指标 + 每日统计 |
分页
列表端点返回 PaginatedResponse 对象:
python
result = client.leads.list(page=1, page_size=50, search=acme)
访问数据
for lead in result:
print(lead.email)
检查分页信息
print(f第 {result.meta.page}/{result.meta.total_pages} 页,共 {result.meta.total} 条)
获取下一页
if result.has
nextpage():
next
result = result.nextpage()
自动遍历所有结果
for lead in client.leads.list().auto
pagingiter():
print(lead.email)
错误处理
始终将 API 调用包裹在 try/except 中:
python
from foxreach import FoxReach, NotFoundError, RateLimitError, AuthenticationError, FoxReachError
try:
lead = client.leads.get(cld_nonexistent)
except NotFoundError:
print(未找到线索)
except AuthenticationError:
print(无效的 API 密钥)
except RateLimitError as e:
print(f请求频率限制。{e.retry_after}秒后重试)
except FoxReachError as e:
print(fAPI 错误:{e})
模板变量与个性化
邮件正文支持使用 {{variable}} 语法进行变量替换:
- - {{firstName}}、{{lastName}}、{{email}}
- {{company}}、{{title}}、{{phone}}
- {{website}}、{{linkedinUrl}}
- 自定义字段:{{customFieldName}}
还支持 Spintax 语法:{Hi|Hey|Hello} {{firstName}}
常见工作流程
1. 完整活动设置
当用户想要设置完整活动时,按以下顺序执行:
- 1. 使用 campaigns.create() 创建活动
- 使用 campaigns.sequences.create() 为邮件链中的每封邮件添加序列步骤
- 使用 campaigns.addleads() 添加线索
- 使用 campaigns.addaccounts() 分配邮箱账户
- 使用 campaigns.start() 启动活动
2. 检查活动表现
- 1. 使用 analytics.campaign(id) 获取活动分析
- 显示已发送、已送达、已退回、已回复、已打开统计数据
- 显示回复率和退回率
- 如果每日统计数据可用,总结趋势
3. 管理收件箱
- 1. 使用 inbox.listthreads(isread=False) 列出未读线程
- 使用 inbox.update(id, ThreadUpdate(category=interested)) 分类回复
- 常见分类:感兴趣、不感兴趣、不在办公室、找错人、取消订阅
4. 批量导入线索
如需添加多个线索,逐一创建(API 按邮箱去重):
python
leads_data = [
{email: a@example