Latest
Sign InSign Up
Product
Resources
DocsTaskmasterHamster StudioCareersAbout
Latest
Sign InSign Up

Same-day shipping for your product team

© 2025 Wheel Go Fast, Inc. All Rights Reserved.

GitHubDiscord
Latest
Resources
  • Docs
  • Careers
  • About
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
    • Quick Start
    • Installation
    • Configuration
    • Briefs
    • Tasks
    • Collaboration
    • AI Assistant
    • Creating Teams
    • Inviting Members
    • Roles & Permissions
    • GitHub
    • Linear
    • Slack

Linear Integration

Synchronize your tasks and issues between our platform and Linear to create a unified project management workflow. This integration ensures your development team stays aligned with project goals while maintaining their preferred Linear workspace.

Overview

Why Integrate Linear?

The Linear integration provides:

  • Unified Task Management: Keep tasks synchronized across both platforms
  • Developer-Friendly Workflow: Maintain Linear's streamlined development experience
  • Bi-directional Sync: Changes in either platform reflect automatically
  • Team Alignment: Ensure project briefs align with development tickets
  • Progress Tracking: Monitor development progress from project briefs

Key Features

Task Synchronization

  • Bi-directional task and issue sync
  • Status mapping between platforms
  • Priority and label synchronization
  • Assignment and ownership tracking
  • Comment and activity sync

Project Management

  • Linear team mapping to platform projects
  • Milestone and cycle integration
  • Epic and initiative alignment
  • Sprint planning coordination
  • Release tracking and reporting

Workflow Integration

  • Automated task creation from briefs
  • Custom field mapping and sync
  • Workflow state synchronization
  • Time tracking integration
  • Progress reporting and analytics

Setup Process

Prerequisites

Before setting up the Linear integration, ensure you have:

  • Linear Account: Access to a Linear workspace
  • Linear Admin Access: Admin permissions in your Linear workspace
  • Platform Team Admin: Admin or owner role in your platform team
  • API Access: Linear API access enabled for your workspace

Step-by-Step Setup

1. Generate Linear API Key

First, create an API key in your Linear workspace:

  1. Access Linear Settings: Go to Linear → Settings → API
  2. Create Personal API Key: Click "Create API Key"
  3. Set Permissions: Grant appropriate permissions for the integration
  4. Copy API Key: Save the generated key securely

2. Configure Platform Integration

Set up the integration in your platform team settings:

  1. Navigate to Integrations: Team Settings → Integrations
  2. Select Linear: Find Linear in the available integrations
  3. Enter API Key: Provide your Linear API key
  4. Test Connection: Verify the connection is working

3. Map Teams and Projects

Configure the mapping between Linear teams and platform projects:

{
  "team_mappings": [
    {
      "platform_project_id": "proj_123",
      "linear_team_id": "team_456",
      "sync_settings": {
        "bi_directional": true,
        "auto_create_issues": true,
        "sync_comments": true,
        "sync_attachments": false
      }
    }
  ]
}

4. Configure Field Mapping

Set up how fields should map between the platforms:

{
  "field_mappings": {
    "status": {
      "pending": "Todo",
      "in-progress": "In Progress", 
      "review": "In Review",
      "completed": "Done",
      "cancelled": "Canceled"
    },
    "priority": {
      "low": 4,
      "medium": 3,
      "high": 2,
      "critical": 1
    },
    "labels": {
      "bug": "Bug",
      "feature": "Feature",
      "improvement": "Improvement"
    }
  }
}

Configuration Options

Synchronization Settings

Sync Direction

Bi-directional Sync (Recommended)

  • Changes in either platform sync to the other
  • Conflict resolution with last-modified-wins
  • Complete alignment between platforms
  • Requires careful workflow coordination

Platform to Linear

  • Tasks created in platform become Linear issues
  • Updates flow from platform to Linear only
  • Maintains platform as source of truth
  • Simpler conflict resolution

Linear to Platform

  • Linear issues become platform tasks
  • Development-driven project management
  • Linear maintains issue ownership
  • Good for development-focused teams

