Zenhub's New Public API

Hey Zenhub Community!

I’m excited to share with you that our new Public GraphQL API is now generally available to all Zenhub users! Our new API provides access to a broader set of data that was not previously available, including sprints, roadmap data and the ability to filter when fetching issues.

To get started, head over to our newly launched documentation site (https://developers.zenhub.com/) and then generate your personal access token from the account management page in Zenhub, under the API section.

We’re super excited to see what integrations and automations everyone builds!

4 Likes

Exciting stuff indeed @Joseph.from.Zenhub!

Looking forward to see what people are able to get out of it and hopefully borrow a few ideas :robot:

2 Likes

This sounds great.

Have you got some worked examples? I want to pull down the start/end dates for epics, which aren’t available via the rest api, which I’ve used to get started. I couldn’t get the schema to display via the explorer.

My full use case is to get all the epics, the GitHub data, dependencies and start/end dates. Managed to get everything else via rest apis, but not these dates!

1 Like

Hey Tcoupland,

Give this query a try to return epics in a workspace with their start and end dates.

query {
  workspace(id: "WORKSPACE_ID") {
            epics {
                nodes {
                    id
                  startOn
                  endOn
                    issue {
                        title
                    }
                }
            }
        }
    }

In terms of working examples, we’ve got a few as part of the Getting Started section of the documentation site. We’re planning to continue updating the documentation site in the future and will look to add a few more examples.

Hope this helps!

2 Likes

I wanted to put together a Colab notebook to experiment with this new API. This is the first time I do anything with GraphQL, so maybe I just am not doing something correctly. Can someone help me?

Or is there a complete minimal working example, where one could plug in the ID and get something meaningful back?

import asyncio
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport

async def main():
  # Select your transport with a defined url endpoint
  transport = AIOHTTPTransport(url="https://api.zenhub.com/public/graphql", headers={'Authorization': '<my authorization token>'})

  # Using `async with` on the client will start a connection on the transport
  # and provide a `session` variable to execute queries on this connection
  async with Client(
      transport=transport,
      fetch_schema_from_transport=True,
  ) as session:

      # Execute single query
      query = gql(
        """
          query {
            workspace(id: "<my workspace ID>") {
                      epics {
                          nodes {
                              id
                            startOn
                            endOn
                              issue {
                                  title
                              }
                          }
                      }
                  }
              }
      """
      )

      result = await session.execute(query)
      print(result)

loop = asyncio.get_running_loop()
loop.create_task(main())
1 Like

ok, I think I have the minimum working example - hope this saves time to someone else - would definitely save me some time if I had it …

import requests
import json

workspaceID = "<workspace id>"
accessToken = "<access token>"

endpoint = f"https://api.zenhub.com/public/graphql"
headers = {"Authorization": f"Bearer {accessToken}"}

query = """query {
  workspace(id: "<workspace ID>") {
            epics {
                nodes {
                    id
                  startOn
                  endOn
                    issue {
                        title
                    }
                }
            }
        }
    }"""

r = requests.post(endpoint, json={"query": query}, headers=headers)
if r.status_code == 200:
    print(json.dumps(r.json(), indent=2))
else:
    raise Exception(f"Query failed to run with a {r.status_code}.")
1 Like

Hi Fedorov,

We are working on launching a query examples page later this week for our documentation site that will provide a few pre-made queries for common data points users would want to retrieve.

We’ve launched a new examples page that is live on the documentation site to help everyone get started with using the GraphQL API. The examples page can be found here.

1 Like

+1 — I’d really like to see how others use the API.

For our part, we use it to drive our public-facing website. This provides our users and stakeholders—largely Austin Transportation colleagues + Austin residents—a way to see what we’re working on and why.

It also provides us with easier-than-Github visibility into our ever-expanding multitude of projects.We’ve used the site (often screenshots!) for everything from internal strategic planning to executive presentations.

@fedorov which accessToken are you using because when i am trying to use api_key it is giving error.

{
    "message": "missing authentication token in headers"
}

have you generated this accessToken by passing api_key into some api or something.
Please let me know i am getting error while using api_key in

"Authorization": f"Bearer {api_key}"

I’ve read through the posts on this thread, and I wonder if someone can explain how this:

POST https://api.zenhub.com/public/graphql

query getIssueInfo($repositoryGhId: Int!, $issueNumber: Int!, $workspaceId: ID!) {
issueByInfo(repositoryGhId: $repositoryGhId, issueNumber: $issueNumber) {
id
repository {
id
ghId
}
number
title
body
state
pipelineIssue(workspaceId: $workspaceId) {
priority {
id
name
color
}
pipeline {
id
name
}
}
estimate {
value
}
sprints(first: 10) {
nodes {
id
name
}
}
labels(first: 10) {
nodes {
id
name
color
}
}
}
}

…is an improvement over this…

GET /p1/repositories/:repo_id/issues/:issue_number