The trouble with API keys that never expire
A key issued years ago, never rotated, and still valid today is not a convenience. It is a liability nobody has actually looked at in years.
A webhook makes sense for an event you cannot predict the timing of: a payment clearing, a shipment status changing, something happening on the provider's side that your system needs to react to whenever it occurs. It makes much less sense as the only way to get an answer to a question you asked directly and expect a direct answer to, like resolving an address or looking up a time zone. Requiring a webhook endpoint just to receive the result of a synchronous lookup pushes real infrastructure work onto a customer who might just want to run a script, wait for a response, and move on.
This becomes a bigger problem specifically for batch and bulk use cases. A developer running a one-off script to resolve a list of addresses from a spreadheet does not want to stand up a webhook receiver, handle retries if their endpoint is briefly unreachable, and correlate incoming webhook payloads back to the original requests, all to get answers that could have come back directly in the response to the call that asked for them. Webhook-only delivery for this kind of task adds an entire layer of infrastructure to a task that should be a single request and a single response.
We treat lookups, including batch and bulk ones, as synchronous by default: you send the request, you get the answer back directly, whether that request contains one item or a thousand. Nothing about using a batch endpoint requires standing up a public-facing receiver just to collect results. A script, a cron job, or a one-off command line tool can call the endpoint and use the response immediately, the same way a single lookup would work.
Webhook-only design tends to come from an architecture built around asynchronous processing on the provider's side, where a large batch job actually takes meaningful time to complete internally, and a webhook is genuinely the more natural way to signal completion. That is a legitimate pattern for some kinds of large-scale or heavily queued processing. It becomes a problem when it is the only option offered, forcing every use case, including ones that would rather just wait a moment and get an answer directly, into an architecture designed for a different, slower kind of workload.
We are not against webhooks existing as an option for genuinely long-running or asynchronous work. We are against making them mandatory for tasks that do not need to be asynchronous at all. A script that wants to send a thousand lookups and get a thousand answers back should be able to do exactly that, in one call and one response, without first building infrastructure to receive a callback for a task that a synchronous request would have handled just as well, with a lot less code involved.