Linear
Sync data from your warehouse to Linear. Zeotap creates and updates issues in your Linear teams, keeping your issue tracker enriched with the latest customer and operational data.
Prerequisites
- A Linear workspace with API access enabled
- A Linear team where issues will be created
- A personal API key or OAuth access token with write permissions
Permissions
The authenticating user (or the OAuth app) must have:
- Write access to the target team to create and update issues
- Read access to query team, project, label, and state metadata
- If assigning issues, the assignee must be a member of the target team
Authentication
Linear uses API key authentication. Each API key is scoped to a single user and inherits that user’s permissions.
Generating an API Key
- Open your Linear workspace
- Navigate to Settings (gear icon) > Account > API
- Click Create Key
- Enter a descriptive label (e.g., “Zeotap Integration”)
- Select the required scopes: Read and Write (or Admin for full access)
- Copy the generated key — it begins with
lin_api_and is only shown once
Configuring in Zeotap
- Navigate to Destinations in the left sidebar
- Click Add Destination and select Linear
- Paste the API Key you generated above
- Click Test Connection to verify
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Team ID | Text | Yes | The UUID of the Linear team where issues will be created or updated. Found in Settings > Teams > [Team Name] > General (the ID in the URL or the “Copy ID” option). |
Supported Operations
Sync Modes
| Mode | Supported |
|---|---|
| Upsert | Yes |
| Insert | Yes |
| Update | Yes |
| Mirror | — |
- Insert: Creates a new issue for every row in the sync.
- Update: Updates existing issues. Each row must include an
idfield containing the Linear issue UUID. - Upsert: Rows with an
idare updated; rows without are created as new issues.
Audience Sync Modes
Linear does not support audience sync modes. Issues are not membership-based entities.
Features
- Field Mapping: Yes — map warehouse columns to Linear issue fields
- Schema Introspection: No — use the default fields list or enter field names manually
Required Mapping Fields
| Field | Description |
|---|---|
| title | The issue title. Required for all new issues. |
Default Destination Fields
| Field | Type | Description |
|---|---|---|
title | string | Issue title |
description | string | Issue description (Markdown formatting supported) |
priority | string | Priority level: 0 (none), 1 (urgent), 2 (high), 3 (medium), 4 (low) |
assigneeId | string | UUID of the user to assign the issue to |
stateId | string | UUID of the workflow state (e.g., Backlog, In Progress, Done) |
labelIds | string | Comma-separated list of label UUIDs to apply |
projectId | string | UUID of the project to associate the issue with |
estimate | string | Point estimate for the issue |
dueDate | string | Due date in YYYY-MM-DD format |
To find UUIDs for states, labels, projects, and users, use the Linear GraphQL API explorer or the Linear UI (right-click an item and select Copy ID).
How It Works
-
Create operations use the Linear GraphQL
issueCreatemutation. Each row is sent as an individual mutation because Linear does not provide a bulk create endpoint. TheteamIdfrom your configuration is automatically included in every create request. -
Update operations use the
issueUpdatemutation with the issue UUID from theidfield in each row. Only the mapped fields are sent in the update — unmapped fields remain unchanged on the issue. -
Upsert operations split rows into creates and updates based on whether the
idfield is present. Rows with a valididare updated; rows without are created. -
Priority values are automatically converted from string to integer. Use
0for no priority,1for urgent,2for high,3for medium, and4for low. -
Label IDs should be provided as a comma-separated string of UUIDs. They are parsed and sent as an array to the GraphQL API.
-
Description fields support full Markdown formatting, including headings, lists, links, and code blocks.
Rate Limits
Linear enforces rate limits on all API requests:
- API Key: 5,000 requests per hour per user
- OAuth App: 5,000 requests per hour per user/app
- Complexity limit: 3,000,000 points per hour (API key) or 2,000,000 points per hour (OAuth)
- Single query maximum: 10,000 complexity points
Linear uses the leaky bucket algorithm, meaning tokens refill at a constant rate. Rate limit errors return HTTP 400 with "code": "RATELIMITED" in the GraphQL error extensions (not HTTP 429).
Zeotap handles rate limiting automatically with exponential backoff and retry. If you encounter persistent rate limit errors, reduce the sync frequency or use an OAuth application for higher limits.
Best Practices
- Use upsert mode when keeping issues in sync — include the Linear issue
idfor rows that already have corresponding issues. - Map
idin your model to enable updates. Without it, upsert mode treats every row as a new issue. - Use UUIDs for all reference fields (assigneeId, stateId, labelIds, projectId). Display names are not accepted by the API.
- Set priority as integers (0–4), not text labels. The API uses numeric priority values.
- Test with a sandbox team before syncing to production teams to verify field mappings and workflow state IDs.
- Use Markdown in descriptions — Linear renders Markdown natively, so you can include rich formatting directly.
Troubleshooting
Authentication failed: invalid API key
Verify that your API key starts with lin_api_ and has not been revoked. API keys are scoped to a single user — if the user’s account is deactivated, the key stops working. Generate a new key in Settings > Account > API.
Team not found or not accessible
Check that the Team ID is a valid UUID. You can find it by navigating to the team in Linear, opening Settings > Teams > [Team Name], and copying the ID from the URL or using the Copy ID option. Verify the authenticating user is a member of the team.
Issue creation fails with validation errors
Ensure the title field is mapped and contains a non-empty value. Linear requires a title for all issues. If you are mapping stateId, verify the state UUID belongs to the target team — workflow states are team-specific.
Assignee field rejected
The assigneeId must be the UUID of a Linear user who is a member of the target team. Display names and email addresses are not accepted. Use the Linear GraphQL API to look up user IDs: { users { nodes { id name email } } }.
Labels not applying
Each label UUID in the labelIds field must belong to the workspace or the target team. Team-specific labels are only valid for issues in that team. Separate multiple UUIDs with commas (no spaces around the separator are required, but are tolerated).
Rate limit errors
Linear rate limit errors appear as GraphQL errors with code RATELIMITED, not as HTTP 429 responses. Zeotap retries automatically with backoff. If you see persistent failures, check that your sync volume fits within the 5,000 requests/hour limit. Consider switching to an OAuth application for higher complexity limits.
Priority values not applying
Priority must be an integer between 0 and 4. String values like “high” or “urgent” are not accepted — use the numeric mapping: 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low.
Due date not setting correctly
The dueDate field must be in YYYY-MM-DD format (e.g., 2025-12-31). Other date formats are not accepted by the Linear API. Ensure your source data is formatted correctly before syncing.