Skip to main content

Zenhub Epics vs Legacy Epics

The Zenhub application contains two types of epics: Legacy Epics and Zenhub Epics. Legacy Epics are based on GitHub Issues, while Zenhub Epics are exclusive to the Zenhub application and do not require a GitHub account for users. Zenhub Epics are intended to replace Legacy Epics completely.

An organization cannot have both types of epics simultaneously. Legacy Epics are only available to organizations that were created before May 30, 2022, and haven't yet been migrated to Zenhub Epics.

Due to structural differences, these two types of epics have different resources in the GraphQL API. The GraphQL type for Legacy Epics is Epic, while the type for Zenhub Epics is ZenhubEpic. If your organization is not enabled for a particular type of epic, queries or mutations on that type will return empty or result in errors.

Checking the Epic Type Used by Your Organization

To determine whether your organization uses Zenhub or Legacy Epics, open your board and check the sidebar for an "Epics" link. If the "Epics" link is present, your organization is using Zenhub Epics. Otherwise, your organization is using Legacy Epics.

Zenhub sidebar with Epics link

Legacy Epics are marked as deprecated in the GraphQL API. However, if your organization is enabled for Legacy Epics, you must use the deprecated resources.

How to Get Your Workspace ID

Some queries in this guide require a workspace ID. You can find your workspace ID in the URL of your workspace. For example, in the URL https://app.zenhub.com/workspaces/-demo-board-58e6e818b2c8573a4fa86b6b, the workspace ID is 58e6e818b2c8573a4fa86b6b.

Zenhub Epics Queries and Mutations

Create a Zenhub Epic

Use the createZenhubEpic mutation to create a Zenhub Epic:

mutation createZenhubEpic($zenhubRepositoryId: ID!, $zenhubOrganizationId: ID!, $title: String!, $body: String) {
	createZenhubEpic(input: {
    zenhubRepositoryId: $zenhubRepositoryId,
    zenhubOrganizationId: $zenhubOrganizationId,
    zenhubEpic:{
      title: $title,
      body: $body
    }
  }) {
    zenhubEpic {
      id
    }
  }
}

Note: The zenhubRepositoryId argument is optional at the moment, but it will be required starting on October 1st, 2023, so it is highly recommended that you start sending it now. See Article for more details.

You can obtain the Zenhub Repository ID and the Zenhub Organization ID from your workspace with the following query:

query zenhubRepositoryandOrganization($workspaceId: ID!) {
  workspace(id: $workspaceId) {
    zenhubRepository {
      id
    }
    zenhubOrganization {
      id
    }
  }
}

List All Zenhub Epics of a Workspace

To list all Zenhub Epics of a workspace, use the following query:

query zenhubEpicsFromWorkspace($workspaceId: ID!) {
  workspace(id: $workspaceId) {
  	zenhubEpics {
      nodes {
        id
        title
      }
    }
  }
}

This query requires a workspace ID. You can obtain your workspace ID by following the instructions in How to Get Your Workspace ID.

This query can also be used to retrieve the ID of a specific epic by its title. To do so, pass the query argument:

query zenhubEpicsFromWorkspace($workspaceId: ID!, $query: String) {
  workspace(id: $workspaceId) {
  	zenhubEpics(query: $query) {
      nodes {
        id
        title
      }
    }
  }
}

Get Zenhub Epic by ID

You can retrieve a Zenhub Epic by its ID using the node query:

query zenhubEpicById($zenhubEpicId: ID!) {
  node(id: $zenhubEpicId) {
    ... on ZenhubEpic {
      title
    }
  }
}

Update a Zenhub Epic

To update a Zenhub Epic, use the following mutation. Obtain your Zenhub Epic ID using the query described in List All Zenhub Epics of a workspace.

mutation updateZenhubEpic($zenhubEpicId: ID!, $title: String, $body:String) {
  updateZenhubEpic(input:{
    zenhubEpicId: $zenhubEpicId,
    title: $title,
    body:$body
  }) {
    zenhubEpic {
      title
    }
  }
}

Get All Issues from a Zenhub Epic

The issues belonging to a Zenhub Epic can be retrieved using the childIssues field of the ZenhubEpic:

query zenhubEpicIssues($zenhubEpicId: ID!, $workspaceId: ID!) {
  node(id: $zenhubEpicId) {
    ... on ZenhubEpic {
      childIssues(workspaceId: $workspaceId) {
        nodes {
          id
          title
        }
      }
    }
  }
}

You can obtain your Zenhub Epic ID using the query described in List All Zenhub Epics of a Workspace, and your workspace ID by following the instructions in How to Get Your workspace ID.

