West Ham broke City's streak of seven consecutive clean sheets at home in all competitions when Michail Antonio scored just before half-time.
"It was really difficult. They have the physicality," City manager Pep Guardiola said after the game.
"After 10-15 minutes today we realise we are not going to paint anything beautiful. Second half we were much better than the first half. When you play a lot of games, in the league and then the Champions League, this is normal.
"We were lucky to get all three points. The mathematics matter at the end of the season."
It took City 30 minutes to score their first against a well set up West Ham side.
The goal added fire to Guardiola's side but West Ham continued to seek their opener which they found through Antonio on 43 minutes.
The goal was the first City have conceded at home since Dec. 15 when they played West Bromwich Albion.
West Ham had a VAR review three minutes into the second half when Lingard went down on the edge of the area. However, replays showed that Fernandinho timed his tackle well and referee Michael Oliver waved away West Ham's calls for a penalty.
David Moyes' side were left rueing their missed chances and lack of possession in the second half when City scored their second of the day.
Riyad Mahrez jinked and dodged around the West Ham defence just inside the penalty box before driving a low, hard cross to Stones who just had to steer it towards the goal.
"A lot of credit must go to West Ham," Stones said after the game.
"We knew what they would do. How they have been playing and their position speaks for itself. All credit. We had to fight them to the last few minutes. We were a bit deflated at half-time.
"We weren't at our free-flowing best as we have been. But that is down to how they set up. West Ham showed great character in the second half."