I am trying to migrate from Rest API to GQL and I would like to bulk download refunds, refundLineItems and Transactions. If refundlineItems and transactions are not supported within return, what is the suggested way that I get these details?
I would like to perform this extraction via Bulk query as I will automate the program. Also, I would like to extract updates on the refundlineitems and transactions. how can I design?
Hi @Mayumi_C
You can get everything you want (refunds, refund line items, and associated transactions) via the Admin GraphQL API, and you can do it via Bulk Operations. refundLineItems and transactions are both supported in on the Refund object:
So you don’t need any workaround “outside” the refund – you can get everything from
Order → refunds → refundLineItems and transactions. For bulk export you typically start at orders and walk down to refunds , refundLineItems , and transactions .
An example bulk mutation could look something like this:
mutation RunRefundsBulkOperation {
bulkOperationRunQuery(
query: """
query RefundsBulkQuery {
orders(first: 100, query: \"created_at:>=2024-01-01\") {
edges {
node {
id
name
processedAt
refunds(first: 50) {
edges {
node {
id
createdAt
updatedAt
totalRefundedSet {
shopMoney {
amount
currencyCode
}
}
refundLineItems(first: 50) {
edges {
node {
id
quantity
subtotalSet {
shopMoney {
amount
currencyCode
}
}
lineItem {
id
sku
}
}
}
}
transactions(first: 50) {
edges {
node {
id
kind
status
amountSet {
presentmentMoney {
amount
currencyCode
}
}
processedAt
}
}
}
}
}
}
}
}
}
}
"""
) {
bulkOperation {
id
status
objectCount
}
userErrors {
field
message
}
}
}
If you need near-real-time updates, you typically complement this with webhooks: use orders/updated or refund-related events to trigger a single-order GraphQL order query that includes refunds , refundLineItems , and transactions , while reserving bulk operations for full backfills and periodic reconciliation.
Hello @Liam-Shopify , I get this error “message”: “Invalid bulk query: Field ‘edges’ doesn’t exist on type ‘Refund’” on above query and if I remove edges and nodes from refunds, I get this “message”: “Queries that contain a connection field within a list field are not currently supported.”
Hi again @Mayumi_C
It does look like you’re hitting a limitation of bulk operations, see: Perform bulk operations with the GraphQL Admin API
Restrictions:
- Maximum of five total connections in the query.
- Connections must implement the Node interface.
- The top-level node and nodes fields can’t be used.
- Maximum of two levels deep for nested connections
On top of that general description, the bulk validator enforces:
- You can use a connection like orders { edges { node { … }}} at the root
- You can nest other connections inside that, but you can’t have a connection field under a simple list ([T]) field in some cases. That’s what “connection field within a list field” is about.
In your case:
ordersis a connectionOrder.refundsis a list ([Refund!]!)Refund.refundLineItemsis a connectionRefund.transactionsis a connection
So the path looks like:
orders (connection)
→ node.refunds (list)
→ refundLineItems (connection) ❌
→ transactions (connection) ❌
This is why fixing refunds to be a list (no edges) gets past the schema error but then the bulk validator rejects refunds { refundLineItems { … } } because it’s a connection (refundLineItems) under a list field (refunds).
It looks like you’ll need to split this into two pieces:
- A bulk operation that only pulls order + refund “headers” (no nested connections under refunds) – this satisfies the bulk restrictions.
- A second-phase job that:
- Streams the JSONL file from the bulk operation
- Extracts
Refund.ids - Calls the normal
refundquery to fetchrefundLineItemsandtransactions
Okay, noted. But will not normal query for many refund ids would result in throttling? Is there a plan for a solution where these objects can be downloaded through Bulk queries?

