Merge Orders

Merge Orders

This guide walks through a complete, real merge/unmerge flow using the ShipHero Public API.

1. List Mergeable Orders

We query to get the mergeable orders based on a real order but we can also ask for mergeable orders without this filter.

Query

query MergeableOrdersQuery (
    $first: Int = 15, 
    $after: String, 
    $order_number: String, 
    $first_name: String, 
    $last_name: String
) {
    mergeable_orders {
        request_id
        complexity
        data(
            first: $first, 
            after: $after, 
            order_number: $order_number, 
            first_name: $first_name, 
            last_name: $last_name
        ) {
            edges {
                node {
                    id
                    order_number
                    potential_merges {
                        id
                        order_number
                        email
                    }
                }
            }
            pageInfo {
                hasNextPage
                hasPreviousPage
                startCursor
                endCursor
            }
        }
    }
}

Variables

{
    "first": 10,
    "order_number": "custom-test-15"
}

We see we have 4 orders that can be merged.

Full Response

{
    "data": {
        "mergeable_orders": {
            "request_id": "69173a90d1d7492c7398fcee",
            "complexity": 16,
            "data": {
                "edges": [
                    {
                        "node": {
                            "id": "T3JkZXI6NzA0MDExNjkw",
                            "order_number": "custom-test-12",
                            "potential_merges": [
                                {
                                    "id": "T3JkZXI6NzA0MDExOTY1",
                                    "order_number": "custom-test-13",
                                    "email": "seba@shiphero.com"
                                },
                                {
                                    "id": "T3JkZXI6NzA0MDEyMjUx",
                                    "order_number": "custom-test-14",
                                    "email": "seba@shiphero.com"
                                },
                                {
                                    "id": "T3JkZXI6NzA0MDEyNDc5",
                                    "order_number": "custom-test-15",
                                    "email": "seba@shiphero.com"
                                }
                            ]
                        }
                    }
                ],
                "pageInfo": {
                    "hasNextPage": false,
                    "hasPreviousPage": false,
                    "startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
                    "endCursor": "YXJyYXljb25uZWN0aW9uOjA="
                }
            }
        }
    },
    "extensions": {
        "throttling": {
            "estimated_complexity": 16,
            "cost": 2,
            "cost_detail": {
                "mergeable_orders": {
                    "items_count": 1,
                    "cost": 1,
                    "total_cost": 2,
                    "fields": {}
                }
            },
            "user_quota": {
                "credits_remaining": 9999,
                "max_available": 10001,
                "increment_rate": 600
            }
        }
    }
}

2. Merge the Orders

We pick one to be the master and set the other 3 as sub-orders.

Mutation

mutation OrderMerge($data: MergeOrdersInput!) {
  order_merge(data: $data) {
    request_id
    complexity
    order {
      id
      order_number
    }
  }
}

Variables

{
    "data": {
        "master_order_id": "T3JkZXI6NzA0MDExNjkw",
        "sub_order_ids": [
            "T3JkZXI6NzA0MDExOTY1",
            "T3JkZXI6NzA0MDEyMjUx",
            "T3JkZXI6NzA0MDEyNDc5"
        ]
    }
}

Full Response

{
    "data": {
        "order_merge": {
            "request_id": "69173add1a7215a63bed8cf8",
            "complexity": 5,
            "order": {
                "id": "T3JkZXI6NzA0MDExNjkw",
                "order_number": "custom-test-12"
            }
        }
    },
    "extensions": {
        "throttling": {
            "estimated_complexity": 5,
            "cost": 5,
            "cost_detail": {
                "order_merge": {
                    "items_count": 0,
                    "cost": 5,
                    "total_cost": 5,
                    "fields": {}
                }
            },
            "user_quota": {
                "credits_remaining": 9996,
                "max_available": 10001,
                "increment_rate": 600
            }
        }
    }
}

3. Inspect Master Order After Merge

We can query the master orders and its sub-orders to confirm all went well.

Query