Real-time vs Batch Sync

Real-time Synchronization

const syncConfig = {
  mode: 'real-time',
  webhook_endpoints: {
    linear: 'https://your-platform.com/webhooks/linear',
    platform: 'https://linear-webhook.your-domain.com/platform'
  },
  retry_policy: {
    max_attempts: 3,
    backoff_strategy: 'exponential'
  }
};

Batch Synchronization

const batchConfig = {
  mode: 'batch',
  schedule: 'every 15 minutes',
  batch_size: 100,
  processing_window: '5 minutes'
};

Advanced Configuration

Custom Field Mapping

Map custom fields between platforms:

{
  "custom_fields": {
    "platform_to_linear": {
      "estimated_hours": {
        "linear_field": "estimate",
        "transform": "hours_to_points"
      },
      "epic_id": {
        "linear_field": "parent_id",
        "type": "relation"
      }
    },
    "linear_to_platform": {
      "estimate": {
        "platform_field": "estimated_hours", 
        "transform": "points_to_hours"
      },
      "cycle": {
        "platform_field": "sprint",
        "type": "reference"
      }
    }
  }
}

Workflow Automation

Set up automated workflows based on Linear events:

# automation-rules.yml
workflows:
  - name: "Auto-create tasks from Linear issues"
    trigger:
      platform: "linear"
      event: "issue.created" 
      conditions:
        - field: "team_id"
          operator: "equals"
          value: "team_456"
    actions:
      - create_platform_task:
          project_id: "proj_123"
          title: "{{ issue.title }}"
          description: "{{ issue.description }}"
          assignee: "{{ issue.assignee.email }}"
          
  - name: "Update Linear status on platform completion"
    trigger:
      platform: "platform"
      event: "task.completed"
    actions:
      - update_linear_issue:
          status: "Done"
          comment: "Completed in platform: {{ task.completion_notes }}"

Using the Integration

Task Creation and Sync

Creating Tasks from Platform

When you create a task in your platform project:

  1. Automatic Linear Issue: A corresponding issue is created in Linear
  2. Field Mapping: Task properties are mapped to Linear issue fields
  3. Assignment Sync: Task assignee becomes Linear issue assignee
  4. Linking: Both items are linked for bi-directional updates

Platform Task Example:

{
  "id": "task_789",
  "title": "Implement user dashboard analytics",
  "description": "Create analytics dashboard showing user engagement metrics",
  "priority": "high",
  "status": "pending",
  "assignee": "[email protected]",
  "labels": ["feature", "analytics"],
  "estimated_hours": 16
}

Generated Linear Issue:

{
  "id": "ISS-123",
  "title": "Implement user dashboard analytics",
  "description": "Create analytics dashboard showing user engagement metrics\n\n---\nCreated from Platform Task: task_789",
  "priority": 2,
  "state": "Todo",
  "assignee": {
    "email": "[email protected]"
  },
  "labels": ["feature", "analytics"],
  "estimate": 8
}

Creating Issues from Linear

When developers create issues directly in Linear:

  1. Platform Task Creation: Corresponding task appears in platform project
  2. Context Addition: Issue context is added to relevant project brief
  3. Team Notification: Project stakeholders are notified of new development work
  4. Progress Tracking: Issue progress reflects in project dashboards

Status and Progress Tracking

Status Synchronization

Status changes automatically sync between platforms:

Linear State Changes:

  • Todo → Pending (Platform)
  • In Progress → In Progress (Platform)
  • In Review → Review (Platform)
  • Done → Completed (Platform)
  • Canceled → Cancelled (Platform)

Progress Reporting

View combined progress across both platforms:

// Example progress dashboard data
const projectProgress = {
  platform_tasks: {
    total: 25,
    completed: 18,
    in_progress: 5,
    pending: 2
  },
  linear_issues: {
    total: 32,
    done: 20,
    in_progress: 8,
    todo: 4
  },
  sync_status: {
    synced_items: 23,
    sync_errors: 2,
    last_sync: "2024-01-22T14:30:00Z"
  }
};

