---
title: "Linear Connector"
description: "Complete Linear integration guide for syncing issues, projects, and team activity data with Brevo via Tajo."
url: https://tajo.io/docs/connectors/custom/linear/
markdown: https://tajo.io/docs/connectors/custom/linear.md
lang: en-US
robots: noindex
---

# Linear Connector

Connector status: Planned Not built yet. Tajo does not run this connector today.

| Source field | Destination field | Sample value |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

Connect your Linear workspace to Brevo for customer-facing issue tracking, product update notifications, and development milestone campaigns through Tajo.

## Overview

| Property | Value |
| --- | --- |
| **Platform** | Linear |
| **Category** | Custom |
| **Setup Complexity** | Easy |
| **Official Integration** | No |
| **Data Synced** | Issues, Projects, Users, Events |
| **API Type** | GraphQL API |
| **Authentication** | OAuth 2.0 / Personal API Key |
| **Base URL** | `https://api.linear.app/graphql` |

## Features

- **Issue event sync** - Forward issue create, update, and complete events to Brevo contact timelines
- **Project milestone tracking** - Trigger Brevo campaigns when projects reach key milestones
- **Customer issue linking** - Associate Linear issues with Brevo contacts for support visibility
- **Label-based segmentation** - Map Linear labels to Brevo contact attributes
- **Cycle analytics** - Sync sprint/cycle completion data for team performance reporting
- **Webhook-driven automation** - Real-time event forwarding via Linear webhooks

## Prerequisites

Before you begin, ensure you have:

1. A Linear workspace with admin access
2. A Personal API key or OAuth application configured
3. A Brevo account with API access
4. A Tajo account with an active subscription

## Authentication

Linear supports Personal API keys and OAuth 2.0.

### Option 1: Personal API Key

1. Go to **Linear** > **Settings** > **API** > **Personal API keys**
2. Click **Create key**
3. Name it “Tajo Integration”
4. Copy the generated key (starts with `lin_api_`)

```bash
curl -X POST https://api.linear.app/graphql \
  -H "Authorization: $LINEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ viewer { id name email } }"}'
```

### Option 2: OAuth 2.0

For integrations serving multiple workspaces:

