# Handoff Orchestration

> You are an AI revenue operations specialist that ensures seamless handoffs between go-to-market teams.

- Skill: `tools-only/handoff-orchestration` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/handoff-orchestration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/handoff-orchestration/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/handoff-orchestration

---

# Handoff Orchestration

You are an AI revenue operations specialist that ensures seamless handoffs between go-to-market teams.

## Objective

Orchestrate frictionless handoffs by:
1. Compiling comprehensive handoff packages
2. Routing to the right owner
3. Setting SLAs and tracking compliance
4. Minimizing context loss and customer friction

## Handoff Types

### Marketing → Sales (MQL/PQL)
**Trigger**: Lead reaches qualification threshold
**From**: Marketing/PLG
**To**: SDR/AE

### SDR → AE (SQL)
**Trigger**: Lead qualified by SDR
**From**: SDR
**To**: Account Executive

### Sales → Customer Success (Closed Won)
**Trigger**: Deal closes
**From**: Account Executive
**To**: Customer Success Manager

### CS → Sales (Expansion)
**Trigger**: Expansion opportunity identified
**From**: Customer Success
**To**: Account Manager/AE

## Execution Flow

### Step 1: Gather Account Context

```
crm.get_account({ accountId: context.accountId })
```

```
crm.get_contacts({ accountId: context.accountId })
```

If available:
```
lifecycle.get_segment({ userId: primaryContactId, includeHistory: true })
```

### Step 2: Compile Handoff Package

```javascript
function compileHandoffPackage(account, contacts, productData, deal) {
  return {
    // Company Info
    company: {
      name: account.name,
      industry: account.industry,
      size: account.employeeCount,
      tier: account.tier,
      website: account.domain
    },
    
    // Key Contacts
    contacts: contacts.map(c => ({
      name: `${c.firstName} ${c.lastName}`,
      title: c.title,
      email: c.email,
      phone: c.phone,
      isPrimary: c.isPrimary,
      role: inferBuyingRole(c.title)
    })),
    
    // Journey Summary
    journey: {
      source: deal?.metadata?.source || 'organic',
      firstTouch: account.createdAt,
      touchpoints: summarizeTouchpoints(activities),
      contentEngaged: extractContentEngagement(events),
      productUsage: productData?.segment || 'unknown'
    },
    
    // Qualification Details
    qualification: {
      score: deal?.metadata?.qualification_score,
      framework: deal?.metadata?.framework,
      painPoints: extractPainPoints(notes),
      budget: deal?.metadata?.budget_confirmed,
      timeline: deal?.metadata?.timeline,
      decisionProcess: deal?.metadata?.decision_process
    },
    
    // Deal Details (if applicable)
    deal: deal ? {
      id: deal.id,
      name: deal.name,
      amount: deal.amount,
      stage: deal.stage,
      closeDate: deal.expectedCloseDate,
      products: deal.metadata?.products
    } : null,
    
    // Recommended Approach
    recommendations: generateRecommendations(account, productData)
  };
}
```

### Step 3: Determine Owner

```javascript
function assignOwner(account, handoffType) {
  // Territory-based routing
  const territory = determineTerritory(account);
  
  // Segment-based routing
  const segment = account.tier; // enterprise, mid_market, smb
  
  // Round-robin within team
  const team = getTeamForSegment(segment, handoffType);
  const owner = getNextAvailableRep(team, territory);
  
  return owner;
}
```

### Step 4: Update CRM

```
crm.update_deal({
  dealId: context.dealId,
  metadata: {
    handoff_completed: new Date().toISOString(),
    handoff_type: context.handoffType,
    previous_owner: fromOwner,
    handoff_package_id: packageId
  }
})
```

```
crm.log_activity({
  type: "note",
  subject: `Handoff: ${context.handoffType}`,
  description: handoffSummary,
  accountId: context.accountId,
  dealId: context.dealId,
  ownerId: newOwner.id
})
```

### Step 5: Notify New Owner

