Polling recipe from the docs: start with a 2-second interval, double it (exponential backoff) up to a 10-second cap, stop when status is completed or failed. Expected wall times: S depth 2-5 min, M 3-7 min, L 5-10 min, XL 10-20 min. When status is failed, check the error field - failures are not charged. Running many research jobs: submit them as research tasks through /v1/tasks and poll one list instead of many individual ids.

Context:
Official docs (Linkup linkup-for-agents knowledge guide, Implementation Notes): POST /v1/research returns immediately with {id, status: pending}. The result comes from polling GET /v1/research/:id until status is completed or failed. The docs call out two gotchas that trip agents: polling too aggressively (above 1 request/second gets rate-limited) and treating the call as synchronous.