Technical Documentation

How StatsAware works internally

StatsAware API Documentation

Connect your tools and services to track team activity

Getting Started

StatsAware helps you see when your team is active across different tools and timezones. Instead of manually checking Slack, Git, or project management tools, get a unified view of who's working, when they're available, and what they're working on.

How It Works

  1. Get your API key from your StatsAware dashboard
  2. Send activity data from your tools via our simple REST API
  3. View unified activity across your team in real-time

What You Can Track

  • Presence status: Who's online, in meetings, or taking breaks
  • Activity events: Commits, messages, task updates, and more
  • Work patterns: When people start/stop working across timezones
  • Team collaboration: See activity overlaps and coordination

Authentication

All API requests require a Bearer token using your integration's API key.

Authorization: Bearer tc_U9aXo8zTqJ7bY2wV3sDc

Getting Your API Key

  1. Log into your StatsAware dashboard
  2. Go to SettingsIntegrations
  3. Create a new integration or copy an existing API key
  4. API keys start with tc_ followed by 20 characters

Security Best Practices

  • Store API keys securely - never commit to version control
  • Use environment variables in production
  • Regenerate keys if compromised
  • Limit API access to only necessary services

Presence API

Track when team members are online, offline, or busy in real-time.

Endpoint

POST /api/v1/presence

Use Cases

  • Custom chat tools: Send online/offline status
  • Productivity apps: Track focus time vs. break time
  • Meeting systems: Show when people join/leave calls
  • Desk sensors: Physical presence detection
  • Calendar integration: Sync meeting status

Request Format

{
  "timestamp": "2024-01-15T14:30:00Z",
  "source": "slack-bot",
  "users": [
    {
      "personIdentifier": "john.doe",
      "name": "John Doe",
      "status": "online",
      "timezone": "America/New_York",
      "email": "[email protected]",
      "details": {
        "location": "office"
      }
    },
    {
      "personIdentifier": "jane.smith", 
      "name": "Jane Smith",
      "status": "away",
      "timezone": "Europe/London",
      "email": "[email protected]"
    }
  ]
}

Status Values

StatsAware accepts any string as a status value. Common examples from integrations:

| Status | Description | Used By | |--------|-------------|---------| | online | Actively working | Slack, Microsoft Teams | | away | Temporarily away | Slack, Microsoft Teams | | offline | Not working | All integrations | | busy | In a meeting/call/DND | Microsoft Teams | | meeting | In a meeting | Demo integration | | coding | Active development | Demo integration | | lunch | Taking lunch break | Demo integration |

Note: You can use any status string that makes sense for your integration. StatsAware will track and display whatever values you send.

Response

{
  "success": true,
  "timestamp": "2024-01-15T14:30:05Z",
  "processed": {
    "users": 2,
    "statuses": {
      "online": 1,
      "away": 1
    }
  }
}

Events API

Log discrete activities like commits, messages, or task updates.

Endpoint

POST /api/v1/events

Use Cases

  • Git webhooks: Track commits and code changes
  • Project management: Log task completions and updates
  • Communication tools: Record message activity (not content)
  • Document collaboration: Track file edits and comments
  • Custom workflows: Any discrete work events

Request Format

{
  "events": [
    {
      "kind": "commit",
      "externalId": "abc123-commit-456",
      "personIdentifier": "john.doe",
      "timestamp": "2024-01-15T14:25:00Z",
      "title": "Fix user authentication bug",
      "scope": "backend/auth",
      "url": "https://github.com/company/repo/commit/abc123",
      "details": {
        "repository": "company/main-app",
        "branch": "feature/auth-fix",
        "filesChanged": 3,
        "linesAdded": 45,
        "linesRemoved": 12
      }
    },
    {
      "kind": "task_update",
      "externalId": "jira-PROJ-123",
      "personIdentifier": "jane.smith",
      "timestamp": "2024-01-15T14:28:00Z", 
      "title": "Complete user onboarding flow",
      "scope": "Product/UX",
      "url": "https://company.atlassian.net/browse/PROJ-123",
      "details": {
        "status": "completed",
        "project": "Q1 Growth",
        "estimatedHours": 8,
        "actualHours": 6.5
      }
    }
  ]
}

Event Types

| Kind | Description | Examples | |------|-------------|----------| | commit | Code commits | Git push, SVN commit | | message | Communication | Chat, email, comment | | task_update | Project work | Jira update, Trello card | | meeting_join | Meeting activity | Zoom join, calendar event | | file_edit | Document work | Google Docs, Notion page | | review | Code/content review | GitHub PR, design review | | deploy | System changes | Production deploy, release |

Note: You can use any event kind string that makes sense for your integration. These are common examples.

Required Fields

  • kind: Event type (see table above)
  • externalId: Unique identifier (prevents duplicates)
  • personIdentifier: User identifier (same as presence API)
  • timestamp: When the event occurred (ISO 8601)
  • title: Human-readable description
  • scope: Project/area context

Optional Fields

  • url: Link to the actual item
  • details: Additional metadata (flexible JSON)

Response

{
  "success": true,
  "timestamp": "2024-01-15T14:30:05Z",
  "processed": {
    "total": 2,
    "created": 2,
    "skipped": 0,
    "errors": 0
  }
}

Data Models

Person Identification

StatsAware automatically matches users across integrations using the personIdentifier field. This should be:

  • Consistent: Same ID across all your integrations
  • Unique: Different for each team member
  • Stable: Doesn't change over time

