Linear

Create and sync Linear issues from Nebutra events — quota exceeded, errors, and deployment failures.

Overview

The Linear integration lets you automatically create and update Linear issues when things happen in your Nebutra organization:

  • Create a bug report when a Sentry error is captured
  • Create a task when a tenant exceeds their quota
  • Sync deployment status to a Linear project

Step 1: Get a Linear API key

  1. Go to Linear → Settings → API → Create Key
  2. Name it "Nebutra Integration"
  3. Copy the API key

Step 2: Configure environment variables

LINEAR_API_KEY=lin_api_xxxxxxxxxxxxxxxxxxxx
LINEAR_TEAM_ID=your_team_id         # From Linear → Settings → Teams
LINEAR_PROJECT_ID=your_project_id   # Optional: default project for issues

Step 3: Register the integration

In Settings → Integrations → Linear → Connect, or via API:

await nebutra.integrations.linear.configure({
  orgId: "org_123",
  teamId: process.env.LINEAR_TEAM_ID!,
  projectId: process.env.LINEAR_PROJECT_ID,
  events: ["quota.exceeded", "deployment.failed"],
});

Step 4: Create issues programmatically

import { LinearClient } from "@linear/sdk";

const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY! });

// Create an issue when quota is exceeded
async function handleQuotaExceeded(event: QuotaExceededEvent) {
  await linear.createIssue({
    teamId: process.env.LINEAR_TEAM_ID!,
    title: `Quota exceeded: ${event.orgName} (${event.metric})`,
    description: [
      `**Organization:** ${event.orgName}`,
      `**Metric:** ${event.metric}`,
      `**Limit:** ${event.limit}`,
      `**Used:** ${event.used}`,
      `**Plan:** ${event.plan}`,
      "",
      `This tenant has exceeded their ${event.metric} quota.`,
      `Consider reaching out to offer an upgrade.`,
    ].join("\n"),
    priority: 2, // High
    labelIds: ["label_quota_exceeded"],
  });
}

Webhook handler

import crypto from "crypto";

export async function POST(req: Request) {
  const body = await req.text();
  const sig = req.headers.get("linear-signature");

  // Verify Linear signature
  const hash = crypto
    .createHmac("sha256", process.env.LINEAR_WEBHOOK_SECRET!)
    .update(body)
    .digest("hex");

  if (sig !== hash) {
    return new Response("Invalid signature", { status: 400 });
  }

  const payload = JSON.parse(body);

  // Handle issue status changes — update Nebutra state
  if (payload.type === "Issue" && payload.action === "update") {
    if (payload.data.state?.name === "Done") {
      await handleIssueClosed(payload.data);
    }
  }

  return new Response("OK", { status: 200 });
}

Common automation patterns

TriggerLinear action
quota.exceededCreate high-priority issue → assign to success team
error.spikeCreate bug report → link to Sentry event
member.joined (enterprise)Create onboarding checklist issue
invoice.payment_failedCreate issue → assign to billing team

How is this guide?

Edit on GitHub

Last updated on

On this page