Причём тут конкретно многопоточность?
Если дело в том, что в нескольких потоках трудно координировать обращения к API, то как выше правильно сказали - делайте очередь запросов (например, queue.SimpleQueue) и отдельный поток, который будет эти запросы выполнять с учётом лимитов.
Например, так: поток-клиент кладёт в очередь словарь вида
task = {'ready': threading.Event(), 'params': {...тут параметры запроса...} }
, а потом делает
task['ready'].wait()
if 'error' in task:
... # реагируем на ошибку
else:
... # читаем результат из task['result']
Тогда рабочий поток, реализующий обращения, будет принимать очередное задание из очереди, делать запрос к API согласно содержимому params, потом записывать результат в task['result'] или ошибку в task['error'] и делать task['ready'].set(), чтобы уведомить клиента о том, что его задание завершено.