Chasing 147 for the win, the hosts were skittled out for 121 during the afternoon session, with spinner Ajaz Patel taking 6-57.
India looked on course for an even heavier defeat when they slipped to 29-5, before a punchy half-century from Rishabh Pant gave them hope.
But Pant’s dismissal for 64 shortly after lunch saw New Zealand regain a grip on the match that they never relinquished.
Pant was given not out on the field but the decision was overturned by the TV umpire, who decided after several replays that the ball had brushed his bat before clipping the pad on the way through to wicketkeeper Tom Blundell.
That left India reeling on 106-7 and they added just 15 runs for the final three wickets, with Patel wrapping up the win to end with match figures of 11-160.
New Zealand had begun the day on 171-9 but added just three runs before Patel was dismissed by Ravindra Jadeja, who took 5-55 to end with match figures of 10-120.
The win keeps New Zealand’s hopes of reaching the World Test Championship final in June alive, but has severely dented India’s chances of reaching it for the third successive time.