query OrderStatus($id: String!) {
  order(id: $id) {
    request_id
    complexity
    data {
      id
      order_number
      fulfillment_status
      created_at
      updated_at
      merged_orders {
        order_id
        is_master
      }
      line_items(first: 20) {
        edges {
          node {
            sku
            quantity
          }
        }
      }
    }
  }
}

Variables

{
  "id": "T3JkZXI6NzA0MDExNjkw"
}

Full Response

{
    "data": {
        "order": {
            "request_id": "691743275f2a04ad114163a9",
            "complexity": 32,
            "data": {
                "id": "T3JkZXI6NzA0MDExNjkw",
                "order_number": "custom-test-12",
                "fulfillment_status": "pending",
                "created_at": "2025-11-14T13:49:37",
                "updated_at": "2025-11-14T13:49:53",
                "merged_orders": [
                    {
                        "order_id": "T3JkZXI6NzA0MDExOTY1",
                        "is_master": false
                    },
                    {
                        "order_id": "T3JkZXI6NzA0MDEyMjUx",
                        "is_master": false
                    },
                    {
                        "order_id": "T3JkZXI6NzA0MDEyNDc5",
                        "is_master": false
                    }
                ],
                "line_items": {
                    "edges": [
                        {
                            "node": {
                                "sku": "ubik",
                                "quantity": 2
                            }
                        }
                    ]
                }
            }
        }
    }
}

4. Inspect Sub-Order After Merge

We can also inspect one of the sub-orders.

Full Response

{
    "data": {
        "order": {
            "request_id": "6917433ee51be82f7669c804",
            "complexity": 32,
            "data": {
                "id": "T3JkZXI6NzA0MDExOTY1",
                "order_number": "custom-test-13",
                "fulfillment_status": "pending",
                "created_at": "2025-11-14T13:50:17",
                "updated_at": "2025-11-14T13:51:20",
                "merged_orders": [
                    {
                        "order_id": "T3JkZXI6NzA0MDExNjkw",
                        "is_master": true
                    },
                    {
                        "order_id": "T3JkZXI6NzA0MDEyMjUx",
                        "is_master": false
                    },
                    {
                        "order_id": "T3JkZXI6NzA0MDEyNDc5",
                        "is_master": false
                    }
                ],
                "line_items": {
                    "edges": [
                        {
                            "node": {
                                "sku": "ubik",
                                "quantity": 2
                            }
                        }
                    ]
                }
            }
        }
    }
}

5. Unmerge One Sub-Order

Let’s take the previously inspected sub-order and let’s unmerge it.

Mutation

mutation OrderUnmerge($data: UnmergeOrdersInput!) {
  order_unmerge(data: $data) {
    request_id
    complexity
    order {
      id
      order_number
    }
  }
}

Variables

{
    "data": {
        "order_ids": [
            "T3JkZXI6NzA0MDExOTY1"
        ]
    }
}

Full Response

{
    "data": {
        "order_unmerge": {
            "request_id": "691743e00f71c32691265383",
            "complexity": 5,
            "order": {
                "id": "T3JkZXI6NzA0MDExNjkw",
                "order_number": "custom-test-12"
            }
        }
    }
}

6. Inspect Master After Unmerge

Final inspect to check everything ended as we intended.

Full Response

{
    "data": {
        "order": {
            "request_id": "6917443ee58868c58b5b27b5",
            "complexity": 32,
            "data": {
                "id": "T3JkZXI6NzA0MDExNjkw",
                "order_number": "custom-test-12",
                "fulfillment_status": "pending",
                "created_at": "2025-11-14T13:49:37",
                "updated_at": "2025-11-14T13:49:53",
                "merged_orders": [
                    {
                        "order_id": "T3JkZXI6NzA0MDEyMjUx",
                        "is_master": false
                    },
                    {
                        "order_id": "T3JkZXI6NzA0MDEyNDc5",
                        "is_master": false
                    }
                ],
                "line_items": {
                    "edges": [
                        {
                            "node": {
                                "sku": "ubik",
                                "quantity": 2
                            }
                        }
                    ]
                }
            }
        }
    }
}