Good examples:

  • Email addresses: [email protected]
  • Employee IDs: emp_12345
  • Usernames: john.doe

Avoid:

  • Display names (can change): John D.
  • Temporary IDs: Session tokens, random UUIDs

Timezone Handling

StatsAware displays activity in each person's local timezone for accurate coordination across global teams.

{
  "personIdentifier": "maria.garcia",
  "timezone": "Europe/Madrid",
  "status": "online"
}

Timezone format: Use IANA timezone names

  • America/New_York, Europe/London, Asia/Tokyo
  • EST, GMT+1, PST

Activity Blocks vs Events

StatsAware tracks two types of data:

Activity Blocks (from Presence API)

Duration-based tracking - how long someone was in a state:

  • Online for 2 hours (9 AM - 11 AM)
  • In meeting for 30 minutes (2 PM - 2:30 PM)
  • Taking break for 15 minutes (10:15 AM - 10:30 AM)

Activity Events (from Events API)

Point-in-time actions - discrete things that happened:

  • Committed code at 10:23 AM
  • Completed task at 3:47 PM
  • Joined meeting at 2:00 PM

Testing Your Integration

1. Verify API Access

Test your authentication with a simple presence update:

curl -X POST /api/v1/presence \
  -H "Authorization: Bearer tc_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
    "source": "test",
    "users": [{
      "personIdentifier": "[email protected]",
      "name": "Test User", 
      "status": "online",
      "timezone": "America/New_York",
      "email": "[email protected]"
    }]
  }'

2. Check Your Dashboard

After sending test data:

  1. Log into your StatsAware dashboard
  2. Look for your test user in the activity view
  3. Verify the status and timing look correct
  4. Check that timezone conversion worked properly

3. Monitor API Responses

Success Response (HTTP 200):

{
  "success": true,
  "timestamp": "2024-01-15T14:30:05Z",
  "processed": { "users": 1, "statuses": { "online": 1 } }
}

Common Errors:

| Status | Error | Solution | |--------|-------|----------| | 401 | Missing API key | Add Authorization header | | 401 | Invalid API key | Check your API key is correct | | 403 | Integration not active | Activate integration in dashboard | | 403 | Account onboarding incomplete | Complete setup process | | 500 | Processing failed | Check request format, try again |

Advanced Features

Rate Limiting

StatsAware automatically handles reasonable API usage. For high-volume integrations:

  • Batch requests: Send multiple users/events per request
  • Reasonable intervals: Don't send presence updates more than once per minute
  • Handle errors gracefully: Implement retry logic with exponential backoff

Duplicate Prevention

Events API automatically prevents duplicates using externalId:

  • Use a unique, stable ID for each event
  • Format: {source}-{original_id} (e.g., github-abc123, jira-PROJ-456)
  • Duplicates are silently skipped (not an error)

Presence API always accepts updates (no duplicate checking).

Error Handling Best Practices

async function sendToStatsAware(endpoint, data) {
  const maxRetries = 3;
  let attempt = 1;
  
  while (attempt <= maxRetries) {
    try {
      const response = await fetch(`${endpoint}`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      
      if (response.ok) {
        return await response.json();
      }
      
      if (response.status === 401 || response.status === 403) {
        throw new Error(`Authentication error: ${response.status}`);
      }
      
      // Retry on server errors
      if (response.status >= 500 && attempt < maxRetries) {
        await sleep(Math.pow(2, attempt) * 1000); // Exponential backoff
        attempt++;
        continue;
      }
      
      throw new Error(`API error: ${response.status}`);
      
    } catch (error) {
      if (attempt === maxRetries) {
        console.error('Failed to send data to StatsAware:', error);
        throw error;
      }
      attempt++;
    }
  }
}

Popular Integration Ideas

Development Tools

  • Git repositories: Commit activity, PR reviews
  • CI/CD systems: Build status, deployment events
  • Code editors: Active coding sessions (VS Code extensions)
  • Issue trackers: Jira, Linear, GitHub Issues

Communication

  • Chat platforms: Slack, Discord, Teams presence
  • Email systems: Email send/receive activity
  • Video calls: Zoom, Meet join/leave events

Productivity

  • Time tracking: Toggle, Harvest, RescueTime
  • Calendar systems: Google Calendar, Outlook events
  • Note taking: Notion, Obsidian, Roam Research
  • Task management: Todoist, Asana, Monday.com

Custom Solutions

  • Physical presence: Badge scanners, IoT sensors
  • Workflow automation: Zapier, IFTTT triggers
  • Internal tools: Custom dashboards, admin systems
  • Analytics events: User actions, feature usage

Support

Documentation

  • API reference: This page covers all endpoints
  • Integration examples: See code samples above
  • Status page: Check API health at status.statsaware.com

Getting Help

  • Email support: [email protected]
  • Response time: Within 24 hours for technical questions
  • Include: Your integration details, error messages, example requests

Common Questions

Q: Can I send historical data?
A: Only in the events api, not for presence.

Q: What if someone uses multiple emails?
A: Use the most consistent identifier across your tools. You can merge data streams into people later.

Q: How often should I send presence updates?
A: Every 1-5 minutes is ideal. More frequent updates won't improve accuracy significantly.

Q: Can I delete or modify data after sending?
A: Not for presence, but you can update events with events identifiers you used before.

Q: Is there a test environment?
A: Use your production integration with test data - it's easy to filter or ignore in your dashboard.


Ready to start? Get your API key from the StatsAware dashboard and send your first presence update!

More questions? We are happy to assist!