Indian seamer Mohammed Shami claimed his 200th Test wicket and completed figures of 5/44 as hosts South Africa were bowled out for 197 on the third day of the first Test on Tuesday.
India reached 16/1 in their second innings at the close, a lead of 146 that already looks imposing for the home side on a Centurion Park wicket that will get harder to bat on.
First-innings centurion K L Rahul (five batting) and nightwatchman Shardul Thakur (four batting) will resume on the fourth day.
Mayank Agarwal (four) was the only wicket to fall in India's second innings as he edged debutant left-arm seamer Marco Jansen to wicketkeeper Quinton de Kock.
Eighteen wickets fell on the third day after no play was possible on Monday due to rain.
Shami led the Indian attack with a superb bowling display, eking out every ounce of assistance from the helpful conditions.
His haul included the wicket of South Africa's top-scorer Temba Bavuma, who had reached 52 when he edged to wicketkeeper Rishabh Pant.
Bavuma put on 72 for the fifth wicket with De Kock (34) before the latter tried to guide a Thakur (2/51) delivery through gully but succeeded only in playing onto his own stumps.
It was a key moment in the game that swung the momentum back in India’s favour and exposed the South African lower order.
Shami is the 11th Indian bowler to pick up 200 Test wickets. He is also the fifth Indian pacer after Kapil Dev (434), Javagal Srinath (236), Zaheer Khan (311) and Ishant Sharma (311) to reach the milestone.
All the Indian seamers were among the wickets, Jasprit Bumrah (2/16) weighing in despite rolling his ankle and being forced to leave the field. He returned late on to pick up the last wicket.
Seamer Lungi Ngidi had earlier taken 6/71 as South Africa made light work of bowling India out after the visitors resumed on 272 for three.
Ngidi, who took a career-best 6/39 on debut against India at Centurion in 2018, helped South Africa claim the last seven wickets for the addition of only 55 runs in 15.3 overs.