1. Create an OAuth application at [linear.app/settings/api/applications](https://linear.app/settings/api/applications)
2. Configure redirect URI: `https://app.tajo.io/callbacks/linear`
3. Request scopes: `read`, `write`, `issues:create`, `comments:create`

GraphQL API

Linear exclusively uses a GraphQL API. All queries and mutations go through a single endpoint: `https://api.linear.app/graphql`. Tajo handles all GraphQL query construction automatically.

### Connecting to Tajo

```bash
# Using Personal API Key
tajo connectors install linear \
  --api-key $LINEAR_API_KEY

# Using OAuth
tajo connectors install linear \
  --client-id $LINEAR_CLIENT_ID \
  --client-secret $LINEAR_CLIENT_SECRET
```

## Configuration

### Basic Setup

```yaml
connectors:
  linear:
    enabled: true

    sync:
      issues: true
      projects: true
      cycles: true
      users: true

    teams:
      - key: "ENG"
        sync_to_list: 38
      - key: "SUPPORT"
        sync_to_list: 39

    issue_states:
      - Backlog
      - Todo
      - "In Progress"
      - Done
      - Canceled
```

### Field Mapping

Map Linear user and issue data to Brevo attributes:

```yaml
field_mapping:
  # User fields
  id: LINEAR_USER_ID
  email: email
  name: FIRSTNAME

  # Issue metrics mapped to contact events
  last_issue_identifier: LAST_LINEAR_ISSUE
  last_issue_state: LAST_ISSUE_STATUS
  last_issue_priority: LAST_ISSUE_PRIORITY
  total_issues: LINEAR_ISSUE_COUNT

  # Project data
  current_project: ACTIVE_PROJECT
  team_key: LINEAR_TEAM
```

### Event Mapping

```yaml
event_mapping:
  Issue.create: ISSUE_CREATED
  Issue.update: ISSUE_UPDATED
  Issue.remove: ISSUE_DELETED
  Comment.create: COMMENT_ADDED
  Project.update: PROJECT_UPDATED
  Cycle.update: CYCLE_UPDATED
```

## API Endpoints

Linear uses a single GraphQL endpoint. Key queries and mutations used by Tajo:

| Operation | Type | Purpose |
| --- | --- | --- |
| `issues` | Query | List and filter issues |
| `issue` | Query | Get single issue by ID |
| `projects` | Query | List all projects |
| `cycles` | Query | List cycles (sprints) |
| `teams` | Query | List workspace teams |
| `users` | Query | List workspace members |
| `viewer` | Query | Get authenticated user info |
| `issueCreate` | Mutation | Create a new issue |
| `issueUpdate` | Mutation | Update an existing issue |
| `commentCreate` | Mutation | Add a comment to an issue |
| `webhookCreate` | Mutation | Register a webhook |

### Example GraphQL Query

```graphql
query GetIssues($filter: IssueFilter, $first: Int, $after: String) {
  issues(filter: $filter, first: $first, after: $after) {
    nodes {
      id
      identifier
      title
      state { name }
      priority
      assignee { email name }
      labels { nodes { name } }
      createdAt
      updatedAt
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Code Examples

### Initialize Connector

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('linear', {
  apiKey: process.env.LINEAR_API_KEY
});
```

### Sync Issues

```javascript
await tajo.connectors.sync('linear', {
  type: 'incremental',
  resources: ['issues'],
  teams: ['ENG', 'SUPPORT'],
  since: '2024-01-01'
});

const status = await tajo.connectors.status('linear');
console.log(status);
// {
//   connected: true,
//   lastSync: '2024-03-15T18:00:00Z',
//   issuesTracked: 3200,
//   projectsMonitored: 8,
//   usersLinked: 45
// }
```

### Handle Linear Webhooks

```javascript
app.post('/webhooks/linear', async (req, res) => {
  const event = req.body;

  // Verify webhook signature
  const signature = req.get('Linear-Signature');
  if (!verifyLinearSignature(req.body, signature)) {
    return res.status(401).send('Unauthorized');
  }

  await tajo.connectors.handleWebhook('linear', {
    type: event.type,
    action: event.action,
    payload: {
      issueId: event.data?.id,
      identifier: event.data?.identifier,
      title: event.data?.title,
      state: event.data?.state?.name,
      assigneeEmail: event.data?.assignee?.email
    }
  });

  res.status(200).send('OK');
});
```

### Create Issue from Brevo Event

```javascript
// Create a Linear issue when a Brevo contact submits a request
tajo.events.on('contact.event', async (event) => {
  if (event.name === 'FEATURE_REQUEST') {
    await tajo.connectors.create('linear', {
      teamId: 'ENG',
      title: `Feature Request: ${event.data.subject}`,
      description: event.data.description,
      priority: 3,
      labelIds: ['feature-request']
    });
  }
});
```

## Rate Limits

Linear enforces rate limits on its GraphQL API:

| Limit Type | Value |
| --- | --- |
| **Request rate** | 1,500 requests per hour per API key |
| **Query complexity** | 10,000 complexity points per request |
| **Pagination** | 250 nodes max per page (default 50) |
| **Webhooks** | Unlimited incoming events |

Complexity Budget

Linear uses a complexity-based rate limiting system. Simple queries cost fewer points. Tajo optimizes queries to minimize complexity by requesting only needed fields and using efficient pagination.

Linear returns `429 Too Many Requests` with a `Retry-After` header when limits are exceeded.

## Troubleshooting

### Common Issues

| Issue | Cause | Solution |
| --- | --- | --- |
| 401 Unauthorized | Invalid or revoked API key | Generate a new API key in Linear Settings |
| Query errors | Invalid GraphQL syntax | Validate queries using Linear’s API explorer |
| Missing issues | Team access restricted | Ensure API key owner has access to target teams |
| Webhook not firing | Incorrect URL or disabled | Check webhook status in Linear Settings > API > Webhooks |
| Pagination incomplete | Missing `after` cursor | Ensure pagination loops until `hasNextPage` is false |

### Debug Mode

```yaml
connectors:
  linear:
    debug: true
    log_level: verbose
    log_queries: true
```

### Test Connection

```bash
tajo connectors test linear
# ✓ GraphQL API connection successful
# ✓ Workspace access verified
# ✓ Team list readable
# ✓ Issue query operational
# ✓ Webhook registration available
```

## Best Practices

1. **Use webhooks for real-time** - Register webhooks instead of polling for issue changes
2. **Filter by team** - Only sync issues from relevant teams to reduce API usage
3. **Optimize GraphQL queries** - Request only needed fields to stay within complexity limits
4. **Map labels to segments** - Use Linear labels to drive Brevo contact segmentation
5. **Handle pagination** - Always check `hasNextPage` and use `endCursor` for complete data
6. **Verify webhook signatures** - Always validate the `Linear-Signature` header

## Security

- **API Key Authentication** - Personal keys scoped to workspace
- **OAuth 2.0** - Secure authorization flow for multi-workspace integrations
- **HTTPS Only** - All API communication encrypted via TLS 1.2+
- **Webhook Signatures** - HMAC-based signature verification
- **Encrypted Storage** - API keys encrypted at rest in Tajo
- **SOC 2 Compliance** - Linear platform is SOC 2 Type II certified

## Related Resources

- [GitHub Connector](https://tajo.io/docs/connectors/custom/github)
- [Jira Connector](https://tajo.io/docs/connectors/custom/jira)
- [Notion Connector](https://tajo.io/docs/connectors/custom/notion)
- [Brevo Contacts API](https://tajo.io/docs/contact-management)

## Open-Source Implementation Map

No official open-source repository was found in the current Tajo connector catalog for Linear. Keep this page focused on the verified public API contract and vendor documentation until an official schema, SDK, MCP server, or public integration repository is available.

### Tajo Revamp Checklist

- Verify authentication and scope requirements against the vendor documentation before each connector release.
- Document primary sync objects, external IDs, pagination strategy, and rate limits explicitly.
- Add smoke tests from public API examples rather than undocumented behavior.
- Capture webhook signature verification and replay protection when the vendor supports webhooks.
- Record gaps where no official public repository or schema exists so future maintainers know what still needs source-backed validation.