Comment and Activity Sync

Bi-directional Comments

Comments automatically sync between platforms:

Platform Comment:

Just reviewed the mockups - the analytics layout looks great! 

One suggestion: can we add a date range picker for the metrics?

@sarah.developer what do you think about the implementation complexity?

Synced to Linear:

💬 **Comment from Platform** (by @john.designer)

Just reviewed the mockups - the analytics layout looks great! 

One suggestion: can we add a date range picker for the metrics?

@sarah.developer what do you think about the implementation complexity?

---
*View in Platform: [task_789](https://platform.com/tasks/task_789)*

Activity Timeline

Unified activity timeline showing actions from both platforms:

  • Platform: Task created, status changed, comment added
  • Linear: Issue assigned, moved to In Progress, branch created
  • Platform: File attached, review requested
  • Linear: Pull request opened, code reviewed
  • Platform: Task marked complete

Advanced Features

Linear Webhooks Integration

Set up Linear webhooks for real-time synchronization:

Webhook Configuration

// Linear webhook handler
app.post('/webhooks/linear', async (req, res) => {
  const { action, data, type } = req.body;
  
  try {
    switch (type) {
      case 'Issue':
        await handleIssueUpdate(action, data);
        break;
      case 'Comment':
        await handleCommentUpdate(action, data);
        break;
      case 'IssueLabel':
        await handleLabelUpdate(action, data);
        break;
    }
    
    res.status(200).send('OK');
  } catch (error) {
    console.error('Linear webhook error:', error);
    res.status(500).send('Error processing webhook');
  }
});

async function handleIssueUpdate(action, issue) {
  const platformTask = await findLinkedTask(issue.id);
  
  if (!platformTask) return;
  
  switch (action) {
    case 'update':
      await syncIssueToTask(issue, platformTask);
      break;
    case 'delete':
      await handleIssueDeleted(issue, platformTask);
      break;
  }
}

Custom Integrations

Linear GraphQL API

Use Linear's GraphQL API for advanced integrations:

# Query for team issues with custom fields
query TeamIssues($teamId: String!) {
  team(id: $teamId) {
    issues {
      nodes {
        id
        title
        description
        state {
          name
          type
        }
        assignee {
          email
          name
        }
        labels {
          nodes {
            name
            color
          }
        }
        estimate
        cycle {
          name
          startsAt
          endsAt
        }
        parent {
          id
          title
        }
        children {
          nodes {
            id
            title
          }
        }
      }
    }
  }
}

Platform API Integration

Sync data using platform APIs:

// Sync Linear cycle to platform sprint
async function syncCycleToSprint(cycle) {
  const sprint = await platformApi.sprints.create({
    name: cycle.name,
    start_date: cycle.startsAt,
    end_date: cycle.endsAt,
    team_id: getTeamMapping(cycle.team.id),
    external_id: cycle.id,
    external_source: 'linear'
  });
  
  // Update all cycle issues to reference the sprint
  const issues = await linearApi.issues.list({
    filter: { cycle: { id: { eq: cycle.id } } }
  });
  
  for (const issue of issues.nodes) {
    const task = await findLinkedTask(issue.id);
    if (task) {
      await platformApi.tasks.update(task.id, {
        sprint_id: sprint.id
      });
    }
  }
}

Reporting and Analytics

Cross-Platform Reports

Generate reports combining data from both platforms:

// Generate development velocity report
async function generateVelocityReport(teamId, timeframe) {
  const [platformTasks, linearIssues] = await Promise.all([
    platformApi.tasks.list({
      team_id: teamId,
      completed_after: timeframe.start,
      completed_before: timeframe.end
    }),
    linearApi.issues.list({
      filter: {
        team: { id: { eq: getLinearTeamId(teamId) } },
        completedAt: {
          gte: timeframe.start,
          lte: timeframe.end
        }
      }
    })
  ]);
  
  return {
    platform_velocity: {
      tasks_completed: platformTasks.length,
      total_hours: platformTasks.reduce((sum, task) => sum + task.actual_hours, 0),
      average_completion_time: calculateAverage(platformTasks, 'completion_time')
    },
    linear_velocity: {
      issues_completed: linearIssues.nodes.length,
      total_estimate: linearIssues.nodes.reduce((sum, issue) => sum + (issue.estimate || 0), 0),
      story_points_per_day: calculateDailyAverage(linearIssues.nodes, timeframe)
    },
    sync_health: {
      synced_percentage: calculateSyncPercentage(platformTasks, linearIssues.nodes),
      last_sync_error: await getLastSyncError(teamId)
    }
  };
}

Troubleshooting

Common Issues

Sync Conflicts

Status Update Conflicts:

// Handle conflicting status updates
async function resolveSyncConflict(taskId, issueId, conflict) {
  const resolution = await determinePriority(conflict);
  
  switch (resolution.strategy) {
    case 'platform_wins':
      await updateLinearIssue(issueId, {
        state: mapStatusToLinearState(conflict.platform_status)
      });
      break;
      
    case 'linear_wins':
      await updatePlatformTask(taskId, {
        status: mapLinearStateToStatus(conflict.linear_status)
      });
      break;
      
    case 'manual_review':
      await createConflictResolutionTask(taskId, issueId, conflict);
      break;
  }
}

API Rate Limiting

Linear API Rate Limits:

  • 1000 requests per hour per user
  • 10 requests per second burst limit
  • GraphQL complexity limits

Rate Limit Handling:

const rateLimiter = {
  async makeRequest(requestFn) {
    try {
      return await requestFn();
    } catch (error) {
      if (error.status === 429) {
        const retryAfter = error.headers['retry-after'] * 1000;
        await new Promise(resolve => setTimeout(resolve, retryAfter));
        return await requestFn();
      }
      throw error;
    }
  }
};

Authentication Issues

API Key Validation:

async function validateLinearApiKey(apiKey) {
  try {
    const response = await fetch('https://api.linear.app/graphql', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        query: 'query { viewer { id name email } }'
      })
    });
    
    const data = await response.json();
    
    if (data.errors) {
      throw new Error('Invalid API key or insufficient permissions');
    }
    
    return data.data.viewer;
  } catch (error) {
    console.error('Linear API key validation failed:', error);
    return null;
  }
}

