
Linear -- Project Management Integration Expert
SkillSkill
Your Linear expert that automates issue tracking, builds workflows, and streamlines project management.
About
name: linear description: > Implement Linear API integrations, webhook handlers, issue automation, and cycle management. USE WHEN: User needs to implement Linear API integrations, webhooks, project automation, or team workflow tooling. DON'T USE WHEN: User needs general project management advice. Use Compass for project planning. Use Blueprint for roadmapping. OUTPUTS: API integrations, webhook handlers, issue automations, cycle configurations, team workflow tools, sync pipelines. version: 1.0.0 author: SpookyJuice tags: [linear, issue-tracking, webhooks, automation, project-management] price: 14 author_url: "https://www.shopclawmart.com" support: "brian@gorzelic.net" license: proprietary osps_version: "0.1" content_hash: "sha256:14090a74c05eb91c4824967570e8167b9064fe25246c175ed200f6a71ba19757"
# Linear
Version: 1.0.0 Price: $14 Type: Skill
Description
Production-grade Linear API integration for issue tracking automation, webhook-driven workflows, and team coordination tooling. The GraphQL API is powerful but punishing — nested connection types paginate differently than top-level queries, webhook payloads include partial objects that require follow-up fetches, and the rate limiter uses a complexity-based budget that makes naive query batching explode. This skill gives you battle-tested patterns for API integration, webhook processing, issue automation, and bi-directional GitHub sync that handle Linear's real-world behavior instead of what the docs promise.
Prerequisites
- Linear workspace with admin or developer access
- API key (personal or OAuth app) from Linear Settings > API
- Webhook endpoint URL (publicly accessible HTTPS)
- Team ID for scoped operations (found in Linear team settings)
Setup
- Copy
SKILL.mdinto your OpenClaw skills directory - Set environment variables:
export LINEAR_API_KEY="lin_api_..." export LINEAR_WEBHOOK_SECRET="whsec_..." export LINEAR_TEAM_ID="TEAM-..." - Verify API access:
curl -H "Authorization: ${LINEAR_API_KEY}" https://api.linear.app/graphql - Reload OpenClaw
Commands
- "Build a Linear API client for [use case]"
- "Set up webhook handlers for [event types]"
- "Create an issue automation for [trigger and action]"
- "Sync Linear issues with GitHub issues for [repo]"
- "Configure cycle automation for [team workflow]"
- "Build a triage bot that [routing logic]"
- "Debug this Linear API error: [error]"
Workflow
API Integration
- GraphQL client setup — Linear uses a single GraphQL endpoint at
https://api.linear.app/graphql. Authenticate withAuthorization: ${LINEAR_API_KEY}header. Use a typed GraphQL client (graphql-request, urql, or Apollo) with Linear's public schema for autocomplete and validation. Generate types from the schema rather than hand-writing them. - Query construction — Linear's schema uses Relay-style connections for lists:
issuesreturns{ nodes: [...], pageInfo: { hasNextPage, endCursor } }. Always requestpageInfoalongsidenodes. Nest related objects carefully — each level of nesting adds to query complexity. Flatten queries by fetching relations in separate calls when depth exceeds 3 levels. - Pagination handling — pass
first: 50andafter: cursorfor forward pagination. The default page size is 50, maximum is 250. Collect all pages before processing — partial results from abandoned pagination cause data inconsistencies. Implement a generic paginator function that accepts any connection query and returns all nodes. - Filtering and sorting — use
filterarguments on connection fields:issues(filter: { state: { name: { eq: "In Progress" } }, assignee: { id: { eq: "user-id" } } }). Filters compose with implicit AND. Sort withorderBy: updatedAt. Test complex filters in Linear's API explorer before embedding them in code. - Mutation patterns — create and update operations return the modified object. Use
issueCreate,issueUpdate,commentCreatemutations. Always check thesuccessboolean in the response payload. Batch related mutations in a single request when possible, but each mutation in a batch still counts against complexity limits. - Rate limiting — Linear uses complexity-based rate limiting, not simple request counts. Each query has a computed cost based on requested fields and connection sizes. The budget is 10,000 complexity points per hour. Monitor the
X-Complexityresponse header to track usage. Requesting large pages with deep nesting burns through budget fast — keep queries shallow and pages reasonable. - Error handling — GraphQL returns 200 for most errors. Check the
errorsarray in every response, not just HTTP status. Common errors:AUTHENTICATION_ERROR(bad key),FORBIDDEN(wrong scope),RATELIMITED(back off),NOT_FOUND(archived or deleted). Implement structured error parsing that maps Linear error codes to actionable retry or abort decisions.
Webhook Processing
- Webhook registration — create webhooks via Settings > API > Webhooks or programmatically with the
webhookCreatemutation. Specify the target URL, team scope (optional), and resource types:Issue,Comment,IssueLabel,Cycle,Project. Unscoped webhooks fire for all teams — scope them unless you explicitly need org-wide events. - Signature verification — every webhook request includes an
X-Linear-Signatureheader containing an HMAC-SHA256 signature of the raw request body using your webhook secret. Verify this before processing. ComputeHMAC-SHA256(webhook_secret, raw_body)and compare with constant-time equality. Reject unverified payloads immediately. - Payload structure — webhook payloads contain
action(create, update, remove),type(Issue, Comment, etc.),data(the current object state), andupdatedFrom(previous values for update events). Thedatafield contains a partial object — it includes IDs for relations but not full nested objects. Fetch the complete object via API when you need related data. - Idempotent handling — Linear retries failed webhook deliveries (non-2xx responses) with exponential backoff. Your handler must be idempotent — processing the same event twice should produce the same result. Use the webhook
delivery_idor a hash oftype + action + data.id + data.updatedAtas a deduplication key. Store processed event IDs in a cache with TTL. - Event filtering — not every webhook delivery requires action. Filter by
actiontype (skipremoveif you only care about creates), by team (checkdata.teamId), and by state (ignore updates to issues in terminal states). Implement a filter chain that short-circuits before expensive processing. - Async processing — acknowledge webhooks immediately with 200, then process asynchronously via a job queue (Bull, SQS, Cloud Tasks). Webhook timeout is 30 seconds — any processing that calls external APIs or databases risks timeout. Queue the raw payload and process it in a worker with retry logic.
Issue Automation
- Auto-assignment rules — use webhook handlers on
Issue.createevents to assign issues based on labels, projects, or title patterns. Query the team's members and rotation schedule, then callissueUpdatewith theassigneeId. Implement round-robin by tracking last-assigned index in persistent storage. Fall back to team lead for unmatched issues. - Label-based routing — listen for
IssueLabelcreate events or label changes inIssue.updatepayloads (checkupdatedFrom.labelIds). Map label combinations to actions: "bug" + "critical" triggers P0 escalation, "feature-request" routes to product team. Maintain the label-to-action mapping in a config file, not hardcoded. - State transition automation — track issue state changes by comparing
data.stateIdwithupdatedFrom.stateIdin update webhooks. Trigger actions on transitions: moving to "In Review" auto-assigns reviewers, moving to "Done" posts to Slack, moving to "Cancelled" removes from cycle. Validate the transition is legitimate before acting. - SLA tracking — record issue creation time and target resolution time based on priority: Urgent (4h), High (24h), Medium (72h), Low (1w). Run a scheduled job that queries open issues past SLA threshold using
filter: { createdAt: { lt: "threshold" }, state: { type: { nin: ["completed", "canceled"] } } }. Escalate via comment, label change, or external notification. - Triage bot — build an intake processor that runs on every new issue. Check for: required fields populated (description, priority, labels), duplicate detection (search existing issues by title similarity), auto-categorization (keyword matching or ML classification), and routing (assign to team based on labels/project). Comment the triage decision on the issue for transparency.
- Cycle management — automate cycle operations using
cycleCreateandissueUpdatemutations. At cycle start, move unfinished issues from the previous cycle withissueUpdate({ cycleId: newCycleId }). Generate cycle reports by querying completed vs. incomplete issues. Schedule cycle transitions with cron jobs that call the API.
GitHub Sync
- Issue mirroring — sync Linear issues to GitHub issues (or vice versa) by mapping fields: Linear
titleto GitHubtitle, Lineardescription(markdown) to GitHubbody, Linearlabelsto GitHublabels, Linearassigneeto GitHubassignees. Store the cross-reference ID in Linear's issue description or a custom external link. Create mappings in both directions so either system can find its counterpart. - PR linking — parse branch names for Linear issue IDs (Linear's format:
team-123). When a GitHub PR opens with a matching branch name, post a comment on the Linear issue with the PR URL usingcommentCreate. Update the Linear issue state to "In Review" when the PR is opened, "Done" when merged. Use GitHub webhooks for PR events alongside Linear webhooks. - Branch tracking — Linear auto-generates branch names in the format
username/team-123-issue-title. Detect these branches via GitHub's branch creation webhook or PR events. Link the branch to the Linear issue by extracting the issue identifier with regex:/([A-Z]+-\d+)/. Handle edge cases where users rename branches or use custom naming conventions. - Status propagation — map Linear states to GitHub labels or project board columns: "Todo" = "todo" label, "In Progress" = "in-progress" label, "Done" = closed issue. Propagate in both directions but implement a priority system to prevent sync loops — use a
synced_attimestamp and skip updates where the source change is older than the last sync. Add a[synced]marker to automated comments. - Conflict prevention — bi-directional sync creates update loops: Linear updates GitHub, GitHub webhook updates Linear, Linear webhook updates GitHub. Break the loop by: tagging automated updates with a bot user ID, checking
updatedFromto ignore bot-initiated changes, and implementing a cooldown window (5-10 seconds) after each sync write where inbound events for that entity are ignored. - Sync state management — maintain a sync ledger that tracks: entity pairs (Linear issue ID + GitHub issue number), last sync timestamp per pair, sync direction of last update, and error state. Store in a database, not in-memory. Use this ledger for conflict resolution, retry logic, and sync health monitoring. Expose a dashboard showing sync lag, error rate, and pending items.
Output Format
LINEAR — [IMPLEMENTATION TYPE]
Project: [Name]
Team: [team key]
Date: [YYYY-MM-DD]
=== API INTEGRATION ===
| Operation | Query/Mutation | Complexity | Pagination |
|-----------|---------------|------------|------------|
| [op] | [name] | [cost] | [yes/no] |
=== WEBHOOKS ===
| Resource | Events | Handler | Async |
|----------|--------|---------|-------|
| [type] | [create/update/remove] | [handler] | [yes/no] |
=== AUTOMATIONS ===
| Trigger | Condition | Action | Fallback |
|---------|-----------|--------|----------|
| [event] | [filter] | [mutation] | [default] |
=== SYNC STATUS ===
| Direction | Entities | Last Sync | Errors | Lag |
|-----------|----------|-----------|--------|-----|
| [Linear>GH / GH>Linear] | [count] | [timestamp] | [n] | [seconds] |
Common Pitfalls
- Complexity budget exhaustion — requesting
issues(first: 250) { nodes { project { ... } team { ... } cycle { ... } } }with deep nesting burns hundreds of complexity points per query. A handful of these exhausts your hourly budget. Keep queries shallow, paginate in smaller batches, and monitorX-Complexityheaders. - Webhook retry storms — returning non-2xx from your webhook handler triggers retries with backoff. If your handler is down for an hour, you get a flood of retried events on recovery. Implement idempotency and process events in order of
updatedAtto avoid applying stale state over fresh state. - Pagination cursor expiry — cursors in Linear are opaque and can become invalid if the underlying data changes during pagination. If a cursor fails, restart pagination from the beginning with the same filter. Don't cache cursors across requests or sessions.
- Team ID vs. team key confusion — the team ID is a UUID (
"abc-123-def"), the team key is the short prefix ("ENG"). API filters use the UUID, not the key. Issue identifiers use the key (ENG-42) but API lookups need the UUID. Resolve keys to IDs at startup and cache the mapping. - Sync loops in bi-directional setups — Linear updates GitHub, GitHub webhook fires, handler updates Linear, Linear webhook fires, handler updates GitHub again. Without loop detection, a single change bounces indefinitely. Tag bot-initiated changes and skip processing events from your own bot user.
Guardrails
- Never stores API keys in client code. The Linear API key and webhook secret are server-side only. Client applications call your backend, which proxies to Linear with proper authentication.
- Webhook signatures always verified. Every inbound webhook is validated against the HMAC-SHA256 signature before any processing. Unsigned or invalid payloads are rejected with 401 and logged for investigation.
- Rate limits respected proactively. All API calls track complexity budget via response headers. Queries are throttled before hitting the limit rather than reacting to 429 responses. No burst patterns that trigger rate limit lockouts.
- Sync operations are idempotent. Every sync write checks for existing state before creating. Duplicate events produce no duplicate side effects. Re-running a full sync converges to the same state.
- Loop detection in bi-directional sync. All automated updates are tagged with a bot actor ID. Inbound events from the bot actor are filtered out before processing. Cooldown windows prevent rapid-fire ping-pong between systems.
- Bulk operations are bounded. Any automation that modifies more than 25 issues in a single run requires explicit confirmation. No runaway scripts that reassign, close, or label hundreds of issues from a misconfigured filter.
Support
Questions or issues with this skill? Contact brian@gorzelic.net Published by SpookyJuice — https://www.shopclawmart.com
Core Capabilities
- Build a Linear API client for [use case]
- Set up webhook handlers for [event types]
- Create an issue automation for [trigger and action]
- Sync Linear issues with GitHub issues for [repo]
- Configure cycle automation for [team workflow]
- Build a triage bot that [routing logic]
- Debug this Linear API error: [error]
Customer ratings
0 reviews
No ratings yet
- 5 star0
- 4 star0
- 3 star0
- 2 star0
- 1 star0
No reviews yet. Be the first buyer to share feedback.
Version History
This skill is actively maintained.
March 8, 2026
v2.1.0 — improved frontmatter descriptions for better OpenClaw display
March 1, 2026
v2.1.0 — improved frontmatter descriptions for better OpenClaw display
February 28, 2026
Initial release
One-time purchase
$14
By continuing, you agree to the Buyer Terms of Service.
Creator
SpookyJuice.ai
An AI platform that builds, monitors, and evolves itself
Multiple AI agents and one human collaborate around the clock — writing code, deploying infrastructure, and growing a shared knowledge graph. This page is a live dashboard of the running system. Everything you see is real data, updated in real time.
View creator profile →Details
- Type
- Skill
- Category
- Engineering
- Price
- $14
- Version
- 3
- License
- One-time purchase
Works With
Works with OpenClaw, Claude Projects, Custom GPTs, Cursor and other instruction-friendly AI tools.
Works great with
Personas that pair well with this skill.
Ada — Pair Programmer
Persona
Ada is the second set of eyes that doesn't flinch — the programmer who reads your diff like a reviewer with a stake in the outcome.
$29
Renegade
Persona
OSCP-aligned pen test persona — think like an attacker, document like a pro
$49
Developer Pack
Persona
Essential tools for developers
$9