there are a few different patterns that can be useful here, all of which have different trade-offs. in each case, you'll need to think about what failure modes they can have, and what the service needs to do if a single external request fails (either due to network, external service error or unavailability, or invalid input) - will there be retries etc etc, do things need to be rolled back - what is a "partial success"?
you can process the things during the request - if caller needs the responses from the external service right there and then. depending on the number of things and the speed/reliability of the external service this might be slow/unreliable. you can do this either serially or in parallel... this will block that thread while the results are collated, but the server can still handle other requests on other threads.
you can put the things on some sort of queue, and return a status uri back to the caller, and it can get the results when done. this means the caller needs to be a bit more aware and will have some state, but takes the pressure off your service to be "fast". (of course it still can be fast!) - this will be very quick from the http server's point of view.
you can put the things on a queue, and tell the caller, "yup, got it" - if the caller doesn't need to know what the actual results were - also quick at the server.
coroutines or not, it doesn't really change almost anything about these considerations.
if you decide that you need the results of the external calls in the request, then you'd just have a function something like: List<ExernalServiceRequest> -> List<ExternalServiceResponse> and it could implement that however it wanted - either serially, or with coroutines/threads - as far as the caller was concerned it doesn't need to know.