Debugging Tools

Sync Status Monitor

// Monitor synchronization health
async function getSyncHealth(teamMapping) {
  const health = {
    last_sync: await getLastSyncTime(teamMapping.id),
    pending_syncs: await getPendingSyncs(teamMapping.id),
    failed_syncs: await getFailedSyncs(teamMapping.id),
    success_rate: await getSyncSuccessRate(teamMapping.id),
    latency: await getAverageSyncLatency(teamMapping.id)
  };
  
  health.status = determineHealthStatus(health);
  return health;
}

function determineHealthStatus(health) {
  if (health.failed_syncs > 5) return 'critical';
  if (health.success_rate < 0.95) return 'degraded';
  if (health.latency > 30000) return 'slow';
  return 'healthy';
}

Integration Testing

// Test Linear integration end-to-end
async function testLinearIntegration(teamMapping) {
  const testResults = [];
  
  try {
    // Test 1: Create platform task
    const task = await createTestTask(teamMapping.platform_project_id);
    testResults.push({ test: 'task_creation', status: 'passed' });
    
    // Test 2: Verify Linear issue creation
    await new Promise(resolve => setTimeout(resolve, 5000)); // Wait for sync
    const issue = await findLinearIssue(task.linear_issue_id);
    testResults.push({ 
      test: 'issue_sync', 
      status: issue ? 'passed' : 'failed' 
    });
    
    // Test 3: Update issue status in Linear
    await updateLinearIssueStatus(issue.id, 'In Progress');
    testResults.push({ test: 'status_update', status: 'passed' });
    
    // Test 4: Verify platform task update
    await new Promise(resolve => setTimeout(resolve, 5000));
    const updatedTask = await getPlatformTask(task.id);
    testResults.push({
      test: 'status_sync_back',
      status: updatedTask.status === 'in-progress' ? 'passed' : 'failed'
    });
    
    // Cleanup
    await deleteTestTask(task.id);
    await deleteLinearIssue(issue.id);
    
  } catch (error) {
    testResults.push({ 
      test: 'integration_test', 
      status: 'failed', 
      error: error.message 
    });
  }
  
  return testResults;
}

