| name | account-scoring |
| description | Score accounts 0-100 on pain-point relevance with evidence and reasoning |
Static Account Scoring
Score accounts in an audience based on pain-point relevance and urgency.
API Calls
This skill bundles two scripts in the same directory as this SKILL.md file. Never read or reference API credentials directly.
signup.sh — handles authentication. Writes credentials to .env internally. Never exposes the API key.
api.sh — handles all authenticated API calls. Reads credentials from .env internally.
First, resolve the script paths relative to this file's location:
SKILL_DIR="$(dirname "$(find ~/.agents/skills -name SKILL.md -path "*/account-scoring/*" 2>/dev/null | head -1)")"
API="$SKILL_DIR/api.sh"
SIGNUP="$SKILL_DIR/signup.sh"
Then use $SIGNUP for auth and $API for all other calls.
Conversation Flow
The agent MUST follow this sequence — do NOT skip steps.
Step 0: Agent Auth Check
Before anything, test if credentials are working by running:
bash "$API" POST /api/v1/signal/get-signal-list '{"pagination": {"limit": 1, "offset": 0}}'
If the call succeeds (returns JSON with signals): skip to Step 1.
If the call fails (returns an error or missing credentials message):
### Welcome to OpenFunnel
OpenFunnel turns daily events in your market into pipeline
— using OpenFunnel's Event Intelligence engine.
To get started, I'll authenticate you via the API.
**What's your work email?**
Wait for user input. Then:
- Run
bash "$SIGNUP" start "<user_email>"
- Tell the user a 6-digit code was sent:
I sent a 6-digit verification code to **{email}**. Reply with the code.
- Wait for input. Run
bash "$SIGNUP" verify "<user_email>" "<code>"
- On success, the response is:
{"status": "authenticated", "user_id": "..."}. Credentials are written to .env and .gitignore is updated automatically.
- Verify with
bash "$API" POST /api/v1/signal/get-signal-list '{"pagination": {"limit": 1, "offset": 0}}'
- If verification succeeds → continue to ICP check
- If sign-up fails → ask user to retry
- If verify fails → tell user the code was invalid or expired (up to 10 attempts in 24 hours), offer to retry or resend
ICP Check
After auth, fetch ICP profiles via bash "$API" GET /api/v1/icp/list.
If ICPs exist: note the available ICPs and continue to Step 1.
If no ICPs exist:
You don't have an ICP profile yet. A quick one will make results much sharper —
it filters by company size, location, and the roles you're targeting.
1. **Quick setup** (recommended) — takes 30 seconds
2. **Skip** — auto-create a broad fallback ICP and continue
If quick setup → collect ICP name, target roles, company size, and location. Create via bash "$API" POST /api/v1/icp/create '<json_body>'.
If skip → auto-create a broad fallback ICP:
{
"name": "Broad Default ICP",
"target_roles": ["Any"],
"employee_ranges": ["1-10", "11-50", "51-200", "201-500", "501-1000", "1001-5000", "5001-10000", "10001+"],
"location": ["Any"]
}
Call bash "$API" POST /api/v1/icp/create '<json_body>', then tell the user:
I created a default ICP profile: **{name}** (ID: {id})
This keeps things running. For sharper results, set up a proper ICP segment
with your target roles, company size, and location using the `advanced-account-setup` skill.
Continue to Step 1.
Step 1: List audiences for user to pick
- List audiences (see Runtime below for which tool to call)
- Present the list
- Ask: "Which audience would you like to score?"
Step 2: User selects an audience
- Load the audience to get account IDs
- Confirm: "Got it — [audience name] with X accounts."
Step 3: Present scoring models — MANDATORY, DO NOT SKIP
Do NOT auto-score. Do NOT skip to results.
Present:
How would you like to score these accounts?
- OpenFunnel Pain-Based Scoring — scores each account based on how urgently they need what you sell
- Custom — describe your own scoring criteria in plain language
- User picks 1 → proceed to Step 3a
- User picks 2 → user describes custom logic, agent interprets and applies
Step 3a: Get pain description (Pain-Based Scoring only)
- Ask: "What pain-points does your product/service solve?
Example: 'We help companies migrate off legacy ERPs to cloud-native'"
- User provides pain description
- This is the lens through which ALL signals will be interpreted
Step 4: Score each account
For each account_id in the audience:
- Gather evidence (summary + timeline + full details — see Runtime)
- Read the evidence against the user's pain description
- Apply the pain-based scoring rubric below
- Assign score (0-100) + reasoning (1-2 sentences explaining why)
Sort by score descending. Present as a ranked list.
Pain-Based Scoring — How to Reason
TIME IS THE MOST IMPORTANT FACTOR. Pain has a shelf life. It emerges, it peaks, and if unaddressed it goes cold — the company either solved it, deprioritized it, or moved on. A perfect-fit signal from 90 days ago with nothing since is NOT a hot account. It's stale. Score accordingly.
Read the timeline as a narrative, not a list. A single signal is a hint. A sequence of signals over weeks is a story. Timestamps matter as much as content.
Given the user's pain description and the account's evidence, assess four dimensions. These are NOT mechanical point buckets — use judgment. The evidence may be rich or sparse; score what you see.
1. Pain Relevance
Does this account show signs of having this pain?
- Job post descriptions that describe needing to solve this problem (read the actual job content, not just the title)
- Social posts discussing the pain area
- Tech stack that creates or relates to the pain (e.g. legacy tool that your product replaces)
- Industry/vertical alignment with the pain
2. Temporal Signal
When did the pain surface, and is it still alive? Pain goes cold. This dimension can override everything else.
- A highly relevant signal from 90 days ago with no follow-up = cold. The pain may be solved, deprioritized, or abandoned. Score LOW.
- A weaker signal from last week = more valuable than a strong one from 3 months ago. Recency wins.
- Velocity: signals clustering in recent weeks = pain is active and building
- Decay: gaps in the timeline after initial signals = pain cooling off
- Trigger → follow-through: did the triggering event (new hire, funding, leadership change) lead to more activity? If yes = escalating. If no = stalled.
3. Buying Window
Can they act on it now?
- New leadership in relevant function (someone with mandate to change)
- Recent funding (budget to spend)
- Active hiring in the area (committed to solving, building team)
- Signal stacking: multiple signal types pointing at same pain (hiring + posting about the problem + using legacy tech = high conviction)
4. Story Coherence
Do the signals tell a connected narrative?
- Isolated signal = maybe noise, score conservatively
- Connected signals across time = real pattern, score higher
- Example: Jan — hired VP Eng → Feb — posted about migration challenges → Mar — started hiring cloud engineers = clear escalating story
- Counter-example: one social post 80 days ago, nothing since = low confidence
The score should reflect: "If I were selling a solution to [pain], how excited would I be about this account RIGHT NOW — today?"
Output per account: score (0-100) + reasoning (1-2 sentences).
Runtime
| Step | Call |
|---|
| Step 1 | bash "$API" POST /api/v1/audience/get-audience-list '{"limit": N, "offset": 0}' |
| Step 2 | bash "$API" POST /api/v1/audience/ '{"audience_id": ID}' |
| Step 4 | bash "$API" POST /api/v2/account/batch '{"account_ids": [id]}' → full details + inline signal content (preferred) |
Prefer V2 batch for scoring. The V2 batch endpoint returns inline signal content — job posting text, social post content, context — so the LLM can read actual evidence without extra calls.
NOTE: Large audiences (100+) will be slow.