The DS Techeetah driver kept Vandoorne at arms' length in the latter stages of a frenetic second race at the Brooklyn Street Circuit, where a flurry of late yellow flags reduced the Belgian's opportunity to mount a pass.
A pile-up at Turn 6 on the ante-penultimate lap, which involved Jean-Eric Vergne, Lucas di Grassi and Oliver Askew, left the Andretti driver stranded on the corner exit as di Grassi stopped further up the road on the exit of Turn 10, limiting Vandoorne's passing zones to Turn 1.
Despite dwindling energy compared to Vandoorne, da Costa held on to collect his and Techeetah's first win of the year, continuing his turnaround after a difficult start to the campaign.
Da Costa held his pole off the start despite pressure from fellow front-row starter Alexander Sims, but the Mahindra driver looked more concerned by the cars behind him and thus tried to stick with the Portuguese driver.
The leading duo picked up their sole eight-minute attack mode activations on lap 12, with Vandoorne instructed to do the opposite of Sims, which allowed the Mercedes driver to secure the lead for a lap.
Vandoorne then picked up attack mode on the following tour, dropping back to third, but he continued to stick with the frontrunners along with team-mate Nyck de Vries.
But having lost a little ground to da Costa, Sims was then under heavy pressure from Vandoorne who, after a few aborted efforts, finally made his way past on the 22nd lap of 39.
That put Vandoorne onto the back of da Costa, but passing opportunities were at a premium as the Season 6 champion was resolute in defence.
Although Vandoorne mounted an assault with fanboost on lap 35, da Costa was far enough ahead to see that threat off.
But amid the late skirmish at Turn 6 with the cars on the fringes of the points, Vandoorne's opportunities dwindled and thus da Costa was able to cement victory - 24 hours after promising Autosport champagne in the second race.
Mitch Evans collected a hard-fought third place, recovering from a shoulder-barge from de Vries and a subsequent huge slide after hitting a bump in the road on the run to Turn 6 - which he miraculously saved.
Those incidents put Evans down into fifth and some way from the leading quartet, but a series of strong laps from the Kiwi meant that he was able to get back onto de Vries's tail - and the Dutchman then explored the same bump, which handed Evans fourth.
As Sims dropped off the back of da Costa and Vandoorne, he was susceptible to Evans's advances and was dispatched on lap 36 - denying the Mahindra driver a podium.
Sims tailed Evans to the finish but, like Vandoorne, had few opportunities to return the favour - but still claimed his best finish of the season.
De Vries hit the bump ahead of Turn 6 for a second time, which put him into the run-off and allowed Bird to pass - and also could not keep Frijns behind him ahead of the final five laps - and thus had to be content with seventh.
Jake Dennis claimed eighth place ahead of Andre Lotterer, who mistimed his start and shed multiple positions from third on the grid, as Edoardo Mortara benefitted from the late-race Turn 6 scuffle to pop up into the points, having worked his way through from 21st on the grid.
Race-one winner Nick Cassidy could not recover from being sent to the back after his penalty for taking a new battery, where he also had to serve a drivethrough to make up the part of the grid drop he could not serve, but was classified in 16th ahead of Maximilian Guenther - who got a five-second penalty for a clash with Oliver Rowland.
Sergio Sette Camara started fourth, but the limitations of his Dragon Penske package came to the fore and the Brazilian thus fell down the order despite holding his own in the top six in the first part of the race - ultimately finishing 18th.
Result - 39 laps:
|1||Antonio Felix da Costa||Techeetah|
|3||Mitch Evans||Jaguar Racing||3.524|
|4||Alexander Sims||Mahindra Racing||3.631|
|5||Sam Bird||Jaguar Racing||4.412|
|6||Robin Frijns||Virgin Racing||4.979|
|7||Nyck de Vries||Mercedes||6.233|
|8||Jake Dennis||Andretti Autosport||6.316|
|9||Andre Lotterer||Porsche Team||6.590|
|11||Pascal Wehrlein||Porsche Team||18.469|
|12||Dan Ticktum||NIO Formula E Team||23.002|
|14||Oliver Rowland||Mahindra Racing||32.676|
|15||Oliver Turvey||NIO Formula E Team||33.255|
|16||Nick Cassidy||Virgin Racing||39.699|
|18||Sergio Sette Camara||Dragon Racing||1'08.193|
|Jean-Eric Vergne||Techeetah||3 Laps|
|Lucas di Grassi||Venturi||3 Laps|
|Oliver Askew||Andretti Autosport||3 Laps|
|Antonio Giovinazzi||Dragon Racing||12 Laps|
|View full results|