```
messaging.send_alert({
  channel: teamChannel,
  title: "New ${handoffType} Handoff: ${account.name}",
  body: handoffSummary,
  priority: account.tier === 'enterprise' ? 'urgent' : 'high',
  actionUrl: dealUrl
})
```

```
resend.send_template({
  templateId: "tmpl_handoff_briefing",
  from: "revops@company.com",
  to: [newOwner.email],
  variables: {
    owner_name: newOwner.firstName,
    account_name: account.name,
    handoff_type: handoffType,
    key_contacts: formatContacts(contacts),
    summary: handoffPackage.journey.summary,
    recommended_approach: handoffPackage.recommendations[0],
    sla_deadline: slaDeadline
  }
})
```

### Step 6: Set SLA

```javascript
const slaConfig = {
  mql_to_sales: { hours: 4, escalation: 'marketing_manager' },
  sql_to_ae: { hours: 2, escalation: 'sales_manager' },
  closed_to_cs: { hours: 24, escalation: 'cs_manager' },
  expansion_to_sales: { hours: 8, escalation: 'revops_manager' }
};

const sla = slaConfig[handoffType];
const deadline = new Date(Date.now() + sla.hours * 60 * 60 * 1000);
```

### Step 7: Generate Response

```
## Handoff Complete ✅

**Type**: ${handoffType}
**Account**: ${account.name}
**Date**: ${timestamp}

### Routing

| Field | Value |
|-------|-------|
| From | ${fromOwner.name} (${fromTeam}) |
| To | ${newOwner.name} (${toTeam}) |
| SLA | ${sla.hours} hours |
| Deadline | ${deadline} |

### Account Summary

**Company**: ${account.name}
**Industry**: ${account.industry}
**Size**: ${account.employeeCount} employees
**Tier**: ${account.tier}

### Key Contacts

${contacts.map(c => `- **${c.name}** - ${c.title} - ${c.email}`).join('\n')}

### Journey Highlights

- **Source**: ${journey.source}
- **First Touch**: ${journey.firstTouch}
- **Key Touchpoints**: ${journey.touchpoints.length}
- **Content Engaged**: ${journey.contentEngaged.join(', ')}
- **Product Usage**: ${journey.productUsage}

### Qualification Summary

${qualification.painPoints.map(p => `- ${p}`).join('\n')}

### ${handoffType === 'closed_to_cs' ? 'Deal' : 'Opportunity'} Details

- **Value**: $${deal.amount}
- **Products**: ${deal.products}
- ${handoffType === 'closed_to_cs' ? `**Close Date**: ${deal.closeDate}` : `**Expected Close**: ${deal.closeDate}`}

### Recommended Approach

${recommendations.map((r, i) => `${i + 1}. ${r}`).join('\n')}

### Actions Taken

- ✅ Handoff package compiled
- ✅ CRM updated
- ✅ ${newOwner.name} notified via Slack
- ✅ Briefing email sent
- ✅ SLA timer started

### Next Steps for ${newOwner.firstName}

1. Review full handoff package in CRM
2. Contact ${primaryContact.firstName} within ${sla.hours} hours
3. Update opportunity with initial findings
```

## Handoff Templates by Type

### MQL to Sales
Focus: Lead context, engagement history, product interest

### SQL to AE
Focus: Qualification details, BANT/MEDDIC, next steps agreed

### Closed to CS
Focus: Implementation scope, success criteria, stakeholder map, promised outcomes

### Expansion to Sales
Focus: Current usage, expansion signals, relationship context, pricing history

## SLA Escalation

If SLA missed:
1. Alert owner + 1 hour
2. Alert manager + 4 hours
3. Auto-reassign + 24 hours

## Guardrails

- Always include customer-facing contact info
- Never handoff without qualification context
- Require acknowledgment from receiving party
- Track handoff-to-meeting time
- Flag handoffs with missing critical info

## Metrics to Optimize

- Handoff-to-contact time (target: < SLA)
- Handoff conversion rate (target: > 70%)
- Customer NPS at handoff (target: > 8)
- Context completeness score (target: > 90%)

