Celery tasks happen asynchronously, so by nature we don’t usually write code that waits on the results.
That said, a Celery task still has access to the database & cache, like normal Python code, so most cases you’d write the results there.
Tasks can also queue up other tasks, so you could chain together Celery tasks once one is done.
Alternatively, create an endpoint in your API that can accept callbacks once a task is finished.
There are a bunch of ways to do it, but ultimately a Celery task is no different from other Django code in your application. It just doesn’t happen inside a web request and isn’t synchronous.