This article demonstrates how to use the GraphQL API to manage a project. For more information about how to use the API in a GitHub Actions workflow, see "Automating projects (beta)." For a full list of the available data types, see "Reference."
Note: Projects (beta) is currently in public beta and subject to change.
Authentication
In all of the following cURL examples, replace TOKEN
with a token that has the read:org
scope (for queries) or write:org
scope (for queries and mutations). The token can be a personal access token for a user or an installation access token for a GitHub App. For more information about creating a personal access token, see "Creating a personal access token." For more information about creating an installation access token for a GitHub App, see "Authenticating with GitHub Apps."
To learn more about GitHub CLI, see "About GitHub CLI."
Before running GitHub CLI commands, you must authenticate by running gh auth login --scopes "write:org"
. If you only need to read, but not edit, projects, you can omit the --scopes
argument. For more information on command line authentication, see "gh auth login."
Using variables
In all of the following examples, you can use variables to simplify your scripts. Use -F
to pass a variable that is a number, Boolean, or null. Use -f
for other variables. For example,
my_org="octo-org"
my_num=5
gh api graphql -f query='
query($organization: String! $number: Int!){
organization(login: $organization){
projectNext(number: $number) {
id
}
}
}' -f organization=$my_org -F number=$my_num
For more information, see "Forming calls with GraphQL."
Finding information about projects
Use queries to get data about projects. For more information, see "About queries."
Finding the node ID of an organization project
To update your project through the API, you will need to know the node ID of the project.
You can find the node ID of an organization project if you know the organization name and project number. Replace ORGANIZATION
with the name of your organization. For example, octo-org
. Replace NUMBER
with the project number. To find the project number, look at the project URL. For example, https://github.com/orgs/octo-org/projects/5
has a project number of 5.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"query{organization(login: \"ORGANIZATION\") {projectNext(number: NUMBER){id}}}"}'
gh api graphql -f query='
query{
organization(login: "ORGANIZATION"){
projectNext(number: NUMBER) {
id
}
}
}'
You can also find the node ID of all projects in your organization. The following example will return the node ID and title of the first 20 projects in an organization. Replace ORGANIZATION
with the name of your organization. For example, octo-org
.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"{organization(login: \"ORGANIZATION\") {projectsNext(first: 20) {nodes {id title}}}}"}'
gh api graphql -f query='
query{
organization(login: "ORGANIZATION") {
projectsNext(first: 20) {
nodes {
id
title
}
}
}
}'
Finding the node ID of a user project
To update your project through the API, you will need to know the node ID of the project.
You can find the node ID of a user project if you know the project number. Replace USER
with your user name. For example, octocat
. Replace NUMBER
with your project number. To find the project number, look at the project URL. For example, https://github.com/users/octocat/projects/5
has a project number of 5.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"query{user(login: \"USER\") {projectNext(number: NUMBER){id}}}"}'
gh api graphql -f query='
query{
user(login: "USER"){
projectNext(number: NUMBER) {
id
}
}
}'
You can also find the node ID for all of your projects. The following example will return the node ID and title of your first 20 projects. Replace USER
with your username. For example, octocat
.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"{user(login: \"USER\") {projectsNext(first: 20) {nodes {id title}}}}"}'
gh api graphql -f query='
query{
user(login: "USER") {
projectsNext(first: 20) {
nodes {
id
title
}
}
}
}'
Finding the node ID of a field
To update the value of a field, you will need to know the node ID of the field. Additionally, you will need to know the ID of the options for single select fields and the ID of the iterations for iteration fields.
The following example will return the ID, name, and settings for the first 20 fields in a project. Replace PROJECT_ID
with the node ID of your project.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"query{node(id: \"PROJECT_ID\") {... on ProjectNext {fields(first: 20) {nodes {id name settings}}}}}"}'
gh api graphql -f query='
query{
node(id: "PROJECT_ID") {
... on ProjectNext {
fields(first: 20) {
nodes {
id
name
settings
}
}
}
}
}'
The response will look similar to the following example:
{
"data": {
"node": {
"fields": {
"nodes": [
{
"id": "MDE2OlByb2plY3ROZXh0RmllbGQxMzE1OQ==",
"name": "Title",
"settings": "null"
},
{
"id": "MDE2OlByb2plY3ROZXh0RmllbGQxMzE2MA==",
"name": "Assignees",
"settings": "null"
},
{
"id": "MDE2OlByb2plY3ROZXh0RmllbGQxMzE2MQ==",
"name": "Status",
"settings": "{\"options\":[{\"id\":\"f75ad846\",\"name\":\"Todo\",\"name_html\":\"Todo\"},{\"id\":\"47fc9ee4\",\"name\":\"In Progress\",\"name_html\":\"In Progress\"},{\"id\":\"98236657\",\"name\":\"Done\",\"name_html\":\"Done\"}]}"
},
{
"id": "MDE2OlByb2plY3ROZXh0RmllbGQ3NTEwNw==",
"name": "Iteration",
"settings": "{\"configuration\":{\"duration\":7,\"start_day\":5,\"iterations\":[{\"id\":\"c4d8e84d\",\"title\":\"Iteration 2\",\"duration\":7,\"start_date\":\"2021-10-08\",\"title_html\":\"Iteration 2\"},{\"id\":\"fafa9c9f\",\"title\":\"Iteration 3\",\"duration\":7,\"start_date\":\"2021-10-15\",\"title_html\":\"Iteration 3\"}],\"completed_iterations\":[{\"id\":\"fa62c118\",\"title\":\"Iteration 1\",\"duration\":7,\"start_date\":\"2021-10-01\",\"title_html\":\"Iteration 1\"}]}}"
}
]
}
}
}
}
Each field has an ID. Additionally, single select fields and iteration fields have a settings
value. In the single select settings, you can find the ID of each option for the single select. In the iteration settings, you can find the duration of the iteration, the start day of the iteration (from 1 for Monday to 7 for Sunday), the list of incomplete iterations, and the list of completed iterations. For each iteration in the lists of iterations, you can find the ID, title, duration, and start date of the iteration.
Finding information about items in a project
You can query the API to find information about items in your project.
Note: The API will not return information about draft issues.
The following example will return the title and ID for the first 20 items in a project. For each item, it will also return the value and name for the first 8 fields in the project. If the item is an issue or pull request, it will return the login of the first 10 assignees. Replace PROJECT_ID
with the node ID of your project.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"query{node(id: \"PROJECT_ID\") {... on ProjectNext {items(first: 20) {nodes{title id fieldValues(first: 8) {nodes{value projectField{name}}} content{...on Issue {assignees(first: 10) {nodes{login}}} ...on PullRequest {assignees(first: 10) {nodes{login}}}}}}}}}"}'
gh api graphql -f query='
query{
node(id: "PROJECT_ID") {
... on ProjectNext {
items(first: 20) {
nodes{
title
id
fieldValues(first: 8) {
nodes{
value
projectField{
name
}
}
}
content{
...on Issue {
assignees(first: 10) {
nodes{
login
}
}
}
...on PullRequest {
assignees(first: 10) {
nodes{
login
}
}
}
}
}
}
}
}
}'
A project may contain items that a user does not have permission to view. In this case, the response will include a redacted item.
{
"node": {
"title": "You can't see this item",
...
}
}
Updating projects
Use mutations to update projects. For more information, see "About mutations."
Note: You cannot add and update an item in the same call. You must use addProjectNextItem
to add the item and then use updateProjectNextItemField
to update the item.
Adding an item to a project
The following example will add an issue or pull request to your project. Replace PROJECT_ID
with the node ID of your project. Replace CONTENT_ID
with the node ID of the issue or pull request that you want to add.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation {addProjectNextItem(input: {projectId: \"PROJECT_ID\" contentId: \"CONTENT_ID\"}) {projectNextItem {id}}}"}'
gh api graphql -f query='
mutation {
addProjectNextItem(input: {projectId: "PROJECT_ID" contentId: "CONTENT_ID"}) {
projectNextItem {
id
}
}
}'
The response will contain the node ID of the newly created item.
{
"data": {
"addProjectNextItem": {
"projectNextItem": {
"id": "MDE1OlByb2plY3ROZXh0SXRlbTM0MjEz"
}
}
}
}
If you try to add an item that already exists, the existing item ID is returned instead.
Updating a project's settings
The following example will update your project's settings. Replace PROJECT_ID
with the node ID of your project. Set public
to true
to make your project public on GitHub. Modify description
to make changes to your project's README.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation { updateProjectNext(input: { projectId: \"PROJECT_ID\", title: \"Project title\", public: false, description: \"# Project README\n\nA long description\", shortDescription: \"A short description\"}) { projectNext { id, title, description, shortDescription }}}"}'
gh api graphql -f query='
mutation {
updateProjectNext(
input: {
projectId: "PROJECT_ID",
title: "Project title",
public: false,
description: "# Project README\n\nA long description",
shortDescription: "A short description"
}
) {
projectNext {
id
title
description
shortDescription
}
}
}'
Updating a custom text, number, or date field
The following example will update the value of a date field for an item. Replace PROJECT_ID
with the node ID of your project. Replace ITEM_ID
with the node ID of the item you want to update. Replace FIELD_ID
with the ID of the field that you want to update.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation {updateProjectNextItemField(input: {projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: \"2021-5-11\"}) {projectNextItem {id}}}"}'
gh api graphql -f query='
mutation {
updateProjectNextItemField(
input: {
projectId: "PROJECT_ID"
itemId: "ITEM_ID"
fieldId: "FIELD_ID"
value: "2021-5-11"
}
) {
projectNextItem {
id
}
}
}'
Note: You cannot use updateProjectNextItemField
to change Assignees
, Labels
, Milestone
, or Repository
because these fields are properties of pull requests and issues, not of project items. Instead, you must use the addAssigneesToAssignable, removeAssigneesFromAssignable, addLabelsToLabelable, removeLabelsFromLabelable, updateIssue, updatePullRequest, or transferIssue mutations.
Updating a single select field
The following example will update the value of a single select field for an item.
PROJECT_ID
- Replace this with the node ID of your project.ITEM_ID
- Replace this with the node ID of the item you want to update.FIELD_ID
- Replace this with the ID of the single select field that you want to update.OPTION_ID
- Replace this with the ID of the desired single select option.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation {updateProjectNextItemField(input: {projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: \"OPTION_ID\"}) {projectNextItem {id}}}"}'
gh api graphql -f query='
mutation {
updateProjectNextItemField(
input: {
projectId: "PROJECT_ID"
itemId: "ITEM_ID"
fieldId: "FIELD_ID"
value: "OPTION_ID"
}
) {
projectNextItem {
id
}
}
}'
Updating an iteration field
The following example will update the value of an iteration field for an item.
PROJECT_ID
- Replace this with the node ID of your project.ITEM_ID
- Replace this with the node ID of the item you want to update.FIELD_ID
- Replace this with the ID of the iteration field that you want to update.ITERATION_ID
- Replace this with the ID of the desired iteration. This can be either an active iteration (from theiterations
array) or a completed iteration (from thecompleted_iterations
array).
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation {updateProjectNextItemField(input: {projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: \"ITERATION_ID\"}) {projectNextItem {id}}}"}'
gh api graphql -f query='
mutation {
updateProjectNextItemField(
input: {
projectId: "PROJECT_ID"
itemId: "ITEM_ID"
fieldId: "FIELD_ID"
value: "ITERATION_ID"
}
) {
projectNextItem {
id
}
}
}'
Deleting an item from a project
The following example will delete an item from a project. Replace PROJECT_ID
with the node ID of your project. Replace ITEM_ID
with the node ID of the item you want to delete.
curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: token TOKEN' \
--data '{"query":"mutation {deleteProjectNextItem(input: {projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\"}) {deletedItemId}}"}'
gh api graphql -f query='
mutation {
deleteProjectNextItem(
input: {
projectId: "PROJECT_ID"
itemId: "ITEM_ID"
}
) {
deletedItemId
}
}'