Rodrigo Rojas
July 21, 2022

If you’ve worked on a digital product, whether as a developer, product manager, or business leader, you know that the most common problems in software development are rarely as straightforward as “bugs.” The root of the problem tends to require a little more trial and error. Using Courier is no different.
In this post, we will discuss example issues around Courier’s Gmail integration and API rate limits, an incomplete data profile, and an incomplete request with Inbox and Toast. We will delve into how such issues can present themselves and how to troubleshoot independently to fix any issues.
Just because an issue is complicated doesn’t mean the solution can’t be simple. Developers are constantly bombarded with jargon and terminology that could frighten even those of us who are more technologically-literate. Despite one’s development experience, programmers have learned how to find solutions through trial and error, pattern matching, and dare I say it - googling.
Needless to say, it’s almost seen as a rite of passage in one’s programming journey. In this post, we’re going to tackle some of the most common, yet crucial hiccups our developers and users come across when integrating Courier into their notification infrastructure. If you’ve come across a hurdle, there’s a good chance that someone else has already figured out how to get across. Gmail integration and API rate limits Congratulations, you’ve successfully signed up to use Courier and are on your way to sending notifications!
Once you’ve gone through the sign-up process and authorized Gmail to send emails on your behalf, you’ll be able to integrate Gmail as a channel to your email notification templates.
Notification looks good, and Gmail is integrated
One recurring issue that has come up with our developers is getting rate limited, i.e 429 errors when sending bulk transactional emails with Gmail integration. It’s understandable, getting 400 response errors isn’t fun. However as developers, Google-fu is one of the many skills required in troubleshooting.
Gmail doesn’t like too many requests
There’s no workaround here. Gmail's API has limitations based on per-method quota usage (250 per second with 100 quota points per SEND). Thus, Gmail is really intended for getting started fast, testing, or small-scale sending. This is a great way for you to get comfortable with using Courier and make your first couple of sends.
Our recommendation is to check out our full list of email providers and choose the best one that will suit your needs depending on your use case. If your intention is to send bulk emails at once, it would be best to choose a provider that will not rate limit you.
It goes without saying - Courier has an extensive list of notification providers our users can integrate into their notification infrastructure. Each of these providers have their own requirements for the profile object in the response.
Without a profile in the request, some of your notifications will not be delivered and tell you why in the response that can be accessed from the message logs.
You’ve integrated your provider and set a channel to your notification. However, the message logs show an ‘Unroutable’ / ‘MISSING_PROVIDER_SUPPORT’ error in the response. This is strange, since you’ve integrated a provider, created a template, and sent a test event.
The best part is that the logs tell you what you’re missing.
This varies by provider and channel, but for some of our most common integrations, i.e - email, the fastest fix to the “unroutable” error is by adding an email recipient to the profile. Courier supports many providers, and you can find each providers’ profile requirements in their respective integration documentation. Depending on whether you’re using email, sms, push, etc to send your notifications, you want to make sure to provide a profile that matches the channel’s needs.
Depending on your channel preference, certain providers have different profile requirements.
Having a valid email recipient in the profile will allow your email notifications to be sent.
In-app notifications require a more detailed profile in the request which will be touched on in the following section.
For argument’s sake, let’s say you’ve integrated Pagerduty to send out notifications for your system alerts. In this case, Pagerduty does not require a profile because an event is mapped to Pagerduty services and not to an individual. So in this case, you can leave the profile empty.
So you’ve decided you wanted a more centralized feed of your notifications and implemented Courier’s Inbox feature in your application. Our demo app certainly makes it look good, and with the additional customization options to match the look of your app and brand, how can one resist. And for our developers using non-react builds, we have embedded integration for you.
The beauty of Toast is that each notification allows developers to communicate a CTA (call to action).
Let’s say you’ve successfully implemented Courier Inbox and Toast in your frontend with the right dependencies, and both Toast and Inbox are children of the CourierProvider component in your application.
Everything looks as it should, and even provided a clientKey as a prop. After being able to send a request and receive no errors in our logs, we see a toast notification pop up in our app, yet if we navigate to our inbox widget, it’s empty.
We can see the widget and 2 notifications, but where did our notifications go?
Before we dive into the answer, let’s take a look at a sample send request in this case.
It’s a subtle oversight, but makes all the difference.
In order for inbox notifications to persist, we need to add to.user_id in the SEND request along with to.courier.channel.
This is for two reasons:
Your request/test event should now look like this:
Copied!
message: {to: {user_id: “user_id”,courier: {channel: “user_id”,}
Once our SEND request includes the above configuration, your inbox messages will persist.
Our team at Courier is constantly working on making improvements, adding support for new features, and fixing bugs. This includes npm/yarn packages for CourierProvider, Toast, and Inbox.
If you wish to update your dependencies, you can update them simply by changing the package.json to the most current version, and running yarn/npm from the root of your project. We invite you to reach out to support should you have any other questions or if you feel like you hit a roadblock.
It’s the nature of the business to always be asking questions particularly in our line of work. This article is merely designed to help answer some of the most common questions we’ve come across with our developers.
With that said, we believe that in order to make software-to-human communication delightful, there needs to be an open line of communication with developers who have implemented Courier to handle their notification infrastructure. We want you to have as many support options as possible whether it’s self-serve through our docs and articles, or 1-1 with our engineers and support staff. We’re here to make your Courier experience as smooth as possible! If you’d prefer enterprise-level support, sign up for a demo request now!

Vibe Coding Notifications: How to Use Courier with Cursor or Claude Code
Courier's MCP server lets AI coding tools like Cursor and Claude Code interact directly with your notification infrastructure. Unlike Knock and Novu's MCP servers that focus on API operations, Courier's includes embedded installation guides for Node, Python, Flutter, React, and other platforms. When you prompt "add Courier to my app," your AI assistant pulls accurate setup instructions rather than relying on outdated training data. OneSignal's MCP is community-maintained, not official. Courier supports 50+ providers, native Slack/Teams integration, drop-in inbox and preference components, and a free tier of 10,000 notifications/month. Configure in Cursor with "url": "https://mcp.courier.com" and "headers": { "api_key": "YOUR_KEY" }.
By Kyle Seyler
January 22, 2026

How Top Notification Platforms Handle Quiet Hours & Delivery Windows in 2026
No platform offers per-template delivery windows in 2026—it's either per-workflow (Customer.io, Knock), per-campaign (Braze), or global settings. This comparison shows exactly how six platforms handle quiet hours and send time controls based on their documentation and API specs. Braze leads on AI timing (23% open rate lift from Intelligent Timing across their customer base). Novu is the only platform letting subscribers set their own delivery windows. Customer.io and Knock require manual workflow configuration. OneSignal's strength is push-specific optimization across 300K+ apps. Courier combines per-node flexibility with API control. Includes feature matrix, timezone handling, and frequency capping differences.
By Kyle Seyler
January 16, 2026

Notification Observability: How to Monitor Delivery, Engagement, and Provider Health
Notification observability is the practice of monitoring notification delivery, engagement, and provider health using the same tools and discipline you apply to the rest of your application infrastructure. It means tracking whether messages are delivered, opened, and acted on across email, SMS, push, and in-app channels, then surfacing that data in dashboards alongside your other application metrics. Key metrics include delivery rate by channel, bounce and failure rates, provider latency, open rate trends, and click-through rates by template. Teams can build notification observability through DIY webhook handlers that pipe provider events to Datadog or Prometheus, log aggregation from application send logs, or notification platforms with built-in observability integrations. This matters most for multi-channel systems, business-critical notifications like password resets and payment confirmations, and teams using multiple providers with fallback routing.
By Kyle Seyler
January 15, 2026
© 2026 Courier. All rights reserved.