Import from Linear

Bring a Linear team into Orkestra as a project, preserving issues, cycles (called cycles here too), workflow states, labels, priorities and comments. Sub-issues are imported as independent issues with a pointer to the parent via custom field.

What format Orkestra expects

A JSON matching the Linear GraphQL API shape:

{
  "teams":          [{ "id", "key", "name" }],
  "workflowStates": [{ "id", "name", "type", "team": { "id" } }],
  "users":          [{ "id", "email", "name" }],
  "cycles":         [{ "id", "number", "name", "startsAt", "endsAt" }],
  "projects":       [{ "id", "name" }],
  "issues":         [{ "id", "identifier", "title", "state", "assignee", "comments", "labels", "attachments", ... }]
}

GraphQL connections can come as plain arrays or as { nodes: [...] }. Orkestra unwraps them automatically.

How to generate the export

Linear has no native “export as JSON” button. Two working approaches:

  1. Generate an API key in Settings → API on Linear.
  2. Use Apollo Sandbox or any GraphQL client (Postman, Insomnia) pointed at https://api.linear.app/graphql.
  3. Run separate queries per entity (teams, workflowStates, users, cycles, projects, issues). Paginate issues with cursors.
  4. Combine results into a single JSON with the expected keys.

2) Linear SDK + script

Linear ships a TypeScript SDK. A ~50-line script walks the team, issues, cycles and writes the JSON directly. Email us if you want our base script.

What gets imported

  • Teams → the first team becomes an Orkestra Project. Others are ignored with warning.
  • Issues → Tasks. Linear priority (0-4) maps to URGENT/HIGH/MEDIUM/LOW (0 = no priority → MEDIUM).
  • Identifier (e.g. ORK-123) → custom field linear_id.
  • WorkflowStates → WorkflowStates. Type completed → marked as final.
  • Cycles → Cycles. State inferred from dates: endsAt < today → COMPLETED, ongoing → ACTIVE, future → PLANNED.
  • Linear Projects → custom field linear_project_id per issue (Orkestra has no “projects within projects”).
  • Labels → task labels.
  • Assignee → org user matched by email.
  • Sub-issues → imported as independent issues with custom field linear_parent_id pointing at the parent’s Linear ID. Orkestra doesn’t build a native parent-child hierarchy because Task has no parentTaskId.
  • Comments → Comments. If the author isn’t in the org, prefixed with [Imported from Linear — originally by X].
  • Attachments → ExternalLink (title + URL). No binary download.

User mapping

Same as Jira: email match, missing users shown in preview with invite toggle. See the general guide for the full flow.

Out of scope

  • Multiple teams in the same JSON — only the first is imported.
  • Sub-issue parent-child hierarchy — the pointer is stored in linear_parent_id, but no native relation is created and sub-issues don’t become subtasks.
  • Issue relations — “blocks”, “blocked by”, “relates to”, “duplicates” are not imported.
  • Cycle goals and milestones — out of scope.
  • Linear custom fields (estimate, custom views, etc.) — beyond the 3 traceability fields, ignored.
  • Custom emojis — not imported. Previous :emoji: text stays as-is.
  • Binary attachments — only title and URL.
  • Workflow automations / triggers — out of scope.
  • Linear integrations (Slack, GitHub bidirectional sync, Figma) — not migrated; reconfigure them in Orkestra.

Warnings vs silent ignores

The preview surfaces warnings for: multiple teams, missing users, large file. Everything else above is silently ignored.

Steps in Orkestra

  1. Open Import, in the menu, and pick Linear.
  2. Upload the JSON. Wait for the preview.
  3. Review: counts, detected states, missing users, warnings.
  4. (Optional) Override state mapping (rename, mark as completed).
  5. (Optional) Enable invitations.
  6. Execute.

Resources