Most "account research" still means a sales rep toggling between six browser tabs, copying LinkedIn bios into a Google Doc, and hoping they noticed the earnings call from last week. It is slow, inconsistent, and does not scale.
What if a 50-line Python script could do it every morning before you open your laptop?
In this tutorial, you will build a real-time account research agent that watches a list of target accounts, pulls intelligence from the Salesmotion API, and generates a structured research brief — optionally delivered to Slack. By the end, you will have a working script you can schedule with cron and forget about.
Key Takeaways
- The Salesmotion API gives you structured account intelligence (earnings, news, AI summaries) in a single call — 100 free credits/month, no credit card.
- You can build a working account research agent in roughly 50 lines of Python using
requestsand the Anthropic SDK. - Combining multiple endpoints (summary, earnings, news) into one brief gives reps the context they actually need before a call.
- The same pattern extends to scoring, outreach triggers, CRM enrichment, or any workflow where fresh account context matters.
See Salesmotion in action
Take a self-guided interactive tour — no signup required.
Prerequisites
Before you start, make sure you have:
- Python 3.10+ installed
- A free Salesmotion API key — sign up here (100 credits/month, no credit card required)
- An Anthropic API key for the LLM-powered brief generation (optional — you can skip Step 4 and use raw data instead)
- A Slack webhook URL (optional — for push notifications)
Install the two Python dependencies:
pip install requests anthropic
“The Business Development team gets 80 to 90 percent of what they need in 15 minutes. That is a complete shift in how our reps work.”
Andrew Giordano
VP of Global Commercial Operations, Analytic Partners
Step 1: Get Your Free API Key
Head to salesmotion.io/developer-signup and create a free account. You will get an API key immediately — no sales call, no credit card.
The free tier gives you 100 credits per month. Each API call costs 1 credit, so you can research roughly 30 accounts across 3 endpoints every day without spending a dollar. For heavier usage, paid plans start at $49/month.
Save your API key somewhere safe. You will reference it in every request.
Step 2: Make Your First API Call
Let us start with the most useful endpoint: the account summary. This returns an AI-generated brief with key insights, talking points, and firmographic data — all in structured JSON.
curl:
curl -s https://api.salesmotion.io/v1/accounts/acc_8xK2mP/summary \
-H "Authorization: Bearer YOUR_API_KEY" | python -m json.tool
Python:
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.salesmotion.io/v1"
def get_account_summary(account_id: str) -> dict:
response = requests.get(
f"{BASE_URL}/accounts/{account_id}/summary",
headers={"Authorization": f"Bearer {API_KEY}"},
)
response.raise_for_status()
return response.json()
summary = get_account_summary("acc_8xK2mP")
print(summary)
Response:
{
"account_id": "acc_8xK2mP",
"company": "Acme Corp",
"summary": {
"overview": "Acme Corp is a $2.4B enterprise software company undergoing significant digital transformation, with recent leadership changes signaling a pivot toward AI-native products.",
"key_insights": [
"Actively hiring for AI/ML roles (34 open positions)",
"New CTO from Google Cloud indicates cloud migration",
"Q4 earnings beat estimates; raised FY2026 guidance",
"Expanding into European markets (London HQ)"
],
"talking_points": [
"Their AI infrastructure buildout creates opportunities for developer tooling",
"European expansion means new compliance requirements",
"Revenue acceleration suggests budget availability for new vendors"
],
"industry": "Enterprise Software",
"employees": 8500,
"hq": "San Francisco, CA",
"last_updated": "2026-02-23T08:30:00Z"
}
}
One call. Structured JSON. No scraping, no parsing, no stale data.
Step 3: Pull Earnings and News for Deeper Context
The summary endpoint is great for a quick overview, but sales conversations often hinge on specifics — what the CEO said on the last earnings call, or a partnership announcement from last week. Two additional endpoints fill that gap.
Earnings calls
def get_earnings(account_id: str) -> dict:
response = requests.get(
f"{BASE_URL}/accounts/{account_id}/earnings",
headers={"Authorization": f"Bearer {API_KEY}"},
)
response.raise_for_status()
return response.json()
Response:
{
"account_id": "acc_8xK2mP",
"company": "Acme Corp",
"earnings": [
{
"quarter": "Q4 2025",
"date": "2025-12-15",
"revenue": "$2.4B",
"yoy_growth": "+12.3%",
"key_topics": [
"AI infrastructure expansion",
"European market entry",
"Margin improvement program"
],
"ceo_quote": "We're doubling down on AI-native products across every business unit.",
"sentiment": "bullish"
}
],
"next_earnings": "2026-03-12"
}
News and press releases
def get_news(account_id: str) -> dict:
response = requests.get(
f"{BASE_URL}/accounts/{account_id}/news",
headers={"Authorization": f"Bearer {API_KEY}"},
)
response.raise_for_status()
return response.json()
Response:
{
"account_id": "acc_8xK2mP",
"company": "Acme Corp",
"news": [
{
"title": "Acme Corp Announces Strategic Partnership with Snowflake",
"date": "2026-02-20",
"source": "Business Wire",
"summary": "Multi-year deal to migrate Acme's data infrastructure to Snowflake, starting with EMEA operations.",
"relevance": 0.91
},
{
"title": "Acme Corp Appoints Jane Rivera as Chief Technology Officer",
"date": "2026-02-18",
"source": "PR Newswire",
"summary": "Former Google Cloud VP joins as CTO, signaling a shift toward cloud-native architecture.",
"relevance": 0.94
}
]
}
Each call costs 1 credit. Three calls per account gives you a comprehensive picture for under a penny on the free tier.
Step 4: Generate a Research Brief with an LLM
Now the interesting part. You have structured data from three endpoints — summary, earnings, and news. Instead of dumping raw JSON into Slack, feed it to an LLM and get a concise, action-oriented brief.
import anthropic
import json
client = anthropic.Anthropic() # Uses ANTHROPIC_API_KEY env var
def generate_brief(summary: dict, earnings: dict, news: dict) -> str:
context = json.dumps(
{"summary": summary, "earnings": earnings, "news": news},
indent=2,
)
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{
"role": "user",
"content": f"""You are a sales research analyst. Given the following account
intelligence data, write a concise daily research brief (max 300 words).
Structure:
1. Company snapshot (one sentence)
2. Key developments (bullet points — what changed recently)
3. Potential talking points for a sales conversation
4. Risk flags (if any)
Account data:
{context}""",
}
],
)
return message.content[0].text
The prompt is deliberately structured: snapshot, developments, talking points, risks. This mirrors what a good AE actually needs before a call — not a wall of text, but a scannable brief they can read in 30 seconds.
Step 5: Monitor Multiple Accounts
A single account is useful for testing. In production, you want to run this across your entire target list every morning.
TARGET_ACCOUNTS = [
"acc_8xK2mP", # Acme Corp
"acc_3jR9nL", # Globex Industries
"acc_5wT1qX", # Initech
"acc_7mN4kD", # Umbrella Corp
]
def run_daily_research() -> list[dict]:
briefs = []
for account_id in TARGET_ACCOUNTS:
try:
summary = get_account_summary(account_id)
earnings = get_earnings(account_id)
news = get_news(account_id)
brief = generate_brief(summary, earnings, news)
briefs.append({
"account_id": account_id,
"company": summary.get("company", account_id),
"brief": brief,
})
print(f"✓ {summary.get('company', account_id)}")
except Exception as e:
print(f"✗ {account_id}: {e}")
return briefs
Four accounts, three endpoints each = 12 credits. You could monitor 33 accounts daily and stay within the free tier.
Step 6: Send to Slack (Optional)
The final piece: push the briefs to a Slack channel so your team sees them without logging in anywhere.
import requests as req
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
def send_to_slack(briefs: list[dict]) -> None:
for entry in briefs:
payload = {
"text": f"*📊 Daily Brief: {entry['company']}*\n\n{entry['brief']}",
}
resp = req.post(SLACK_WEBHOOK, json=payload)
if resp.status_code != 200:
print(f"Slack error for {entry['company']}: {resp.text}")
Create a Slack incoming webhook at api.slack.com/messaging/webhooks. Point it at your team's research or deal-room channel.
Full Script
Here is the complete agent, combining every step above into a single file:
#!/usr/bin/env python3
"""Daily account research agent — Salesmotion API + Claude."""
import json
import os
import requests
import anthropic
# --- Config ---
API_KEY = os.environ["SALESMOTION_API_KEY"]
BASE_URL = "https://api.salesmotion.io/v1"
SLACK_WEBHOOK = os.environ.get("SLACK_WEBHOOK_URL")
TARGET_ACCOUNTS = [
"acc_8xK2mP", # Acme Corp
"acc_3jR9nL", # Globex Industries
"acc_5wT1qX", # Initech
"acc_7mN4kD", # Umbrella Corp
]
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
client = anthropic.Anthropic()
# --- API helpers ---
def get_account_summary(account_id: str) -> dict:
r = requests.get(f"{BASE_URL}/accounts/{account_id}/summary", headers=HEADERS)
r.raise_for_status()
return r.json()
def get_earnings(account_id: str) -> dict:
r = requests.get(f"{BASE_URL}/accounts/{account_id}/earnings", headers=HEADERS)
r.raise_for_status()
return r.json()
def get_news(account_id: str) -> dict:
r = requests.get(f"{BASE_URL}/accounts/{account_id}/news", headers=HEADERS)
r.raise_for_status()
return r.json()
# --- LLM brief ---
def generate_brief(summary: dict, earnings: dict, news: dict) -> str:
context = json.dumps(
{"summary": summary, "earnings": earnings, "news": news}, indent=2
)
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"""You are a sales research analyst. Given the following account
intelligence data, write a concise daily brief (max 300 words).
Structure:
1. Company snapshot (one sentence)
2. Key developments (bullet points)
3. Talking points for a sales conversation
4. Risk flags (if any)
Account data:
{context}""",
}],
)
return message.content[0].text
# --- Slack ---
def send_to_slack(briefs: list[dict]) -> None:
if not SLACK_WEBHOOK:
return
for entry in briefs:
requests.post(SLACK_WEBHOOK, json={
"text": f"*Daily Brief: {entry['company']}*\n\n{entry['brief']}",
})
# --- Main ---
def main():
briefs = []
for account_id in TARGET_ACCOUNTS:
try:
summary = get_account_summary(account_id)
earnings = get_earnings(account_id)
news = get_news(account_id)
brief = generate_brief(summary, earnings, news)
briefs.append({
"account_id": account_id,
"company": summary.get("company", account_id),
"brief": brief,
})
print(f"Done: {summary.get('company', account_id)}")
except Exception as e:
print(f"Error {account_id}: {e}")
send_to_slack(briefs)
print(f"\nGenerated {len(briefs)} briefs.")
if __name__ == "__main__":
main()
Save it as research_agent.py, set your environment variables, and run:
export SALESMOTION_API_KEY="your_key_here"
export ANTHROPIC_API_KEY="your_key_here"
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..." # optional
python research_agent.py
To run it every morning at 7 AM, add a cron entry:
crontab -e
# Add this line:
0 7 * * * cd /path/to/agent && python research_agent.py
What to Build Next
This agent is a starting point. Here are a few ways to extend it:
- Add more endpoints. The Salesmotion API also covers job postings, SEC filings, clinical trials, and legal data. Adding the jobs endpoint, for example, lets you detect hiring surges that signal budget expansion.
- Build account scoring. Use the signals and firmographic data to compute a priority score. Surface the accounts that changed the most since yesterday.
- Trigger outreach automatically. When a high-priority signal fires (new CTO, earnings beat, funding round), use the brief as context for a personalized email draft.
- Connect to your CRM. Push the briefs and scores into Salesforce or HubSpot so reps see fresh context without leaving their workflow.
- Use the MCP server instead. If your team already uses Claude or another AI assistant, the Salesmotion MCP server gives you the same intelligence through natural conversation — no code required.
The pattern is always the same: pull structured data from the API, add your own logic, and push the output where your team already works. If you want to go deeper on the category, see our guide to AI-powered account research or the breakdown of building AI sales agents.
Get your free API key and start building.
Frequently Asked Questions
How many API credits does this agent use per run?
Three endpoints per account (summary, earnings, news) = 3 credits per account. If you monitor 10 accounts daily, that is 30 credits per day, or about 900 per month. The free tier covers 100 credits/month — enough for about 3 accounts per day. The Build plan at $49/month gives you 2,500 credits, which covers roughly 27 accounts daily.
Can I use a different LLM instead of Claude?
Yes. The LLM step is completely independent of the Salesmotion API. You can swap in OpenAI, Gemini, Mistral, or any model that accepts a text prompt. The Salesmotion API returns structured JSON, so any LLM can process it. The Anthropic SDK is used here because Claude handles structured data particularly well.
Do I need a paid Salesmotion plan to follow this tutorial?
No. The free tier gives you 100 credits per month with no credit card required. That is enough to follow every step in this tutorial and monitor a few accounts daily. Scale up to a paid plan when you need more volume.
What is the difference between the API and the Salesmotion platform?
The API gives you raw, structured intelligence via REST endpoints — ideal for developers building custom tools, agents, or data pipelines. The Salesmotion platform is the full product: dashboard, AI agents, CRM integrations, Slack alerts, and the MCP server for AI assistants. Platform users on Team and Enterprise plans get API access included.
