Aiden McGeady’s 31st-minute goal ultimately proved the difference between the two sides at the Stadium of Light as the Black Cats extended their impressive unbeaten home league run to 11 matches.
But Jack Payne thought he’d snatched a late equaliser for the Bantams when his effort, which looked to have crossed the line, was not given.
Goalkeeper Jon McLaughlin got a hand to Payne’s shot but, even though he took the pace off the effort, the ball looked to have gone in.
However, referee Darren England waved away the visitors protestors and they are still without an away league win since October 2.
“I didn’t have a clear view but I’ve seen the replay afterwards and the goalkeeper’s body is behind the line,” insisted Caddis.
“Clearly the ball is in, but these things happen. It’s difficult to take. The referee has made the wrong decision though, and that could be vital for us this season.
“There wasn’t much in the game, but it was fine margins.
“We gave a good account of ourselves and we defended well, but it was that final goal which was the difference.”
David Ball rifled over with a free-kick early on for the Bantams, while at the other end Lynden Gooch shot wide for the Wearside hosts.
McGeady forced a save from visiting goalkeeper Richard O’Donnell and Eoin Doyle shot wide as City pushed for an opener.
But Payne wasted a good chance soon after when he fired wide when he should have done much better.
Then McGeady slotted home the opener after O’Donnell had initially saved, firing into the bottom right corner with a sweet left-foot strike.
McGeady had an effort saved on the stroke of half-time and Gooch and Josh Maja had good chances to put the game to bed, but they both failed to take their opportunities.
George Miller had a shot charged down at the other end as the Bantams kept battling for a point, but Duncan Watmore went agonisingly close to a second goal when he had a header saved with a minute remaining.
Payne thought he’d snatched a point with his 81st-minute effort but – to the Bantams’ frustration – it was to no avail.
Sunderland: McLaughlin, O’Nien, Flanagan, Baldwin, Oviedo, Power, Cattermole, Gooch (Wyke 84), McGeady, Maguire (McGeouch 87), Maja (Whatmore 76). Unused substitutes: Ozturk, James, Sinclair, Ruiter.
Bradford City: O’Donnell, Caddis, Knight-Percival, McGowan, Chicksen (O’Connor 88), Payne, Akpan (Brunker 85), O’Brien, Ball, Doyle (O’Brien 80), Miller. Unused substitutes: Wilson, Wood, Devine, Goldthorp.
Referee: Darren England (South Yorkshire).