Linear Integration

Overview

This guide explains how to integrate Hardal analytics with Linear’s issue tracking system using Hardal’s Custom API integration. By connecting these platforms, you can automatically create Linear issues based on analytics events captured by Hardal, streamlining your workflow between user analytics and project management.

This integration leverages Linear’s GraphQL API to create issues directly from Hardal events.

Prerequisites

Before setting up the integration, ensure you have:

  • A Hardal account with access to Marketing Destinations
  • A Linear account with API access
  • Linear API key or OAuth2 authentication configured
  • A Linear Team ID where issues will be created

Setting Up Linear Authentication

1

Access Linear API Settings

  1. Log in to your Linear account
  2. Navigate to Settings > Account > API
2

Generate API Key

Click “Create Key” to generate a new personal API key

3

Copy API Key

Save this key securely (it will only be shown once)

4

Verify Permissions

Ensure your API key has sufficient permissions to create issues

Keep your API key secure! Never expose it in client-side code or public repositories.

Finding Your Linear Team ID

To create issues in the correct team, you need the Team ID:

1

Open Command Menu

In Linear, open the command menu (⌘/CTRL+K)

2

Select 'Copy model UUID'

Type “Copy model UUID” and select it

3

Navigate to Team Page

First navigate to your team’s page

4

Copy Team UUID

The copied value is your Team ID

Creating a Custom API Destination in Hardal

1

Access Destinations

  1. Go to your Hardal dashboard
  2. Navigate to Marketing Destinations
2

Add Custom Destination

Click “Add Custom Destination”

3

Select Template

Select “Custom API” from the templates

4

Configure Basic Settings

Fill in the following settings:

SettingValue
Endpoint LabelLinear Integration
Endpoint IDlinear-integration
Endpoint URLhttps://api.linear.app/graphql
Request MethodPOST
Content Typeapplication/json

Adding Authentication Headers

Add a header for Linear authentication:

{
  "headers": {
    "Authorization": "Bearer YOUR_LINEAR_API_KEY"
  }
}

Replace YOUR_LINEAR_API_KEY with the API key you generated earlier.

Configuring the GraphQL Query

For the request format, you’ll need to use a GraphQL mutation:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"##event_name## from Hardal\", description: \"Event details: ##properties##\", teamId: \"YOUR_TEAM_ID\" }) { success issue { id title } } }"
}

Replace YOUR_TEAM_ID with the Team ID you copied earlier. You can use Hardal variables like ##event_name## and ##properties## to dynamically insert data from events.

Example Use Cases

Example 1: NPS Responses to Linear Issues

This example creates a Linear issue whenever an NPS (Net Promoter Score) response is received:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"NPS Received: ##properties.user## - ##properties.score##\", description: \"NPS received from Hardal Connections.\\nUser: ##properties.user##\\nScore: ##properties.score##\\nFeedback: ##properties.feedback##\", teamId: \"a06dd9aa-72c4-4e0e-9814-03616f9297ab\" }) { success issue { id title } } }"
}

Add a condition to only trigger this for NPS events:

  • Event Name: equals - nps_response

Example 2: Error Events to Bug Reports

This example converts error events into Linear bug reports:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"Bug: ##properties.error_message##\", description: \"**Error Details**\\n\\nMessage: ##properties.error_message##\\nURL: ##page.url##\\nUser ID: ##user_id##\\nBrowser: ##browser.name## ##browser.version##\\nTimestamp: ##created_at##\", teamId: \"YOUR_TEAM_ID\", stateId: \"YOUR_BUG_STATE_ID\" }) { success issue { id title } } }"
}

Add a condition:

  • Event Name: equals - error_tracked

Example 3: Feature Requests from User Feedback

This example creates feature request issues from user feedback forms:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"Feature Request: ##properties.feature_title##\", description: \"**Feature Request Details**\\n\\nRequested by: ##properties.user_email##\\nPriority (user rated): ##properties.priority##/5\\n\\n**Description**\\n##properties.feature_description##\", teamId: \"YOUR_TEAM_ID\", labelIds: [\"FEATURE_REQUEST_LABEL_ID\"] }) { success issue { id title } } }"
}

Add a condition:

  • Event Name: equals - feature_request_submitted

Advanced Configuration

Assigning Issues to Team Members

To automatically assign issues to team members, include the assigneeId field:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"##properties.title##\", description: \"##properties.description##\", teamId: \"YOUR_TEAM_ID\", assigneeId: \"USER_ID\" }) { success issue { id title } } }"
}

Setting Issue Priority

To set priority on Linear issues:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"##properties.title##\", description: \"##properties.description##\", teamId: \"YOUR_TEAM_ID\", priority: ##properties.priority## }) { success issue { id title } } }"
}

Linear priority values are 0 (no priority), 1 (urgent), 2 (high), 3 (medium), 4 (low).

Adding Labels to Issues

To add labels to your issues:

{
  "query": "mutation IssueCreate { issueCreate(input: { title: \"##properties.title##\", description: \"##properties.description##\", teamId: \"YOUR_TEAM_ID\", labelIds: [\"LABEL_ID_1\", \"LABEL_ID_2\"] }) { success issue { id title } } }"
}

You’ll need to find the Label IDs using the same method as finding Team IDs.

Testing & Troubleshooting

1

Use Test Endpoint

Use the “Test Endpoint” button in Hardal to verify your configuration

2

Check Response

A successful response should contain {"data":{"issueCreate":{"success":true}}}

3

Verify in Linear

Check that the issue appears in your Linear workspace

4

Debug if Needed

If issues aren’t appearing, check the troubleshooting guide below

Common Issues and Solutions

Resources