Add Issues to Zenhub Epics

To add issues to Zenhub Epics, use the following mutation:

mutation addIssuesToZenhubEpic($epicIds: [ID!]!, $issueIds: [ID!]!) {
  addIssuesToZenhubEpics(input: {
    zenhubEpicIds: $epicIds,
    issueIds: $issueIds
  }) {
    zenhubEpics {
      id
    }
  }
}

Remove Issues from Zenhub Epics

To remove issues from Zenhub Epics, use the following mutation:

mutation removeIssuesFromZenhubEpics($epicIds: [ID!]!, $issueIds: [ID!]!) {
  removeIssuesFromZenhubEpics(input: {
    zenhubEpicIds: $epicIds,
    issueIds: $issueIds
  }) {
    zenhubEpics {
      id
    }
  }
}

Update Zenhub Epic Dates

To change Zenhub Epic dates, use the following mutation:

mutation updateZenhubEpicDates($zenhubEpicId: ID!, $startOn: ISO8601Date!, $endOn: ISO8601Date!) {
  updateZenhubEpicDates(input: {
    zenhubEpicId: $zenhubEpicId,
    startOn:$startOn,
    endOn: $endOn,
  }) {
    zenhubEpic {
      id
      startOn
      endOn
    }
  }
}

Legacy Epics Queries and Mutations

Create a Legacy Epic

The createEpic mutation is used to create a Legacy Epic:

mutation createEpic($repositoryId: ID!, $title: String!, $body: String) {
  createEpic(input: {
    issue: {
      repositoryId: $repositoryId,
      title: $title,
      body: $body,
    }
  }) {
    epic {
      id
    }
  }
}

You can obtain the repository ID by checking the connected repositories in your workspace with the query:

query repositoryIds($workspaceId: ID!) {
  workspace(id: $workspaceId) {
  	repositoriesConnection {
      nodes {
        name
        id
      }
    }
  }
}

This query requires a workspace ID. You can obtain your workspace ID by following the instructions in How to Get Your Workspace ID.

List All Legacy Epics of a Workspace

To list all legacy epics of a workspace, use the followin query:

query epicsFromWorkspace($workspaceId: ID!) {
  workspace(id: $workspaceId) {
  	epics {
      nodes {
        id
        issue {
          title
        }
      }
    }
  }
}

This query can also be used when you want to know the ID of a specific epic by its title. To do that, you can pass the query argument:

query epicsFromWorkspace($workspaceId: ID!, $query: String!) {
  workspace(id: $workspaceId) {
  	epics(query: $query) {
      nodes {
        id
        issue {
          title
        }
      }
    }
  }
}

Get Legacy Epic by ID

You can get a Legacy Epic by its ID using the node query:

query epicById($epicId: ID!) {
  node(id: $epicId) {
    ... on Epic {
      issue {
        title
      }
    }
  }
}

Update a Legacy Epic

To update a Legacy Epic, you need to update its inner issue. First, get the issue ID using the Get Legacy Epic By ID query. Then, use the updateIssue mutation to update the epic:

mutation updateEpic($issueId: ID!, $title: String!, $body: String) {
  updateIssue(input: {
    issueId: $issueId,
    title:$title,
    body: $body
  }) {
    issue {
      id
    }
  }
}

Get All Issues From a Legacy Epic

The issues belonging to a Legacy Epic can be retrieved using the childIssues field of the Epic:

query epicIssues($epicId: ID!) {
  node(id: $epicId) {
    ... on Epic {
      childIssues {
        nodes {
          id
          title
        }
      }
    }
  }
}

Add Issues to Legacy Epics

To add issues to Legacy Epics, use the following mutation:

mutation addIssuesToEpic($epicIds: [ID!]!, $issueIds: [ID!]!) {
  addIssuesToEpics(input: {
    epicIds: $epicIds,
    issueIds: $issueIds
  }) {
    epics {
      id
    }
  }
}

Remove issues from Legacy Epics

To remove issues from Legacy Epics, use the following mutation:

mutation removeIssuesFromEpic($epicIds: [ID!]!, $issueIds: [ID!]!) {
  removeIssuesFromEpics(input: {
    epicIds: $epicIds,
    issueIds: $issueIds
  }) {
    epics {
      id
    }
  }
}

Update Legacy Epic dates

To change Legacy Epic dates, use the following mutation:

mutation updateEpicDates($epicId: ID!, $startOn: ISO8601Date!, $endOn: ISO8601Date!) {
  updateEpicDates(input: {
    epicId: $epicId,
    startOn:$startOn,
    endOn: $endOn,
  }) {
    epic {
      id
      startOn
      endOn
    }
  }
}