follow-up-sla.md13.5 KBView on GitHub # Follow-up SLA
How fast the team responds, how consistently it follows up, and how that maps to revenue. SLA targets: **first response < 1h**, **post-meeting follow-up < 24h**, **follow-up gap < 3 days**. Last 90 days, 100 deals per rep. All figures are demo data.
## The SLA standard
The rings fill toward each metric's SLA target — a full ring means the team is at (or past) budget. Compliance is the share of first responses that beat the 1-hour target.
```dashboard
{
"id": "sla_standard",
"dataSources": {
"headline": {
"mock": [
{ "response": 2520, "postMeeting": 61200, "followup": 181000, "compliance": 68 }
]
}
},
"layout": {
"type": "grid",
"columns": 4,
"gap": "lg",
"children": [
{
"type": "stat",
"source": "headline",
"field": "response",
"label": "Avg first response",
"format": "duration",
"style": "radial",
"max": 3600
},
{
"type": "stat",
"source": "headline",
"field": "postMeeting",
"label": "Avg post-meeting follow-up",
"format": "duration",
"style": "radial",
"max": 86400
},
{
"type": "stat",
"source": "headline",
"field": "followup",
"label": "Avg follow-up gap",
"format": "duration",
"style": "radial",
"max": 259200
},
{
"type": "stat",
"source": "headline",
"field": "compliance",
"label": "First responses within 1h",
"format": "percent",
"style": "radial",
"max": 100,
"highlight": true
}
]
},
"spec_version": "2.0"
}
```
## Why it matters
Speed is a consistent separator between won and lost deals. Win and reply rates slide the longer the first response takes.
```dashboard
{
"id": "sla_why",
"dataSources": {
"outcome": {
"mock": [
{ "outcome": "Won deals", "firstResponse": 2520, "followupGap": 129600, "replyRate": 71, "deals": 42 },
{ "outcome": "Lost deals", "firstResponse": 19440, "followupGap": 540000, "replyRate": 31, "deals": 58 },
{ "outcome": "All deals", "firstResponse": 6480, "followupGap": 226800, "replyRate": 49, "deals": 100 }
]
},
"decay": {
"mock": [
{ "bucket": "<1h", "winRate": 56, "replyRate": 66 },
{ "bucket": "1–4h", "winRate": 50, "replyRate": 60 },
{ "bucket": "4–24h", "winRate": 44, "replyRate": 54 },
{ "bucket": "1–3d", "winRate": 38, "replyRate": 48 },
{ "bucket": ">3d", "winRate": 32, "replyRate": 42 }
]
}
},
"layout": {
"type": "column",
"gap": "lg",
"children": [
{
"type": "table",
"source": "outcome",
"title": "Response & follow-up by outcome",
"columns": [
{ "key": "outcome", "label": "Outcome", "weight": 2 },
{ "key": "firstResponse", "label": "Avg first response", "format": "duration", "align": "right" },
{ "key": "followupGap", "label": "Avg follow-up gap", "format": "duration", "align": "right" },
{ "key": "replyRate", "label": "Reply rate", "format": "percent", "align": "right" },
{ "key": "deals", "label": "Deals", "format": "number", "align": "right" }
]
},
{
"type": "chart",
"source": "decay",
"chart": "line",
"title": "Win & reply rate by first-response speed",
"xAxis": "bucket",
"series": [
{ "key": "winRate", "label": "Win %" },
{ "key": "replyRate", "label": "Reply %" }
]
}
]
},
"spec_version": "2.0"
}
```
## Per-rep follow-up
Each card compares the rep's response, follow-up, and post-meeting times against the team average, beside their win rate, with a sample deal's activity timeline. A tight, regular cadence (Willem) keeps deals alive; widening gaps (Marcus) let them stall. Click a card to open the rep's playbook.
```dashboard
{
"id": "sla_per_rep",
"dataSources": {
"reps": {
"mock": [
{
"name": "Willem",
"initials": "WE",
"label": "Top rep",
"response": 1500,
"followup": 129600,
"postMeeting": 18000,
"winRate": 38,
"docPath": "user/files/users/willem",
"events": [
{ "kind": "inbound_email", "at": "2026-05-01T09:00:00Z", "title": "Inbound: pricing question" },
{ "kind": "outbound_email", "at": "2026-05-01T09:30:00Z", "title": "Reply + book demo" },
{ "kind": "meeting", "at": "2026-05-04T16:00:00Z", "title": "Demo" },
{ "kind": "outbound_email", "at": "2026-05-04T18:00:00Z", "title": "Recap + next steps" },
{ "kind": "outbound_email", "at": "2026-05-07T10:00:00Z", "title": "Check-in + mutual action plan" },
{ "kind": "meeting", "at": "2026-05-11T15:00:00Z", "title": "Exec readout" },
{ "kind": "outbound_email", "at": "2026-05-11T17:00:00Z", "title": "Order form" }
]
},
{
"name": "Lily",
"initials": "LP",
"label": "Account Exec",
"response": 2700,
"followup": 172800,
"postMeeting": 54000,
"winRate": 22,
"docPath": "user/files/users/lily",
"events": [
{ "kind": "inbound_email", "at": "2026-05-01T09:00:00Z", "title": "Inbound: demo request" },
{ "kind": "outbound_email", "at": "2026-05-01T14:00:00Z", "title": "Reply" },
{ "kind": "meeting", "at": "2026-05-05T16:00:00Z", "title": "Demo" },
{ "kind": "outbound_email", "at": "2026-05-06T12:00:00Z", "title": "Recap" },
{ "kind": "outbound_email", "at": "2026-05-10T10:00:00Z", "title": "Follow-up" },
{ "kind": "outbound_email", "at": "2026-05-14T09:00:00Z", "title": "Check-in" }
]
},
{
"name": "Sarah",
"initials": "SK",
"label": "Account Exec",
"response": 4200,
"followup": 226800,
"postMeeting": 75600,
"winRate": 21,
"docPath": "user/files/users/sarah",
"events": [
{ "kind": "inbound_email", "at": "2026-05-01T09:00:00Z", "title": "Inbound" },
{ "kind": "outbound_email", "at": "2026-05-02T11:00:00Z", "title": "Reply (next day)" },
{ "kind": "meeting", "at": "2026-05-06T16:00:00Z", "title": "Demo" },
{ "kind": "outbound_email", "at": "2026-05-08T10:00:00Z", "title": "Recap (2 days later)" },
{ "kind": "outbound_email", "at": "2026-05-13T10:00:00Z", "title": "Follow-up" }
]
},
{
"name": "Marcus",
"initials": "MR",
"label": "Account Exec",
"response": 9000,
"followup": 432000,
"postMeeting": 129600,
"winRate": 10,
"docPath": "user/files/users/marcus",
"events": [
{ "kind": "inbound_email", "at": "2026-05-01T09:00:00Z", "title": "Inbound" },
{ "kind": "outbound_email", "at": "2026-05-03T15:00:00Z", "title": "Reply (2 days later)" },
{ "kind": "meeting", "at": "2026-05-07T16:00:00Z", "title": "Demo" },
{ "kind": "outbound_email", "at": "2026-05-12T10:00:00Z", "title": "Recap (5 days later)" },
{ "kind": "outbound_email", "at": "2026-05-15T10:00:00Z", "title": "Still there?" }
]
}
]
}
},
"layout": {
"type": "repeater",
"source": "reps",
"as": "rep",
"layout": "grid",
"columns": 1,
"gap": "lg",
"template": {
"type": "entityCard",
"linkField": "docPath",
"children": [
{
"type": "row",
"gap": "md",
"align": "center",
"children": [
{ "type": "profile", "name": "{{rep.name}}", "initials": "{{rep.initials}}", "label": "{{rep.label}}" },
{ "type": "stat", "field": "winRate", "label": "Win rate", "format": "percent" }
]
},
{
"type": "comparison",
"format": "duration",
"rowLabel": "This rep",
"teamLabel": "Team avg",
"fields": [
{ "key": "response", "label": "First response" },
{ "key": "followup", "label": "Follow-up gap" },
{ "key": "postMeeting", "label": "Post-meeting follow-up" }
]
},
{
"type": "timeline",
"rowField": "events",
"title": "Sample deal activity",
"rangeStart": "2026-05-01T00:00:00Z",
"rangeEnd": "2026-05-16T00:00:00Z"
}
]
}
},
"spec_version": "2.0"
}
```
## Breaking the no-reply streak
The emails that revive a dead thread — short, specific, and easy to answer yes or no.
```dashboard
{
"id": "sla_breakers",
"dataSources": {
"breakers": {
"mock": [
{
"name": "The permission-to-close",
"subject": "Should I close your file?",
"body": "Haven't heard back, which usually means one of three things: it's not a priority right now, the timing is off, or I dropped the ball. Totally fine either way — just tell me which and I'll act accordingly.",
"replyRate": 61,
"context": "After 2 unanswered follow-ups"
},
{
"name": "The trigger event",
"subject": "Saw the Series B — congrats",
"body": "Congrats on the raise. New headcount usually means more pipeline than the team can follow up on — which is exactly the gap we close. Worth 15 minutes now that you're scaling the team?",
"replyRate": 58,
"context": "Triggered by funding news"
},
{
"name": "The case-study drop",
"subject": "How Ramp cut follow-up time 60%",
"body": "You mentioned reps forgetting to follow up. Ramp had the same problem — attached is the one-pager on how they fixed it in 3 weeks. Happy to walk through it live if useful.",
"replyRate": 52,
"context": "Mapped to a stated pain"
}
]
}
},
"layout": {
"type": "repeater",
"source": "breakers",
"as": "breaker",
"layout": "list",
"gap": "md",
"template": {
"type": "entityCard",
"children": [
{ "type": "text", "markdown": "**{{breaker.name}}** · {{breaker.context}} · replies {{breaker.replyRate}}%" },
{ "type": "text", "markdown": "**Subject:** {{breaker.subject}}" },
{ "type": "text", "markdown": "{{breaker.body}}", "className": "text-muted-foreground italic" }
]
}
},
"spec_version": "2.0"
}
```
## Where the time goes
Most first responses land inside the SLA window — the long tail is where deals quietly die. Post-meeting speed compounds the effect.
```dashboard
{
"id": "sla_distribution",
"dataSources": {
"dist": {
"mock": [
{ "bucket": "<1h", "count": 38 },
{ "bucket": "1–4h", "count": 27 },
{ "bucket": "4–24h", "count": 18 },
{ "bucket": "1–3d", "count": 11 },
{ "bucket": ">3d", "count": 6 }
]
},
"pmSplit": {
"mock": [
{ "window": "Same day", "win": 52 },
{ "window": "Next day", "win": 34 },
{ "window": ">2 days", "win": 15 }
]
}
},
"layout": {
"type": "grid",
"columns": 2,
"gap": "lg",
"children": [
{
"type": "chart",
"source": "dist",
"chart": "bar",
"title": "First-response time distribution",
"xAxis": "bucket",
"series": [{ "key": "count", "label": "Deals" }]
},
{
"type": "chart",
"source": "pmSplit",
"chart": "bar",
"title": "Win rate by post-meeting follow-up window",
"xAxis": "window",
"series": [{ "key": "win", "label": "Win %" }]
}
]
},
"spec_version": "2.0"
}
```
## Breaching SLA right now
Open deals whose last inbound has gone unanswered past the 1-hour target. Work these first.
```dashboard
{
"id": "sla_breaching",
"dataSources": {
"breaching": {
"mock": [
{ "deal": "Acme Corp", "owner": "Marcus", "waiting": 320000, "path": "user/files/deals/acme-corp" },
{ "deal": "Globex", "owner": "Sarah", "waiting": 280000, "path": "user/files/deals/globex" },
{ "deal": "Initech", "owner": "Lily", "waiting": 210000, "path": "user/files/deals/initech" }
]
},
"cadence": {
"mock": [
{ "outcome": "Won deals", "touches": 6, "avgGap": 129600 },
{ "outcome": "Lost deals", "touches": 3, "avgGap": 540000 }
]
}
},
"layout": {
"type": "column",
"gap": "lg",
"children": [
{
"type": "table",
"source": "breaching",
"title": "Unanswered inbound — breaching SLA",
"columns": [
{ "key": "deal", "label": "Deal", "weight": 2 },
{ "key": "owner", "label": "Owner", "type": "rep", "weight": 1 },
{ "key": "waiting", "label": "Waiting", "format": "duration", "align": "right" },
{ "key": "path", "label": "Open", "type": "docLink", "linkLabel": "Open →", "weight": 1 }
]
},
{
"type": "table",
"source": "cadence",
"title": "Touches to reply — won vs lost",
"columns": [
{ "key": "outcome", "label": "Outcome", "weight": 2 },
{ "key": "touches", "label": "Avg follow-ups before reply", "format": "number", "align": "right" },
{ "key": "avgGap", "label": "Avg gap between touches", "format": "duration", "align": "right" }
]
}
]
},
"spec_version": "2.0"
}
```