This workflow corresponds to n8n.io template #2154 — we link there as the canonical source.
This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"id": "8920dc6e-b2fb-4446-8cb3-f3f6d626dcb3",
"name": "Linear Trigger",
"type": "n8n-nodes-base.linearTrigger",
"position": [
420,
360
],
"parameters": {
"teamId": "7a330c36-4b39-4bf1-922e-b4ceeb91850a",
"resources": [
"issue"
],
"authentication": "oAuth2"
},
"credentials": {
"linearOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "61214884-62f9-4a00-9517-e2d51b44d0ae",
"name": "Only tickets that need to be classified",
"type": "n8n-nodes-base.filter",
"position": [
1000,
360
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bc3a756d-b2b6-407b-91c9-a1cd9da004e0",
"operator": {
"type": "string",
"operation": "notContains"
},
"leftValue": "={{ $('Linear Trigger').item.json.data.description }}",
"rightValue": "Add a description here"
},
{
"id": "f3d8d0fc-332d-41a6-aef8-1f221bf30c0e",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Linear Trigger').item.json.data.state.id }}",
"rightValue": "6b9a8eec-82dc-453a-878b-50f4c98d3e53"
},
{
"id": "9cdb55b2-3ca9-43bd-84b0-ef025b59ce18",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $('Linear Trigger').item.json.data.labels.filter(label => label.id === 'f2b6e3e9-b42d-4106-821c-6a08dcb489a9').length }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "da4d8e0c-895b-4a84-8319-438f971af403",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1000,
111.31510859283728
],
"parameters": {
"color": 7,
"height": 219.68489140716272,
"content": "### When does this fire?\nIn our setup we have a general team in Linear where we post new tickets to. Additionally, the bug needs to have a certain label and the description needs to be filled. \nYou're of course free to adjust this to your needs\n\ud83d\udc47"
},
"typeVersion": 1
},
{
"id": "b7e3a328-96c4-4082-93a9-0cb331367190",
"name": "Update team",
"type": "n8n-nodes-base.linear",
"position": [
2160,
280
],
"parameters": {
"issueId": "={{ $('Linear Trigger').item.json.data.id }}",
"operation": "update",
"updateFields": {
"teamId": "={{ $json.teamId }}"
}
},
"credentials": {
"linearApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "858764ce-cd24-4399-88ce-cf69e676beaa",
"name": "Get all linear teams",
"type": "n8n-nodes-base.httpRequest",
"position": [
1300,
540
],
"parameters": {
"url": "https://api.linear.app/graphql",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "query",
"value": "{ teams { nodes { id name } } }"
}
]
},
"nodeCredentialType": "linearOAuth2Api"
},
"credentials": {
"linearOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "167f0c66-5bfb-4dd7-a345-81f4d62df2c4",
"name": "Set team ID",
"type": "n8n-nodes-base.set",
"position": [
2000,
280
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a46c4476-b851-4112-ac72-e805308c5ab7",
"name": "teamId",
"type": "string",
"value": "={{ $('Get all linear teams').first().json.data.teams.nodes.find(team => team.name === $json.message.content).id }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "36363240-2b03-4af8-8987-0db95094403b",
"name": "Set me up",
"type": "n8n-nodes-base.set",
"position": [
700,
360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a56f24c8-0a28-4dd2-885a-cb6a081a5bf4",
"name": "teams",
"type": "string",
"value": "- [Adore][Is responsible for every persona that is not Enterprise. This includes signup journeys, trials, n8n Cloud, the Canvas building experience and more, the nodes detail view (NDV), the nodes panel, the workflows list and the executions view] \n- [Payday][Is responsible for the Enterprise persona. This includes making sure n8n is performant, the enterprise features SSO, LDAP, SAML, Log streaming, environments, queue mode, version control, external storage. Additionally the team looks out for the execution logic in n8n and how branching works] \n- [Nodes][This team is responsible for everything that is related to a specific node in n8n] \n- [Other][This is a placeholder if you don't know to which team something belongs]"
},
{
"id": "d672cb59-72be-4fc8-9327-2623795f225d",
"name": "slackChannel",
"type": "string",
"value": "#yourChannelName"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "49f2a157-b037-46d9-a6d7-97f8a72ee093",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
581.3284642016245,
85.15358950105212
],
"parameters": {
"color": 5,
"width": 349.85308830334156,
"height": 439.62604295396085,
"content": "## Setup\n1. Add your Linear and OpenAi credentials\n2. Change the team in the `Linear Trigger` to match your needs\n3. Customize your teams and their areas of responsibility in the `Set me up` node. Please use the format `[Teamname][Description/Areas of responsibility]`. Also make sure that the teamnames match the names in Linear exactly.\n4. Change the Slack channel in the `Set me up` node to your Slack channel of choice."
},
"typeVersion": 1
},
{
"id": "8cdb3d0d-4fd3-4ea2-957f-daf746934728",
"name": "Check if AI was able to find a team",
"type": "n8n-nodes-base.if",
"position": [
1780,
380
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "86bfb688-3ecc-4360-b83a-d706bb11c8f9",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.message.content }}",
"rightValue": "Other"
}
]
}
},
"typeVersion": 2
},
{
"id": "a4cb20ca-658a-4b30-9185-5af9a32a7e20",
"name": "Notify in Slack",
"type": "n8n-nodes-base.slack",
"position": [
2000,
460
],
"parameters": {
"text": "The AI was not able to identify a fitting team for a bug",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "={{ $('Set me up').first().json.slackChannel }}"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "393b2392-80be-4a68-9240-dc1065e0081a",
"name": "Merge data",
"type": "n8n-nodes-base.merge",
"position": [
1600,
380
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 2.1
},
{
"id": "f25da511-b255-4a53-ba4e-5765916e90be",
"name": "OpenAI",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1220,
360
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4-32k-0314",
"cachedResultName": "GPT-4-32K-0314"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "I need you to classify a bug ticket and tell me which team should work on it"
},
{
"role": "system",
"content": "All possible teams will be described in the following format: [Teamname][Areas of responsibility] "
},
{
"role": "system",
"content": "=The possible teams are the following:\n {{ $('Set me up').first().json.teams }}"
},
{
"role": "system",
"content": "=This is the bug that we're trying to classify:\nTitle: {{ $('Linear Trigger').first().json.data.title }}\nDescription: {{ $('Linear Trigger').first().json.data.description }}"
},
{
"content": "Which team should work on this bug?"
},
{
"role": "system",
"content": "Do not respond with anything else than the name of the team from the list you were given"
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"connections": {
"OpenAI": {
"main": [
[
{
"node": "Merge data",
"type": "main",
"index": 0
}
]
]
},
"Set me up": {
"main": [
[
{
"node": "Only tickets that need to be classified",
"type": "main",
"index": 0
}
]
]
},
"Merge data": {
"main": [
[
{
"node": "Check if AI was able to find a team",
"type": "main",
"index": 0
}
]
]
},
"Set team ID": {
"main": [
[
{
"node": "Update team",
"type": "main",
"index": 0
}
]
]
},
"Linear Trigger": {
"main": [
[
{
"node": "Set me up",
"type": "main",
"index": 0
}
]
]
},
"Get all linear teams": {
"main": [
[
{
"node": "Merge data",
"type": "main",
"index": 1
}
]
]
},
"Check if AI was able to find a team": {
"main": [
[
{
"node": "Set team ID",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify in Slack",
"type": "main",
"index": 0
}
]
]
},
"Only tickets that need to be classified": {
"main": [
[
{
"node": "OpenAI",
"type": "main",
"index": 0
},
{
"node": "Get all linear teams",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
linearApilinearOAuth2ApiopenAiApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
When working with multiple teams, bugs must get in front of the right team as quickly as possible to be resolved. Normally this includes a manual grooming of new bugs that have arrived in your ticketing system (in our case Linear). We found this way too time-consuming. That's…
Source: https://n8n.io/workflows/2154/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Classify New Bugs In Linear With Openai S Gpt 4 And Move Them To The Right Team. Uses linearTrigger, stickyNote, linear, httpRequest. Event-driven trigger; 12 nodes.
Domain Outbound Machine is an n8n workflow designed to fully automate the domain sales process: lead generation, email extraction, personalized outreach, and automated email sending. It also stores ex
Social Media Audio Extractor. Uses telegramTrigger, telegram, openAi, httpRequest. Event-driven trigger; 31 nodes.
Baby Chaganti. Uses httpRequest, googleDrive, youTube, openAi. Event-driven trigger; 23 nodes.
Monitor YouTube channels, fetch stats, classify videos as viral (≥ 1000 likes) or normal, and auto‑generate LinkedIn/email summaries with GPT‑4. Deliver via Gmail or SMTP. Clear node names, examples,