Refer to this page for further guidance on how to use the Goals GraphQL API.
Your GraphQL request needs to be sent to this url: https://{subdomain}.atlassian.net/gateway/api/graphql.
Authentication proves who you are. The Goals GraphQL API supports three ways to authenticate a request. Once authenticated, what you can access is determined by Authorization.
Our GraphQL API supports Basic Authentication. Instead of a password, you use your scoped or classic API token along with your user email.
See the Manage API tokens for your Atlassian account page to create an API token.
Copy this API token to use in the next step.
You can construct and send basic auth headers. To do this you perform the following steps:
user@example.com:api_token_stringAuthorization header with content Basic followed by a space, then the encoded stringhttps://{subdomain}.atlassian.net/gateway/api/graphql1 2curl -D- \ -X POST \ -H "Authorization: Basic BASE_64_ENCODED{EMAIL:TOKEN}" \ -H "Content-Type: application/json" \ --data-binary '{"query":"query WhoAmI {me{user{name}}}","operationName":"WhoAmI"}' \ "https://{subdomain}.atlassian.net/gateway/api/graphql"
This should return a JSON response similar to the following:
1 2{"data":{"me":{"user":{"name":"Jane Doe"}}},"extensions":{"gateway":{"request_id":"{requestId}","trace_id":"{traceId}","crossRegion":false,"edgeCrossRegion":false}}}%
Use this for server-to-server integrations that run without user interaction (for example, automated syncs or reporting pipelines). It uses the OAuth 2.0 client-credentials flow and also support scoped access tokens.
grant_type=client_credentials against https://auth.atlassian.com/oauth/token.Authorization: Bearer <ACCESS_TOKEN>.Full guide: Create OAuth 2.0 credential for service accounts
Authentication proves who you are; authorization determines what you can do. When you authenticate with OAuth (2LO or 3LO) or a scoped service-account credential, your access is constrained by the scopes granted to your token.
Request the scopes your integration needs when configuring your OAuth 2.0 (3LO) app or service-account credential.
| Scope | Grants access to |
|---|---|
read:goal:goals | Read goal core data and links |
read:access:goals | Read goal membership and access info |
write:goal:goals | Create, edit, archive, and clone goals |
write:update:goals | Post and manage goal updates and comments |
write:chat-integration:goals | Connect or disconnect Slack and MS Teams channels |
delete:goal:goals | Delete goal content |
manage:access:goals | Manage goal access and watchers |
Note: For queries, a missing field-level scope returns
nullfor that field with a matching entry in theerrorsarray, while other authorized fields still resolve.
GraphQL uses HTTP POST and application/json content type. This is a requirement of the GraphQL-over-HTTP specification.
The payload of the GraphQL request follows the GraphQL-over-HTTP specification. See this documentation for how to add variables and extensions to the payload.
Let us assume you want to use goals_byId to query for the name, owner, and tags of a goal with id ari:cloud:townsquare:{siteId}:goal/{goalUuid} .
Your GraphQL query would look like as follows:
1 2query GoalQuery { goals_byId(goalId: "ari:cloud:townsquare:{siteId}:goal/{goalUuid}") { name owner { name } tags { edges { node { name } } } } }
From this, your cURL command would be as follows:
1 2curl -X POST 'https://{subdomain}.atlassian.net/gateway/api/graphql' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic <YOUR_BASE_64_TOKEN_HERE>' \ --data '{"query":"query GoalQuery { goals_byId(goalId: \"ari:cloud:townsquare:{siteId}:goal/{goalUuid}\") { name owner { name } tags { edges { node { name } } } } }"}'
Let us assume you want to use goals_byIds to query for the name of the goal, its associated updates as well as comments and any current draft update. The goals you want to query have ids of ari:cloud:townsquare:{siteId_1}:goal/{goalUuid_1} and ari:cloud:townsquare:{siteId_2}:goal/{goalUuid_2}.
Note that at the time of writing this example, theupdates field on a goal was marked as experimental, and so we opted in by using the optIn directive @optIn(to: "Townsquare").
Your GraphQL query would look like as follows:
1 2query GoalsQuery { goals_byIds(goalIds: ["ari:cloud:townsquare:{siteId_1}:goal/{goalUuid_1}", "ari:cloud:townsquare:{siteId_2}:goal/{goalUuid_2}"]) @optIn(to: "Townsquare") { name draftUpdate { author { name } input modifiedDate } updates { edges { node { creator { name } summary comments { edges { node { creator { name } commentText creationDate } } } } } } } }
From this, your cURL command would be as follows:
1 2curl -X POST 'https://{subdomain}.atlassian.net/gateway/api/graphql' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic <YOUR_BASE_64_TOKEN_HERE>' \ --data '{"query":"query GoalsQuery { goals_byIds(goalIds: [\"ari:cloud:townsquare:{siteId_1}:goal/{goalUuid_1}\", \"ari:cloud:townsquare:{siteId_2}:goal/{goalUuid_2}\"]) @optIn(to: \"Townsquare\") { name draftUpdate { author { name } input modifiedDate } updates { edges { node { creator { name } summary comments { edges { node { creator { name } commentText creationDate } } } } } } } }"}'
Let us assume you want to use goals_create to create a goal with the name "Goal created from GraphQL" and a target date of the 31st of December 2026.
Your GraphQL mutation would look like as follows:
1 2mutation CreateGoalMutation { goals_create ( input: { containerId: "ari:cloud:townsquare::site/{siteId}" name: "Goal created from GraphQL" goalTypeId:"ari:cloud:goal:{siteId}:goal-type/{activationId}/{goalTypeId}" targetDate:{ date: "2026-12-31" confidence:QUARTER } } ) { goal { id name } } }
From this, your cURL command would be as follows:
1 2curl -X POST 'https://{subdomain}.atlassian.net/gateway/api/graphql' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic <YOUR_BASE_64_TOKEN_HERE>' \ --data '{"query":"mutation CreateGoalMutation { goals_create ( input: { containerId: \"ari:cloud:townsquare::site/{siteId}\" name: \"Goal created from GraphQL\" goalTypeId: \"ari:cloud:goal:{siteId}:goal-type/{activationId}/{goalTypeId}\" targetDate: { date: \"2026-12-31\" confidence: QUARTER } } ) { goal { id name } } }"}'
Let us assume you want to use goals_createUpdate to create an update for a goal with id ari:cloud:townsquare:{siteId}:goal/{goalUuid}. From the response, you would like to know whether the operation succeeded and retrieve the id, url, creation date, update type, summary, new score, new target date, and new target date confidence of the goal.
Your GraphQL mutation would look like as follows:
1 2mutation CreateGoalUpdateMutation { goals_createUpdate( input: { goalId: "ari:cloud:townsquare:{siteId}:goal/{goalUuid}" summary: "{\"version\":1,\"type\":\"doc\",\"content\":[{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"Description body for the update.\"}]}]}" status: "off_track" score: 75 targetDate: { date: "2026-03-15", confidence: DAY } } ) { success errors { message } update { id url creationDate updateType summary newScore newTargetDate newTargetDateConfidence } } }
From this, your cURL command would be as follows:
1 2curl -X POST 'https://{subdomain}.atlassian.net/gateway/api/graphql' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic <YOUR_BASE_64_TOKEN_HERE>' \ --data '{ "query": "mutation CreateGoalUpdateMutation { goals_createUpdate(input: { goalId: \"ari:cloud:townsquare:{siteId}:goal/{goalUuid}\", summary: \"{\\\"version\\\":1,\\\"type\\\":\\\"doc\\\",\\\"content\\\":[{\\\"type\\\":\\\"paragraph\\\",\\\"content\\\":[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"Description body for the update.\\\"}]}]}\", status: \"off_track\", score: 75, targetDate: { date: \"2026-03-15\", confidence: DAY } }) { success errors { message } update { id url creationDate updateType summary newScore newTargetDate newTargetDateConfidence } } }" }'
An important thing to note here is the summary field needs to be in Atlassian Document Format.
Let us assume you want to use goals_edit to archive a goal with id ari:cloud:townsquare:{siteId}:goal/{goalUuid}. From the response, you would like the id, name, and archived status of the goal.
Your GraphQL mutation would look like as follows:
1 2mutation ArchiveGoalMutation { goals_edit(input: { goalId: "ari:cloud:townsquare:{siteId}:goal/{goalUuid}" archived: true }) { goal { id name isArchived } } }
From this, your cURL command would be as follows:
1 2curl -X POST 'https://{subdomain}.atlassian.net/gateway/api/graphql' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic <YOUR_BASE_64_TOKEN_HERE>' \ --data '{"query":"mutation ArchiveGoalMutation { goals_edit(input: { goalId: \"ari:cloud:townsquare:{siteId}:goal/{goalUuid}\" archived: true }) { goal { id name isArchived } } }"}'
Rate this page: