Mohammed Shami made a double strike to tilt the balance towards India on the second day of the series-deciding third Test against South Africa at Newlands on Wednesday.
Keegan Petersen, South Africa's last remaining recognised batsman, led the resistance with 70 not out as South Africa reached 176 for seven at tea, 47 runs behind India's first innings total of 223.
With batting conditions seemingly easier in bright sunshine than on the overcast first day, South Africa reached 159 for four, with Petersen and Temba Bavuma both batting relatively comfortably.
But the consistently accurate Shami produced a ball which climbed on Bavuma, forcing an edge which was taken by Indian captain Virat Kohli at second slip.
Bavuma, who made half-centuries in the first innings in both previous Tests, was out for 28.
Two balls later Kyle Verreynne prodded at a good-length delivery from Shami and was caught behind for nought.
Jasprit Bumrah followed by bowling Marco Jansen for seven with the last ball before tea.
Petersen, whose only previous half-century came in the previous Test at the Wanderers, had to face the third ball of the morning after Aiden Markram padded up and was bowled by an in-swinger from Bumrah without a run added to the overnight 17 for one.
When nightwatchman Keshav Maharaj was bowled by Umesh Yadav for 25, South Africa were precariously placed at 45 for three.
The slightly-built Petersen batted with skill and application in partnerships of 67 with Rassie van der Dussen (21) and 47 with Bavuma before Shami struck.