Building an Events API: Choosing the Best of 6 Options on AWS

Learn how we evaluated EventBridge, Kinesis, SNS, and SQS FIFO to build a secure, ordered, multi-tenant events API architecture on AWS.

Events API

Table of contents

A look into how we chose an architecture to build our new events API, planned for release in Q3 2026.

Motivation

At EdgeTier, we always want to give our clients as much access to their data in our system as possible. Until now, we’ve provided dedicated single-tenant database exports to allow users to write whatever SQL they want or directly link Tableau, Looker or whatever they want to it. This works well for some workflows, but there has been a clear requirement to give more real-time access to individual updates. We decided that, like many SaaS applications, adding an events API was the way forward. The idea is that our clients can subscribe to any updates of their choosing, and get events based on these subscriptions.

Our Events API’s Requirements

The following were our requirements. While yours may differ, this is probably a best practice list of requirements for most products implementing webhooks in 2026:

  • Events needed to be sent in order: Please read “Ordered Events” if you want to understand why this was important to us, and why it might be for you too.
  • Strong security: Options for this kind of feature include basic authentication, OAuth, HMAC, among others. We had a strong preference for HMAC as it is currently best practice.
  • There needed to be some sensible retry strategy: Things happen, and our clients should be able to recover from an outage on their end easily. More details under “Retries” below.
  • Cost needs to be reasonable.
  • Good observability/monitoring options.
  • Able to handle our current and future volume: Ideally scaling automatically.
  • Easy to set up and maintain.
  • Since our platform exists almost entirely on AWS, this feature can also only use AWS services.

Ordered Events

In our system, the lifecycle of a chat will include events like the chat being created, messages being added, an agent joining, the chat ending etc. We decided it would be extremely difficult for our tenants to handle if the chat creation event was ever sent after one of the others, for example.

Many events APIs ignore this requirement and leave it up to the receiver to manage out-of-order events. This is something we’re painfully aware of, considering the number of systems we integrate with. Knowing the difficulty this can cause, we wanted to avoid it for our end users.

Maybe your use case differs. Some products might even generate entirely isolated events that do not have a time-order significance. If that is the case, you will definitely have more options available to you.

Retries

There are a few schools of thought when it comes to retries in an events API. Some products blame failed deliveries almost entirely on the receiver. Other products are more lenient.

On the two ends of the scale are GitHub, which doesn’t automatically retry (although you can manually trigger them) and Stripe who retry for up to three days. To be fair, in Stripe’s financial use case it is likely much more important that these events are successfully delivered.

A balanced approach is probably best; where your system should attempt some retries, but not so many that you create a massive backlog in your pipelines.

We like our clients, and we recognise that things can go wrong or down sometimes, so a generous retry process is a price worth paying in our opinion.

Possible Solutions

As always with AWS, there are about a million possible ways of doing anything. The options we decided to evaluate were:

  • EventBridge Event Buses
  • EventBridge Pipes
  • SNS
  • Kinesis
  • SQS and Lambda
  • Homemade direct API to webhook solution with no additional services.

EventBridge Event Buses

Initially, this seemed like the winner for us at least. It’s ideal for multi-tenant applications because you can filter events for different subscriptions. However, it does not natively support HMAC or guarantee order, unless you put something like an SQS FIFO somewhere along with it.

Although EventBridge can send custom headers, they can only be static. To support HMAC you could:

  • Include the HMAC signature in the body of the payload. This is a security risk as it would require the receiving webhook to decode JSON before verifying it.
  • Route events to Lambda after the Event Bus. This mostly defeats the purpose of using EventBridge in the first place though.

EventBridge Pipes

EventBridge Pipes is a great solution for getting data from point A to point B. It could be used in a multi-tenant environment, but that would require setting up a new pipe for each tenant. While the creation of that infrastructure could be automated, setting up new infrastructure and the associated monitoring, alerting etc. for each tenant could be overkill.

