Skip to main content
Finowl never retries a lookup for you. Every attempt that starts a lookup is charged, so automatic retries could double your costs without you noticing. You stay in control of when to try again.

The rules

Safe to resend

rate_limitedquota_exceeded (after topping up)provider_not_configuredNetwork errors before a connection was made

Resend with care

provider_rate_limitedprovider_unavailableprovider_response_unconfirmedaccounting_response_unconfirmedTimeouts on your side

Never resend as is

invalid_inputunauthorizedjson_requiredpayload_too_largenot_found
Safe to resend errors were rejected before any work happened, so trying again costs nothing extra. Resend with care errors happened after the lookup was sent, so the first attempt was already charged. Resending is fine when you need the answer, but do it once, after a delay, and not in a tight loop. Never resend errors will fail the same way every time. Fix the request or the key first.

A retry policy that works

  • Retry at most 2 times.
  • Wait for Retry-After when it is present, otherwise back off exponentially: 2 seconds, then 8 seconds, with random jitter.
  • Only retry “resend with care” errors for requests a user is actively waiting on, such as a password check at sign up. For background jobs, record the failure and move on.

Batches

Never resend a whole batch because some items failed. The successful items were charged and their results are in the response.
  1. Save every item that has data.
  2. Collect the items that have error.
  3. If an item’s error has action: "inspect_billing_before_retry", check your usage before deciding.
  4. Send the failed items again in a new batch, once, if you still need them.
If billing_status is unconfirmed, do not assume failed items were free.

Timeouts

Most lookups finish in well under a second, but Finowl waits up to 35 seconds for a slow lookup before answering with 504 provider_response_unconfirmed. Set your HTTP client timeout to 40 seconds so that you receive Finowl’s answer instead of cutting the connection yourself. If your own timeout fires first, the request may still have run and been charged. Treat it like provider_response_unconfirmed.