Best Practices

Workflow Optimization

Team Structure Alignment

Map Linear Teams to Platform Projects:

const teamStructure = {
  // Frontend team handles UI/UX briefs
  'frontend-team': {
    linear_team_id: 'team_frontend_123',
    platform_projects: ['ui-redesign', 'mobile-app'],
    sync_settings: {
      auto_create_from_briefs: true,
      label_mapping: {
        'ui': 'Frontend',
        'mobile': 'Mobile'
      }
    }
  },
  
  // Backend team handles API and infrastructure
  'backend-team': {
    linear_team_id: 'team_backend_456',
    platform_projects: ['api-v2', 'infrastructure'],
    sync_settings: {
      priority_threshold: 'medium', // Only sync medium+ priority tasks
      include_technical_details: true
    }
  }
};

Development Cycle Integration

Sprint/Cycle Synchronization:

// Sync Linear cycles with platform sprints  
async function syncCycleWithSprint(cycle) {
  const sprint = await platformApi.sprints.findOrCreate({
    name: cycle.name,
    start_date: cycle.startsAt,
    end_date: cycle.endsAt,
    team_id: getTeamMapping(cycle.team.id)
  });
  
  // Move all cycle issues to sprint
  const cycleIssues = await linearApi.issues.list({
    filter: { cycle: { id: { eq: cycle.id } } }
  });
  
  for (const issue of cycleIssues.nodes) {
    const task = await findLinkedTask(issue.id);
    if (task) {
      await platformApi.tasks.update(task.id, {
        sprint_id: sprint.id,
        planned_start: cycle.startsAt,
        planned_end: cycle.endsAt
      });
    }
  }
}

Data Consistency

Conflict Resolution Strategy

const conflictResolution = {
  // Priority-based resolution
  priority: {
    'critical': 'linear_wins', // Critical issues drive platform updates
    'high': 'platform_wins',   // High priority tasks drive Linear
    'medium': 'last_modified', // Most recent change wins  
    'low': 'manual_review'     // Manual review for low priority
  },
  
  // Field-specific resolution
  fields: {
    'status': 'last_modified',
    'assignee': 'linear_wins',     // Developers manage assignments
    'priority': 'platform_wins',  // Product manages priorities
    'estimate': 'linear_wins',     // Developers manage estimates
    'description': 'platform_wins' // Product manages descriptions
  }
};

Data Validation

// Validate sync data before applying changes
function validateSyncData(platformTask, linearIssue) {
  const validations = [
    {
      name: 'title_length',
      test: () => platformTask.title.length <= 255,
      message: 'Task title exceeds Linear title limit'
    },
    {
      name: 'assignee_exists',
      test: async () => await linearApi.users.find(platformTask.assignee_email),
      message: 'Assignee not found in Linear workspace'
    },
    {
      name: 'valid_status',
      test: () => mapStatusToLinearState(platformTask.status) !== null,
      message: 'Platform status cannot be mapped to Linear state'
    }
  ];
  
  return Promise.all(validations.map(async validation => ({
    name: validation.name,
    passed: await validation.test(),
    message: validation.message
  })));
}

Next Steps

Your Linear integration is now set up! Here's what you can do next:

  1. Test the Integration: Create a test task in your platform and verify it appears in Linear
  2. Configure Team Workflows: Set up your team's specific sync preferences and field mappings
  3. Set up Notifications: Configure Slack Integration to get notified about Linear activity
  4. Monitor Sync Health: Use the integration dashboard to monitor synchronization status
  5. Explore Automation: Set up advanced project workflows through team settings and integrations

For questions or advanced configuration needs, check out our Integration Support Center or join the Developer Community.