HELIOS DOCS
Webhooks

Delivery and retries

The retry schedule, every failure reason, the throughput limits per target, when a delivery expires, when a failing target turns off, and what happens while a target or Helios is paused.

Each event creates one delivery for each target that subscribes to it. Helios sends a delivery in one or more attempts. Every attempt of a delivery carries the same webhook-id, so you can drop duplicates. See delivery and ordering.

A successful attempt

An attempt succeeds when your server answers with a 2xx status within 10 seconds.

  • The 10 seconds cover the DNS lookup, the connection, the TLS handshake and your full response.
  • Helios does not follow redirects. A 3xx fails with redirect.
  • Helios does not store your response body. Each attempt records the status code, the failure reason, the duration and the URL it called.

Do slow work after you reply. Put the event in your own queue and answer at once.

Retry schedule

When an attempt fails because of your server or its network, Helios tries again later. The delay grows after each failure.

AttemptSent after the previous attempt failed
1At once
21 minute
35 minutes
430 minutes
52 hours
66 hours
712 hours
824 hours

After the 8th failed attempt the delivery is failed. That is about 44 hours and 36 minutes after the first attempt. For example, a server that answers 503 for two hours and then recovers gets the event on the 5th attempt, about 2 hours and 36 minutes after the first one.

You can send a delivery again from the delivery history or with helios webhook resend. A resend uses the same webhook-id. A resent delivery gets the full retry schedule again.

Failure reasons

Each failed attempt records exactly one reason. You see it in the delivery history and in helios webhook deliveries.

ReasonWhat happenedNext step
dnsThe host name does not exist, or it has no IPv4 address.Retried
connection_refusedThe connection was refused, reset or closed before a response, or the host was unreachable.Retried
tlsThe TLS handshake failed, or the certificate is not valid for the host name.Retried
timeoutNo full response within 10 seconds.Retried
redirectYour server answered 3xx.Retried
blocked_destinationThe host name resolved to a private, loopback, link-local, multicast or reserved address.Retried
http_4xxYour server answered 4xx.Retried
http_5xxYour server answered 5xx.Retried
internal_errorHelios could not send because of a problem on its side.Retried in 1 minute. Counts toward the 8 attempts only after the delivery's 24 hour expiry time.
target_disabledThe target was paused or turned off before the delivery was sent.Ends the delivery. You can resend it.
expiredThe delivery waited 24 hours without an attempt (see expiry), or its event is no longer stored.Ends the delivery. You can resend it while the event is stored.

An internal_error never marks your target as failing and never turns it off.

Throughput limits

Helios sends each target's deliveries separately, so a slow or failing target never delays another target. These are the default limits.

LimitDefault
Deliveries in flight to one target5
Deliveries sent to one organization per minute600
Deliveries in flight to one destination host, across all Helios organizations20
Deliveries sent to one destination host per minute, across all Helios organizations1,000
Test events per target per hour10
Resends per user per hour60

A target's throughput ceiling is its in-flight limit divided by your response time. With 5 in flight and a 1 second response, one target receives about 5 deliveries per second, or 300 per minute. A faster response raises the ceiling.

  • Waiting is free. A delivery over a limit waits as pending and shows as queued in the history. Waiting does not use an attempt.
  • Live events first. Within one target, Helios sends first attempts of new events before retries, and retries before resends. A large resend never delays new events.
  • Slow targets. After 3 attempts in a row end in timeout, Helios sends to that target one delivery at a time until an attempt ends with anything other than a timeout.
  • Test events and resends count against the organization's per-minute limit and the limits of the destination host. When the host is at its limit, they answer 429. Try again a few seconds later.

If a target needs more, email [email protected] with the target ID. Helios can raise the limits of one target or one organization without a release.

Expiry

A delivery that has had no attempt 24 hours after it was created ends as failed with the reason expired. This happens when a target receives more events than its throughput ceiling for a long time. The target then shows a banner with its limit.

To stop deliveries from expiring, answer faster or ask support to raise the target's limit. Time while Helios paused delivery does not count toward the 24 hours.

Failing targets turn off

A target is marked failing at its first failed attempt. Any 2xx clears the mark. Test events and internal_error attempts never mark a target as failing.

When a target has been failing for more than 3 days, Helios turns it off with the reason failing. Its pending deliveries end with target_disabled. The target shows a banner with two actions.

  • Turn back on clears the failing mark and turns the target on.
  • Resend all failed since sends again every failed delivery since a time you choose, up to 10,000 per run, spread over 30 minutes.

Time while Helios paused delivery does not count toward the 3 days.

Target status

StatusWhat it receives
unverifiedOnly test events. A new target starts here, and a target returns here when its URL changes, with the reason url_changed. It turns on when a test event to the current URL gets a 2xx.
onEvery event it subscribes to.
pausedNothing, except test events an admin sends. An admin paused it.
offNothing, except test events an admin sends. Helios turned it off with a reason: failing (above), owner_lost_access (see access) or version_retired (see versions).

A change to a target applies to the next deliveries. This includes a pause, a new URL, a new payload version and a rotated secret. Requests that are already in flight finish.

Pausing a target has two effects. Make sure you want both.

  • Events that occur while the target is paused are dropped for that target. You cannot resend them later.
  • Deliveries that are still waiting for a retry end with target_disabled. You can resend them after you resume the target.

Pauses by Helios

During an incident, the Helios team can pause delivery for all organizations or for one. A pause by Helios keeps every event and every pending delivery. Nothing is dropped.

When delivery resumes, retry times, the 24 hour expiry, the 3 day failing clock and the 7 day owner deadline move forward by the length of the pause. A pause by Helios never turns your target off and never expires a delivery. While delivery is paused, test events and resends answer 503.

Network

  • The URL must use HTTPS on port 443 and must not contain a user name or password.
  • Before every attempt Helios resolves the host name and checks every address. It refuses private, loopback, link-local, multicast and reserved ranges, so a host name that later resolves to an internal address fails with blocked_destination.
  • Helios connects over IPv4 only. A host name with only AAAA records fails with dns.
  • The certificate must be valid for the host name in the URL.
  • Requests come from a fixed set of IP addresses. See egress IPs to allow them in your firewall.

History and retention

Events, deliveries and attempts are kept for 30 days. Open a target in Settings > Webhooks to see its deliveries, or list them from the CLI.

helios webhook deliveries <target-id> --status failed --since 2026-10-01T00:00:00Z

See CLI webhooks for every filter.

Last updated on