You could use some of the rxjs operators to handle that.
The one I suggest is windowCount
import { fromEvent, windowCount, delay, skip, mergeAll } from 'rxjs';
uploads$.pipe(
windowCount(3),
delay(3000),
concatMap((r)=>callYourApiHere(r))
);
// ....
And just use a uploads$ behaviour Subject to emit on every upload.
here is a better example
import { fromEvent, windowCount, delay, skip, mergeAll,of, switchMap, Subject, tap, concatMap } from 'rxjs';
const bh = new Subject()
const result = bh.pipe(
windowCount(3),
concatMap((a)=>of(new Date().getSeconds()).pipe(tap(()=>{console.log("API CALLED")}),delay(2000)))
);
result.subscribe(x => console.log(x));
for(let i of [1,2,3,4,5,6,7,8,9]) {
bh.next(i)
}