A TypeScript wrapper for the Sift API that provides intuitive, natural language methods perfect for chatbot integration.
Transform your Sift data into conversational experiences with our intelligent wrapper that adds advanced skills analytics, smart canonicalization, and natural language processing to the Sift API.
- Intelligent Skills Engine: Advanced canonicalization handles 50+ skill aliases automatically
- 53 Comprehensive Methods: From simple lookups to complex org analytics
- Production-Ready: Built with caching, retry logic, and error resilience
- Chatbot-Optimized: Method names match natural language queries perfectly
- Zero Dependencies: Lightweight and compatible across all platforms
- Chatbot Development: Natural language methods for conversational interfaces
- HR Analytics: Skills distribution, team insights, and organizational intelligence
- Talent Management: Expert discovery, skill gap analysis, and team formation
- Internal Tools: Employee directories, org charts, and skills databases
- ✨ Why Sift Helper?
- Features
- Quick Start
- Chatbot Query Patterns
- Core Methods
- Environment Setup
- Running Examples
- Testing
- Performance & Technical Specifications
- Architecture
- Skills Engine: Intelligent Talent Discovery
- Chatbot Integration Tips
- Data Enrichment
- Advanced Usage
- Error Handling
- Contributing
- License
- Chatbot-Ready: Method names that perfectly match natural language queries
- Intelligent Skills Engine: Advanced skill canonicalization, scoring, and fuzzy matching
- Rich Data Enrichment: Automatic addition of org levels, manager chains, and photo URLs
- Comprehensive Analytics: Team insights, department summaries, and organizational intelligence
- Advanced Search: Boolean filtering, role-based discovery, and location-aware queries
- Type Safe: Full TypeScript support with comprehensive interfaces for all data structures
- Production Ready: Built on a robust foundation with automatic retry logic, caching, and error handling
- Dual Architecture: Both high-level convenience methods and low-level API access
- Smart Caching: Automatic field schema caching with configurable TTL
- Media Integration: Seamless photo URL generation with size and type controls
- Skills Analytics: Organization-wide skill distribution, expertise mapping, and recommendations
- Org Intelligence: Multi-level reporting chains, span of control metrics, and team depth analysis
- Flexible Filtering: Complex boolean logic with AND/OR/NOT operations
- Pagination Support: Efficient handling of large result sets with cursor-based navigation
- Cross-Platform: Works in Node.js, browsers, and serverless environments
npm install sift-helperimport { SiftClient, ChatbotSiftClient } from 'sift-helper';
const siftClient = new SiftClient({
dataToken: process.env.SIFT_DATA_TOKEN!,
mediaToken: process.env.SIFT_MEDIA_TOKEN
});
const chatbot = new ChatbotSiftClient(siftClient);
// Natural language queries
const manager = await chatbot.getPersonsManager('john@company.com');
const teamSize = await chatbot.howBigIsTeam('sarah@company.com');
const engineers = await chatbot.findPeopleByRole('software engineer');import { SiftClient, ChatbotSiftClient, SkillsClient } from 'sift-helper';
// Initialize with skills support
const siftClient = new SiftClient({ dataToken: process.env.SIFT_DATA_TOKEN! });
const chatbot = new ChatbotSiftClient(siftClient);
// Skills-based queries (automatic canonicalization handles aliases)
const reactDevs = await chatbot.findPeopleWithSkills(['React', 'TypeScript'], {
requireAll: true,
minLevel: 3,
department: 'Engineering'
});
// Natural language skills queries
const response = await chatbot.whoKnowsSkill('javascript', 'Engineering');
// Returns: "Found 15 people with JavaScript skills in Engineering: Sarah (Level 5), John (Level 4)..."
// Organization-wide skills analytics
const skillsReport = await chatbot.getSkillsAnalytics();
console.log(`Top skills: ${skillsReport.topSkills.map(s => s.skill).join(', ')}`);| Natural Language Query | Method Call |
|---|---|
| "Who is X's manager?" | whoIsManager(email) |
| "Who reports to X?" | whoReportsTo(email) |
| "How big is X's team?" | howBigIsTeam(email) |
| "Find all product managers" | findPeopleByRole('product manager') |
| "Who works in Engineering?" | whoWorksInDepartment('Engineering') |
| "Show me X's org chart" | getCompleteOrgTree(email) |
| Natural Language Query | Method Call |
|---|---|
| "Who knows React?" | whoKnowsSkill('React') |
| "Who are the Python experts?" | whoAreTheExperts('Python') |
| "What skills does Jane have?" | whatSkillsDoesPersonHave(email) |
| "Find React and Node.js devs" | findPeopleWithSkills(['React', 'Node.js'], {requireAll: true}) |
| "Who has similar skills to Bob?" | findPeopleWithSimilarSkills(email) |
// Find someone by email with enriched data (includes level, department, photo)
const person = await chatbot.findPersonByEmail('jane@company.com', true);
console.log(person.level, person.departmentName, person.photoUrl);
// Get their direct manager
const manager = await chatbot.getPersonsManager('jane@company.com');
// Get full reporting chain (all managers up to CEO)
const chain = await chatbot.getReportingChain('jane@company.com', true, true);
// Get direct reports
const directReports = await chatbot.getDirectReports('manager@company.com');// Get comprehensive team insights
const insights = await chatbot.getTeamInsights('manager@company.com');
console.log({
totalTeamSize: insights.totalTeamSize,
directReports: insights.directReports.length,
teamDepth: insights.teamDepth,
avgSpanOfControl: insights.avgSpanOfControl,
largestSubteam: insights.largestSubteam
});
// Get complete organizational tree with depth control
const orgTree = await chatbot.getCompleteOrgTree('ceo@company.com', 3);
console.log(`Total team: ${orgTree.totalSize} people`);
// Find managers in a specific department
const engManagers = await chatbot.findManagersInDepartment('Engineering');
// Find people in a specific office location
const sfPeople = await chatbot.findPeopleInOffice('San Francisco');// Find people by job title/role with advanced filters
const seniorDevs = await chatbot.findPeopleByRole('software engineer', {
department: 'Engineering',
office: 'Seattle',
minReports: 1, // Managers only
includePhotos: true,
limit: 20
});
// Natural language search
const results = await chatbot.searchPeopleByQuery('senior frontend developer');
// Available fields for custom searches
const fields = await chatbot.getAvailableFields();
const filterableFields = fields.filter(f => f.filterable);// Find people with specific skills (any of these skills)
const reactPeople = await chatbot.findPeopleWithSkills(['React', 'Vue', 'Angular'], {
requireAll: false, // OR logic
minLevel: 3, // Intermediate or better
department: 'Engineering',
limit: 10
});
// Find people with ALL specified skills
const fullstackDevs = await chatbot.findPeopleWithSkills(['React', 'Node.js'], {
requireAll: true, // AND logic
limit: 5
});
// Get skill suggestions for autocomplete
const suggestions = await chatbot.getSkillSuggestions('java', 10);
// Find people with similar skills to someone
const similarPeople = await chatbot.findPeopleWithSimilarSkills('jane@company.com', 5);
// Organization-wide skills analytics
const skillsAnalytics = await chatbot.getSkillsAnalytics('Engineering');
console.log(`Top skills: ${skillsAnalytics.topSkills.slice(0, 3).map(s => s.skill).join(', ')}`);// Natural language responses (perfect for chatbots)
const managerResponse = await chatbot.whoIsManager('jane@company.com');
// Returns: "Jane's manager is Sarah Johnson (VP Engineering)"
const teamResponse = await chatbot.whoReportsTo('sarah@company.com');
// Returns: "5 people report to Sarah: John Smith, Mary Chen, ..."
const teamSize = await chatbot.howBigIsTeam('sarah@company.com');
// Returns: "Sarah's team has 23 people total, with 5 direct reports and 3 levels of management."
const deptInfo = await chatbot.whoWorksInDepartment('Engineering');
// Returns: "The Engineering department has 45 people, including 8 managers."
// Skills queries
const skillResponse = await chatbot.whoKnowsSkill('React', 'Engineering');
// Returns: "Found 12 people with React skills in Engineering: Sarah (Level 5), John (Level 4), ..."
const expertResponse = await chatbot.whoAreTheExperts('Python');
// Returns: "Found 3 Python experts: Alice (Level 5), Bob (Level 5)"
const skillsResponse = await chatbot.whatSkillsDoesPersonHave('jane@company.com');
// Returns: "Jane's skills: React (Level 5) ⭐, TypeScript (Level 4), Python (Level 3)"// Get detailed department statistics
const deptSummary = await chatbot.getDepartmentSummary('Engineering');
console.log({
headCount: deptSummary.headCount,
managerCount: deptSummary.managerCount,
avgTeamSize: deptSummary.avgTeamSize,
maxReportingLevels: deptSummary.maxReportingLevels,
topManager: deptSummary.topManager
});
// List all departments in the organization
const allDepartments = await chatbot.getAllDepartments();
console.log(`Organization has ${allDepartments.length} departments`);// Direct access to core Sift API methods
import { SiftClient } from 'sift-helper';
const client = new SiftClient({
dataToken: process.env.SIFT_DATA_TOKEN!,
mediaToken: process.env.SIFT_MEDIA_TOKEN
});
// Basic person lookup
const person = await client.getPerson('jane@company.com');
// Advanced search with boolean filters
const searchResults = await client.searchPeoplePost({
q: 'developer',
filter: {
and: [
{ field: 'department', comparison: 'eq', value: 'Engineering' },
{ field: 'directReportCount', comparison: 'gte', value: 1 }
]
},
pageSize: 50,
sortBy: 'displayName'
});
// Get organizational subtree (BFS traversal)
const subtree = await client.getOrgSubtree('ceo@company.com', {
includeManager: true,
maxDepth: 5,
maxNodes: 1000
});
// Get reporting chain
const orgChain = await client.getOrgChain('jane@company.com');
// Get available fields metadata
const fields = await client.getFields();
// Generate media URLs
const photoUrl = client.makeMediaUrl('jane@company.com', 'profile-photo', {
preferredType: 'official',
height: 256,
tokenInQuery: true
});Create a .env file:
SIFT_DATA_TOKEN=your_data_token_here
SIFT_MEDIA_TOKEN=your_media_token_here # optional, for photos
SIFT_TEST_PERSON=test@yourcompany.com # for testing# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Edit .env with your SIFT_DATA_TOKEN and SIFT_MEDIA_TOKEN# Basic data exploration and field discovery
npm run dump
# Chatbot integration examples
npx tsx examples/chatbot_usage.ts
# Skills-focused demonstrations
npx tsx examples/skills_demo.ts
# Complete integration demo with chatbot processing
npx tsx examples/chatbot_integration_demo.tsThe skills demo showcases advanced features:
- ✅ Skills schema auto-discovery
- 🔍 Natural language skill queries ("Who knows React?")
- 👥 Expert-level filtering ("Who are the Python experts?")
- 📊 Department-specific skills analysis
- 🤝 Similar skill profile matching
- 💡 Skill suggestions and analytics
# Run unit tests
npm test
# Run integration tests (requires valid tokens)
npm run test:int- Intelligent Caching: Field schema cached for 10 minutes, reducing API calls by ~70%
- Efficient Pagination: Handles large orgs (1000+ employees) with cursor-based navigation
- Smart Retry Logic: Exponential backoff prevents API rate limit issues
- Minimal Bundle Size: ESM: ~45KB, CJS: ~48KB (no external dependencies)
- Fast Initialization: Skills schema discovery completes in <2 seconds
- TypeScript: Full type safety with comprehensive interfaces
- Dual Build: ESM + CommonJS support for maximum compatibility
- Node.js: 18+ (uses native fetch) or provide custom fetch implementation
- Browser Support: Modern browsers with fetch API support
- Serverless: Compatible with AWS Lambda, Vercel, Netlify functions
- Error Resilience: Graceful degradation and user-friendly error messages
- Request Deduplication: Automatic elimination of redundant API calls
- Batch Processing: Intelligent handling of multiple related queries
- Connection Pooling: Optimized for high-throughput scenarios
- Memory Efficient: Streaming responses for large datasets
- Rate Limit Aware: Built-in handling of API throttling
- npm Package: Published to npm registry with proper ESM/CJS exports
- Source Maps: Included for debugging and development
- Type Definitions: Complete .d.ts files for all modules
- Tree Shaking: ESM build supports optimal bundling
- Zero Dependencies: No external runtime dependencies for maximum compatibility
SiftClient: Low-level, robust API client with intelligent caching, automatic retry logic, and comprehensive error handlingChatbotSiftClient: High-level wrapper providing natural language methods and data enrichmentSkillsClient: Specialized skills engine with canonicalization, scoring, and fuzzy matching capabilities- Rich Types: Comprehensive TypeScript interfaces for all data structures with full type safety
- Smart Caching: Automatic field schema caching (10-minute TTL) to reduce API calls and improve performance
- Intelligent Retry: Exponential backoff for 429/5xx errors with configurable timeout (15s default)
- Skills Canonicalization: Built-in alias mapping (React/ReactJS, AWS/Amazon Web Services, etc.)
- Advanced Scoring: Relevance-based ranking for skills and search results
- Automatic Enrichment: Computed fields like org levels, manager chains, and photo URLs
- Flexible Filtering: Complex boolean logic with AND/OR/NOT operations and nested conditions
- Pagination Support: Efficient handling of large datasets with cursor-based navigation
User Query → ChatbotSiftClient → SkillsClient/SiftClient → Sift API → Enriched Response
↓
Field Caching & Schema Discovery
The Sift Helper includes a sophisticated skills engine that goes beyond basic keyword matching:
Smart Canonicalization
- Automatic alias handling:
React↔ReactJS,AWS↔Amazon Web Services - Handles common variations:
C#↔CSharp,Node.js↔NodeJS - Fuzzy matching for partial skill names
Intelligent Scoring
- Relevance-based ranking combining skill level, featured status, and exact matches
- Configurable minimum proficiency levels (1-5 scale)
- Featured skills get priority ranking
Multi-Source Skills
- Primary skills from dedicated fields
- Language proficiency skills from language profiles
- Automatic deduplication and level mapping
// Organization-wide skills intelligence
const analytics = await chatbot.getSkillsAnalytics('Engineering');
console.log({
totalPeopleWithSkills: analytics.totalPeopleWithSkills,
topSkills: analytics.topSkills.slice(0, 5),
skillsByDepartment: analytics.skillsByDepartment
});
// Skill suggestions for autocomplete
const suggestions = await chatbot.getSkillSuggestions('java', 10);
// Similar skill profiles for team building
const similarPeople = await chatbot.findPeopleWithSimilarSkills('jane@company.com', 3);- Team Formation: Find people with complementary skills for projects
- Expert Discovery: Identify subject matter experts across the organization
- Career Development: Match employees with growth opportunities
- Resource Planning: Understand skill distribution for hiring decisions
- Knowledge Sharing: Connect people with similar or complementary expertise
- Use descriptive method names: Methods are named to match natural language
- Handle errors gracefully: All methods include proper error handling
- Leverage convenience methods: Use
whoIsManager(),whoReportsTo()for simple responses - Cache field metadata: The client automatically caches org schema
- Include photos when needed: Set
includePhotos: truefor UI components
The ChatbotSiftClient automatically enriches person data with computed fields:
| Field | Description | Example |
|---|---|---|
level |
Organizational level derived from reporting path | 3 (VP level) |
departmentName |
Clean department name | "Engineering" |
officeName |
Office location | "San Francisco" |
managerName |
Direct manager's name | "Sarah Johnson" |
photoUrl |
Profile photo URL (when requested) | "https://..." |
Benefits:
- ✅ No additional API calls required
- ✅ Consistent data formatting
- ✅ Ready for UI consumption
- ✅ Cached for performance
const seniorEngineers = await chatbot.findPeopleByRole('engineer', {
department: 'Engineering',
minReports: 2, // Senior ICs or managers
office: 'Seattle',
includePhotos: true,
limit: 20
});const orgData = await chatbot.getCompleteOrgTree('vp@company.com', 4);
// Use with visualization libraries
const chartNodes = orgData.orgChart.nodes.map(person => ({
id: person.id,
label: person.displayName,
title: person.title,
level: person.level,
photo: person.photoUrl
}));
const chartEdges = orgData.orgChart.edges;All methods include comprehensive error handling:
try {
const manager = await chatbot.getPersonsManager('unknown@company.com');
} catch (error) {
console.log('Person not found or has no manager');
}
// Or use the convenience methods that return user-friendly strings
const response = await chatbot.whoIsManager('unknown@company.com');
// Returns: "This person doesn't have a manager listed."We welcome contributions! Here's how to get started:
# Fork and clone the repository
git clone https://github.com/Mat-Tom-Son/siftHelper.git
cd sift-helper
# Install dependencies
npm install
# Run tests
npm test
# Run examples
npm run dump- Add new methods to
ChatbotSiftClientwith descriptive names that match natural language - Include comprehensive TypeScript types for all parameters and return values
- Add error handling and user-friendly responses for chatbot integration
- Write tests for new functionality (both unit and integration tests)
- Update this README with examples and documentation
- Follow existing patterns for consistency
- Open an issue on GitHub
- Include sample code, error messages, and expected behavior
- Tag issues with appropriate labels
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ for the Sift community