An engineering lead told me his team spent 2 hours every Monday manually creating sprint issues from a spreadsheet. He wrote a 50-line script with Linear's API — now it takes 0 seconds and happens automatically every Monday at 9 AM.
What Linear Offers for Free
Linear free tier:
- Unlimited members and unlimited issues
- GraphQL API with full access
- Webhooks for real-time notifications
- GitHub, GitLab, Slack integrations
- Cycles (sprints) and projects
- Custom views and filters
- OAuth for third-party apps
Quick Start
# Get your API key from Linear > Settings > API
export LINEAR_API_KEY='lin_api_YOUR_KEY'
# Test the connection
curl 'https://api.linear.app/graphql' \
-H 'Authorization: lin_api_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"query": "{ viewer { id name email } }"}'
GraphQL Queries
const { LinearClient } = require('@linear/sdk');
const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY });
// Get all teams
const teams = await linear.teams();
teams.nodes.forEach(t => console.log(`${t.name}: ${t.key}`));
// Get issues assigned to me
const me = await linear.viewer;
const myIssues = await me.assignedIssues({
filter: { state: { type: { in: ['started', 'unstarted'] } } },
orderBy: LinearDocument.PaginationOrderBy.Priority
});
myIssues.nodes.forEach(issue => {
console.log(`[${issue.identifier}] ${issue.title} — ${issue.state?.name}`);
});
Create Issues Programmatically
// Create a single issue
const issue = await linear.createIssue({
teamId: 'TEAM_ID',
title: 'Implement user onboarding flow',
description: 'Build the 3-step onboarding wizard as per the Figma mockup',
priority: 2, // 1=Urgent, 2=High, 3=Medium, 4=Low
labelIds: ['LABEL_ID'],
assigneeId: 'USER_ID'
});
console.log(`Created: ${issue.issue?.identifier}`);
// Bulk create from template
const sprintTasks = [
{ title: 'API endpoints for user profile', priority: 2 },
{ title: 'Unit tests for auth module', priority: 3 },
{ title: 'Update API documentation', priority: 4 },
{ title: 'Performance testing', priority: 3 }
];
for (const task of sprintTasks) {
await linear.createIssue({ teamId: 'TEAM_ID', ...task });
}
Automate Sprint Creation
// Create a new cycle (sprint) with issues
async function createSprint(teamId, name, issues) {
// Create cycle
const cycle = await linear.createCycle({
teamId,
name,
startsAt: new Date(),
endsAt: new Date(Date.now() + 14 * 86400000) // 2 weeks
});
// Add issues to cycle
for (const issueData of issues) {
const issue = await linear.createIssue({
teamId,
cycleId: cycle.cycle?.id,
...issueData
});
}
return cycle;
}
Webhooks
// Set up webhook to get notified of changes
const express = require('express');
const app = express();
app.post('/linear-webhook', express.json(), (req, res) => {
const { action, type, data } = req.body;
if (type === 'Issue' && action === 'update') {
if (data.state?.name === 'Done') {
// Issue completed — trigger deployment, notify Slack, etc.
console.log(`Issue ${data.identifier} completed!`);
}
}
res.sendStatus(200);
});
Useful Automations
- Auto-create issues from GitHub PRs — when PR opened, create Linear issue
- Sprint reports — query cycle issues, generate Slack summary
- Bug triage — auto-assign based on labels and priority
- Standup bot — pull yesterday's completed + today's in-progress
- SLA tracking — alert if high-priority issues stale > 24h
Need to track scraping project tasks? Check out my web scraping actors on Apify — managed scraping with monitoring.
Need custom project automation? Email me at spinov001@gmail.com.
Top comments (0)