Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot get customfield in grphql Goals

nick_pearson
January 27, 2026

Hi 

I am using graphql and the Atlassian Developer to perform two main tasks:
1. Extract details of a given Goal and a given Metric showing a Custom Field 
2. Update a Metric Performance

The eventual objective is to automate the update of Metrics from our Business Metrics held in google sheets.

My first problem is trying to access the list of Custom Fields and identify the custom field I need to update.

I have the following GraphQL which extracts a given Goal (I have obscured the ARI):

query GoalQuery2 {
goals_byIds(goalIds: "ari:cloud:townsquare:xxxxxxxxx:goal/55541a4f-7a34-4d10-9170-154ea141cf2b") @optIn(to: "Townsquare")
{
name
status {
value
}
progress {
percentage
type
}
}
}

The above works and produces the following result:
{
"data": {
"goals_byIds": [
{
"name": "Increase new customers who graduate to paying subscribers",
"status": {
"value": "pending"
},
"progress": {
"percentage": 0.04713804713804714,
"type": "AVERAGE_SUCCESS_MEASURE_ROLLUP"
}
}
]
},
"extensions": {
"gateway": {
"request_id": "db620beb-37d4-4bf9-a9f5-5d3eff47b9c2",
"trace_id": "db620beb37d44bf9a9f55d3eff47b9c2",
"crossRegion": false,
"edgeCrossRegion": false
}
}

When I then include the code to pull the Custom Field 

query GoalQuery2 {
  goals_byIds(goalIds: "ari:cloud:townsquare:xxxxxxxgoal/55541a4f-7a34-4d10-9170-154ea141cf2b")  @optIn(to: "Townsquare")
  {
    name
    status {
      value
    }
    progress {
      percentage
      type
    }
customFields {
      edges {
        node
      }
    }
    }
  }

It fails as follows:

{
"errors": [
{
"message": "Validation error (SubselectionRequired@[goals_byIds/customFields/edges/node]) : Subselection required for type 'TownsquareCustomField' of field 'node'",
"locations": [
{
"line": 14,
"column": 10
}
],
"extensions": {
"classification": "ValidationError",
"errorSource": "GRAPHQL_GATEWAY",
"statusCode": 400
}
}
],
"extensions": {
"gateway": {
"request_id": "4c790695-6aa3-495c-90a9-5d4e7f781c18",
"trace_id": "4c7906956aa3495c90a95d4e7f781c18",
"crossRegion": false,
"edgeCrossRegion": false
}
}
}

Can you help me to find the correct syntax please?

Also another second question:

2. I could only get the code above to work based on the Goal UUID which is hard for me to find (I had to use a web browser in dev mode to find it). Is there an easier way to run a graphQL to list all Goals Key and then use that?  Or is there a way in graphQL to list all the Goals UUID?

Thank you for any help you can give


2 answers

1 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Jorge Cammarota
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Champions.
January 27, 2026

It looks like you’ve hit two distinct walls: the GraphQL syntax for customFields (the "Subselection required" error) and the challenge of listing Goals without hardcoding ARI/UUIDs.

Correct Syntax for customFields in goals_byIds

The error Subselection required for type 'TownsquareCustomField' of field 'node' means that node is an object, not a scalar. In GraphQL, when a field returns an object, you must explicitly define which sub-fields you want.
The Fix

You need to specify the fields inside the node. Since customFields often use interfaces or unions, you should use inline fragments (... on TypeName) to access the specific values.
GraphQL

query GoalQuery2 {
goals_byIds(
goalIds: "ari:cloud:townsquare:xxxxxx:goal/55541a4f-7a34-4d10-9170-154ea141cf2b"
) @optIn(to: "Townsquare") {
name
status {
value
}
progress {
percentage
type
}
customFields {
edges {
node {
id
name
key
__typename # Useful to identify the specific type

# Use fragments to get the value based on the field type
... on TownsquareTextCustomField {
value
}
... on TownsquareNumberCustomField {
value
}
... on TownsquareSelectCustomField {
option {
id
value
}
}
}
}
}
}
}

Key Points:

edges { node { ... } } always requires sub-fields inside the node.

If you aren't sure which types exist yet, query only the metadata (id, name, key, __typename) first. The __typename will tell you exactly which fragment to use.

2. How to Find Goals Without the ARI/UUID

You don't have to use goals_byIds exclusively. You can use search or listing queries to find the IDs dynamically.
2.1. Listing Goals by Workspace or Filter

Use goals_search to list goals and retrieve their ARIs:
GraphQL

query ListGoals {
goals_search(
query: {
# Optional filters
# text: "client"
# status: [PENDING, IN_PROGRESS]
}
first: 50
) @optIn(to: "Townsquare") {
edges {
node {
id # This is the ARI you need for updates
key # Human-readable key/slug
name
status {
value
}
}
}
}
}

2.2. Filtering by Text (Goal Name)

If you only have the name of the goal from a spreadsheet, search for it:
GraphQL

query SearchGoalsByName {
goals_search(
query: {
text: "Increase New Customers"
}
first: 10
) @optIn(to: "Townsquare") {
edges {
node {
id
name
}
}
}
}

3. Linking to Google Sheets Automation

Suggested Workflow:

Preparation: Your Google Sheet should have a column for the Goal Name (or internal Key) and a column for the Metric Value.

Resolution: Your script (Apps Script) calls goals_search to map the "Goal Name" from the sheet to the "Goal ARI (ID)" from the API.

Identification: Fetch the customFields for that ID to find which fieldId matches the metric you want to update.

Execution: Run a mutation (e.g., goalMetric_update or customField_update) passing the Goal ARI, the Custom Field ID, and the Value from the spreadsheet.

Tente implementar essas alterações e me avise se surgirem outros erros.

nick_pearson
January 27, 2026

This is super useful and I managed to get the first graphql to work and also pulled out the custom select options that were selected - excellent thank you.  I produced the following code. 

I'd like to find the field Name for the TextSelectCustomField. I tried various things like __name, name, __descrption and description but none worked. 

Here is my code:

query GoalQuery2 {
goals_byIds(
goalIds: "ari:cloud:townsquare:11be4063-9258-45a2-8cee-629f0fae93d1:goal/55541a4f-7a34-4d10-9170-154ea141cf2b"
) @optIn(to: "Townsquare") 
  {
key
    name
status {
value
      __typename #shows the field type for Status
}
progress {
percentage
type
      __typename  #shows the field type for Percentage
}
    
    customFields {
edges {
node {
          ... on TownsquareTextCustomField {
value {
id}
}
... on TownsquareNumberCustomField {
value {
id}
}
... on TownsquareTextSelectCustomField {
__typename  
    values { # gets values from selection list
      edges {
        node {
          value
        }
      }
    }
  }
}
}
}
}
}


Also when I tried running the 2.1. Listing Goals by Workspace or Filter and 2.2. Filtering by Text (Goal Name) I need to include the ContainerID but do not know where it should go. I did search online for guidance on graphql field names and functions to be used for Goals and Metrics but found very limited information. If you know a resource i can read then I'd be happy to read through all the documentation.

Thank you once again - this really is invaluable help
Jorge Cammarota
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Champions.
January 27, 2026

That's great that it worked, my friend. Now you just need to accept my answer. This helps me a lot in becoming a community champion.

 

nick_pearson
January 27, 2026

Are you able to assist on the two follow up questions above or should I raise them as another question?

Jorge Cammarota
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Champions.
January 27, 2026

 

I will divide this into two parts: (1) correction/adjustment of your current query and where containerId fits in, and (2) where to find documentation and examples (even if it is currently quite limited).
1. Where containerId fits in and why it is necessary

Based on the type names (Townsquare*) and the goals_byIds field, you are using the internal Goals/Atlas (Townsquare) GraphQL API. Generally, the patterns that appear in this schema are:

To fetch specific goals: Something like goals_byIds(goalIds: [ID!]!, containerId: ID) or similar.

To list goals by workspace/filter: Something like goals(filter: { containerId: "..." ... }) or a direct containerId: "..." argument.

In other words, the containerId is almost always:

An argument of the root query field, not inside the return fields.

Placed right after goalIds, separated by a comma.

Adapting your query, it should probably look like this (adjust names according to the schema you see in the explorer):
GraphQL

query GoalQuery2 {
goals_byIds(
goalIds: [
"ari:cloud:townsquare:11be4063-9258-45a2-8cee-629f0fae93d1:goal/55541a4f-7a34-4d10-9170-154ea141cf2b"
]
containerId: "ari:cloud:platform::workspace/YOUR-WORKSPACE-OR-CONTAINER-HERE"
) @optIn(for: "Townsquare") {
key
name
status {
value
__typename
}
progress {
percentage
type
__typename
}
customFields {
edges {
node {
... on TownsquareTextCustomField {
value {
id
}
}
... on TownsquareNumberCustomField {
value {
id
}
}
... on TownsquareTextSelectCustomField {
__typename
values {
edges {
node {
value
}
}
}
}
}
}
}
}
}

Important corrections regarding your original code:

query instead of "consulta" (GraphQL requires query, mutation, or subscription keywords).

Arguments: goalIds is usually a list ([]), even if you use only 1 ID. containerId enters the same argument list as goals_byIds.

Directive @optIn: The standard syntax is @optIn(for: "Townsquare").

Field names in English: "chave" → key; "nome" → name; "progresso.percentagem" → progress.percentage.

customFields: The Relay-like pattern is edges { node { ... }}.

Fragments: GraphQL uses ... on Type.

1.1. Example: List goals by workspace/filter

A typical pattern would be (adjust according to your explorer's actual schema):
GraphQL

query ListGoalsByWorkspace {
goals(
containerId: "ari:cloud:platform::workspace/YOUR-WORKSPACE"
filter: {
# other specific criteria, if they exist in the schema
}
) @optIn(for: "Townsquare") {
edges {
node {
id
key
name
status {
value
}
progress {
percentage
}
}
}
}
}

1.2. Example: Filtering by text (goal name)

This also usually follows the pattern of filters in the argument:
GraphQL

query ListGoalsByName {
goals(
containerId: "ari:cloud:platform::workspace/YOUR-WORKSPACE"
filter: {
name: {
contains: "text you want to filter"
}
}
) @optIn(for: "Townsquare") {
edges {
node {
id
key
name
}
}
}
}

The central point: containerId always stays in the query field (root) arguments, never inside the selection body.
2. Where to find documentation and examples

Public documentation for Atlas/Townsquare via GraphQL is still limited, but you have practical ways to discover field names, types, and filters:

2.1. Use the GraphQL Explorer/Playground If you have access to the GraphQL endpoint via a Playground or GraphiQL:

Use the Schema or Docs panel on the right side.

Search for Query and find fields like goals_byIds, goals, or goalsByFilter.

Check the arguments (e.g., goalIds, containerId, filter, searchText) and their types.

2.2. Inspect Network calls from the frontend (Browser DevTools) When you navigate the Atlas UI:

Open DevTools (F12) → Network tab.

Filter by graphql or townsquare.

Click on the requests to see the payload with the query and variables. This is the most reliable way to see how the Atlassian frontend uses the schema.

2.3. Public Documentation for Atlas / Goals Even if not 100% GraphQL-focused, these help understand concepts of goals, containers, and workspaces:

Atlassian Platform Apps | Atlassian: https://developer.atlassian.com/platform/

Learn GraphQL (Syntax/Fragments): https://graphql.org/learn/

1 vote
Marc -Devoteam-
Community Champion
January 27, 2026

HI @nick_pearson 

Might this be related to; https://developer.atlassian.com/platform/goals/graphql/#field-lifecycle 

I haven't tested it, but it seems the only thing I can find around custom fields and goals in Graph API

nick_pearson
January 27, 2026

Hi Marc

Thanks for getting in touch.  I did read through the above page and wondered if Custom Fields were considered Beta.  However without the ability to pull the name of the custom field (in a way that graphQL will accept) I could not set the HeaderX-ExperimentalApi: {CustomFiled Name}


DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
PERMISSIONS LEVEL
Product Admin
TAGS
AUG Leaders

Atlassian Community Events