Whenever you consider an infrastructure-heavy solution like this you need to think about AWS quotas. There is a soft limit of 1,000 pipes per account. While you can request a quota increase you should seriously consider if you want to gamble your product’s ability to scale on AWS granting an increase to your quota.

EventBridge Pipes supports basic authentication, API keys, and OAuth but not HMAC natively. Unlike Event Buses, Pipes does support an “enrichment” step where you could probably implement HMAC.

SNS

For simple use cases, SNS is one of the easiest options. Like EventBridge Event Buses you can set up filters to route events to different endpoints. With SNS FIFO you can guarantee order BUT for some unknown reason it doesn’t support HTTP endpoints. Security options include basic authentication and signed messages.

The cryptographic signing of messages is close to but not quite HMAC. AWS signs the payload with its own keys and the receiver would need to verify that along with the TopicArn to ensure it’s legitimate and from you. This works but it’s not very user-friendly.

SNS is usually more of a “fire and forget” service, you don’t get much in the way of monitoring and if there was a huge burst of events that your tenants’ HTTP endpoints can’t handle there is no queue that can build up, although it does retry. For that reason, it’s not really that appropriate for a webhook use case.

Kinesis

Reading the headline of what Kinesis does makes it sound like a great candidate for an events API. However, it’s just too expensive to support multi-tenancy in most use cases. By default, a blocked stream is going to be blocked for everybody. One dodgy webhook in your implementation could slow down events for everybody.

The solution is to introduce a shard per tenant so they are isolated, but the costs then become too high. You will pay $0.015 per shard hour (eu-west-1 price) i.e. for only 50 tenants that would be ~$540 per month before any processing.

SQS FIFO (with Lambda)

Spoiler: this is what we selected. This approach supports almost everything you need. HMAC can be handled in your Lambda, order is guaranteed by the queue, and it scales well.

The main downside is that it’s less of a managed service like EventBridge, so you do need to write some code. Also some complicated retry policies can be hard to implement. For example, if you wanted exponential backoff over a period of days it’s not as easily achievable as some other options. You can easily do short-term backoff inside your Lambda (what we did) over let’s say 15 seconds, or whatever runtime you accept inside the Lambda. But after that you mostly have to retry on a fixed interval by setting the VisibilityTimeout or by updating the message visibility directly using ChangeMessageVisibility. Generally, this should be enough for webhooks in most use cases.

Direct API to Webhook

This could be the easiest option to implement, depending on how you do it. You just need a function in your application to send an event to a webhook. It’s not really a realistic option though, you will run into these problems:

  • Longer term retries (beyond a few seconds) will require building some background infrastructure anyway like a queue or similar.
  • It will block your API. You need to give webhooks at least a few seconds to process a request. This is extra time added to every request in your API unless you manage to do it completely in the background.
  • In place of a Dead Letter Queue, you will probably need to build a failed event store yourself e.g. in your database.

It will support HMAC though or any authentication under the sun.

Conclusion

There are many ways to implement an events API on AWS. If, like us, you need ordered events and HMAC, choose SQS FIFO + Lambda. If unordered events and non-HMAC security methods are acceptable, then you can still use SQS + Lambda but EventBridge Event Buses is probably the best choice. If you really like spending money, choose Kinesis.

Customer-Focused Leaders Trust EdgeTier

  • codere logo

    "We now have highly detailed understanding of agent performance, not just on key agent metrics, but also on how customers react to our agents and the emotions of our customers feel when talking to our team."

  • EdgeTier Assets - Tui Logo

    "We’re a big business, so getting the right people to agree and fix something hasn’t always been easy. Now we’ve got one version of the truth—it’s much easier to align and act"

  • EdgeTier - Powerplay logo

    "You’ve got an issue, but you don’t know how many people are affected. You don’t know the scale. You don’t even know if it’s real."

Employees avatar purple
Employees avatar yellow
Employees avatar blue

Ready to see results?

Let us help your company go from reactive to proactive customer support.

Unlock AI Insights