Graphql API - Get all ACTIVE and PUBLISHED Products by Collection Id

Topic summary

Goal: retrieve all ACTIVE and PUBLISHED products for a specific collection in a single GraphQL query.

Key points and timeline:

  • Initial limitation: The Collection.products connection lacks filters for status/published_status, so a single-query solution wasn’t available. Internal feedback was submitted to add such filters.
  • Workarounds shared: Query the collection and fetch products (up to 250) then filter client-side (e.g., LINQ). Caveats: may return DRAFT items if they appear first; doesn’t inherently enforce ACTIVE or PUBLISHED filters server-side.

Latest update (partial solution):

  • Use productVariants with server-side filters: productVariants(query: “collection:{numeric-collection-id} product_status:active” …). Note: use product_status:active (not status:ACTIVE), and pass the collection’s numeric ID (not gid). This returns variants and includes parent product info.

Remaining gaps:

  • PUBLISHED filter: No confirmed way in this thread to also filter by published_status:published within the same productVariants query. Original requirement (ACTIVE + PUBLISHED) is only partially solved.

Status: Partially resolved; server-side filtering for ACTIVE via productVariants works, but handling published_status remains open.

Summarized with AI on December 27. AI used: gpt-5.

Hi, I need to get all active and published products by collection id.

I know I can get all Active and published products by doing this:

{
  products (first:50, query:"status:active AND published_status:published") {
    nodes {
      id,
      title,
    }
  }
}

And I know I can get all products by collection id by doing this:

query ProductsByCollection ($id: ID!) { 
  collection(id: $id) {
    handle
    products(first: 50) {
      nodes {
        title,
        id,
        status
      }
    }
  }
}

How can I get all active and published products for a specific collection with just one query ?

Thanks

2 Likes

Hi @pablores ,

Thanks for your post. Currently there’s not a built in way to achieve that in a single query so we’ve submitted some feedback about it internally, particularly around having some more filters in the Collection.products connection.

Hope you have a great day

Hi Pablores!

Put this in Query:

query Collections ($first: Int!, $reverse: Boolean!, $query: String!){
    collections(first: $first, reverse: $reverse, query: $query) {
        edges {
            node {

                id
                products(first: 250) {
                    edges {
                        node {
                            id
                            title
                            status
                            description
                        }
                    }
                }
            }
        }
    }
}

and put this in Variables:

{
    "first": 1,
    "reverse": true,
    "query": "id:440808079677"
}

You will receive 250 products from that collection identified on the ID variable:

{
    "data": {
        "collections": {
            "edges": [
                {
                    "node": {
                        "id": "gid://shopify/Collection/440808079677",
                        "products": {
                            "edges": [
                                {
                                    "node": {
                                        "id": "gid://shopify/Product/8177835835709",
                                        "title": "DARSHAN & GURUPURNIMA 2023",
                                        "status": "ACTIVE",
                                        "description": "Darshan starts on the 01.07.2023 at 14:00 in the Tent. Gurupurnima celebration starts on the 03.07.2023 at 18:00 at the stage outside."
                                    }
                                },
                                {
                                    "node": {
                                        "id": "gid://shopify/Product/8189817225533",
                                        "title": "DARSHAN 01 JULY 2023 14:00 @ SPN",
                                        "status": "ACTIVE",
                                        "description": "You can attend 2 In-Person Darshan in July. One of them has to be the 24th of July.Newcomers can attend 3 In-Person Darshans in July."
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 7,
            "actualQueryCost": 7,
            "throttleStatus": {
                "maximumAvailable": 10000.0,
                "currentlyAvailable": 9993,
                "restoreRate": 500.0
            }
        }
    }
}
1 Like

Is there another way to do this with multiple queries?

You forgot the condition “products is ACTIVE” :disappointed_face:

It’s true, but I am using C#, and because of that I can just use LINQ to filter the returned data super quick.
Don’t know what technology you are using, but maybe it has something similar

But in case this collection has the first 250 products as DRAFT, that means at this time no products found in one graphQL query

2 Likes

This should be possible now by using the productVariants graphql query.

For example:

query getProductVariantsByCollection {
  productVariants(query:"collection:{your-collection-id} status:ACTIVE" first:10) {
    nodes {
      id
      sku
      product {
        title
      }
    }
  }
}

This will give you all of the active products for a specific collection id. The collection id you send in is just the number and not the gid. Hope this helps.

I made a typo in my query… it should actually be

... product_status:active