Most people using a travel app never think about API keys
And they shouldn’t have to.
You open an app, search for a destination, check the weather, compare places or plan a trip. Somewhere behind that simple tap, however, the app may be communicating with several different services.
Weather data has to come from somewhere. Maps have to come from somewhere. Artificial intelligence, databases, images and other services all have their own systems behind them.
And many of those systems use something called an API key.
Recently, while working on WhisperingPlaces, we learned a rather uncomfortable lesson about them.
Someone got hold of one of ours.
First: What Is an API Key?
Think of an API as a door between two pieces of software.
WhisperingPlaces might ask another service: What’s the weather going to be like in Lisbon? Or it might request information needed to help analyse a destination.
The external service needs to know who’s making the request. One common way of identifying the application making it is through an API key.
It can look like a long, meaningless combination of letters and numbers. But depending on the service and how the key is configured, someone who obtains it may be able to make requests that appear to come from the legitimate application.
That’s where things can become expensive. Because many APIs aren’t free.
The Moment You Realise Something Is Wrong
There is a peculiar moment in software development when numbers stop making sense.
Traffic doesn’t look right. Usage doesn’t correspond with what your users could realistically be doing. Requests appear that you didn’t expect.
At first, there are plenty of innocent explanations. Maybe a feature is calling an API more frequently than expected. Maybe there’s a bug. Maybe some background process is running unnecessarily. Maybe your analytics are misleading you.
And then there is another possibility:
What if those requests aren’t coming from your app at all?
That’s the possibility no developer wants to discover. But ignoring it doesn’t make it disappear.
The Key Wasn’t the Most Important Lesson
Our immediate priority was obvious: stop the unauthorized use and secure the service.
But once the immediate problem was dealt with, a more interesting question appeared:
How could we make it harder for something like this to happen again?
Simply replacing a compromised key isn’t necessarily enough.
If you replace a key and put the new one back into exactly the same vulnerable situation, you haven’t really solved the underlying problem. You’ve changed the lock while leaving the key under the doormat.
That realization changed the way we thought about parts of WhisperingPlaces.
Mobile Apps Have an Awkward Security Problem
There is something slightly counterintuitive about mobile development.
When you install an app, the application has to exist on your device. That means developers should assume that determined people can inspect what is shipped inside an application.
Renaming a variable doesn’t make a secret safe. Moving a sensitive value into another file doesn’t automatically make it safe. Obfuscating code can make reverse engineering harder, but “harder to find” and “secure” are not the same thing.
For genuinely sensitive credentials, a much stronger architecture is often to avoid giving the secret to the mobile app in the first place.
Phone → Your backend → External API
The secret remains on infrastructure controlled by the developer rather than being distributed to every device running the application.
That doesn’t magically solve security. The backend itself has to be protected against abuse. But it changes the problem dramatically.
Not Every API Key Is Actually a Secret
This was another useful lesson. The term “API key” can be misleading because not every API key serves the same purpose.
Some keys are designed to identify an application and can safely exist in client software when they are properly restricted. Others grant access to services that should never be exposed directly inside a mobile application.
For example, Firebase API keys are generally identifiers rather than authorization credentials. Access to Firebase data should instead be controlled through mechanisms such as Security Rules, IAM and App Check.
Other credentials require very different treatment.
So the lesson isn’t simply: “Never put an API key in an app.”
It’s: Understand exactly what each credential can do, what an attacker could do with it, and what restrictions protect it.
Restrictions Matter More Than They Sound
Imagine losing a hotel room key.
Now imagine that same key only works on one floor, on one particular door, during a limited period, and nowhere else.
Losing it is still a problem. But the potential damage is much smaller.
API restrictions work on a similar principle. Depending on the service, a key may be restricted to particular APIs, applications, websites, IP addresses or other conditions.
In other words: A key shouldn’t automatically be allowed to open every door just because it’s a valid key.
That principle sounds obvious after something goes wrong. It is considerably easier to underestimate beforehand.
Security Isn’t a Feature You Finish
This may have been the biggest lesson of all.
When you’re building a small product, there is always another visible feature demanding attention: a better search, a nicer interface, another destination, better recommendations, faster results or a new travel tool.
Security work is different. When it works perfectly, users see absolutely nothing.
There is no shiny new button saying: “Congratulations! Today nothing terrible happened.”
But invisible work can be some of the most important work in an application.
Building WhisperingPlaces has gradually taught us that security can’t simply be something you “do” shortly before publishing an app. It has to become part of the architecture.
What We Changed in the Way We Think
The incident led us to adopt a much more defensive mindset.
Before integrating a service, the questions are no longer only: Does it work? and How much does it cost?
We also ask: Does this credential need to be on the device at all? Can the key be restricted? What happens if somebody extracts it? Can unusual usage be detected? Can an attacker generate costs without being a legitimate WhisperingPlaces user? Can sensitive requests be moved behind infrastructure we control?
These questions aren’t particularly exciting. Until the day they become extremely exciting.
What Other Indie Developers Can Learn From Our Mistake
1. Know which credentials are actually secrets. Don’t assume every API key has the same security model.
2. Don’t rely on hiding sensitive credentials inside an app. If a credential genuinely has to remain secret, shipping it to users’ devices deserves serious reconsideration.
3. Restrict keys wherever the provider allows it. Give credentials the smallest amount of access necessary.
4. Separate services and credentials where practical. One compromised credential shouldn’t automatically expose everything else.
5. Watch your usage. Unexpected API traffic isn’t necessarily an attack, but it deserves investigation.
6. Think about abuse before thinking about scale. You don’t need millions of users before somebody notices your application.
7. Treat an incident as an architectural lesson. Rotating a key can stop an immediate problem. Understanding why the problem was possible can prevent the next one.
Why Are We Telling You This?
We could have said nothing.
From a marketing perspective, admitting that something went wrong might seem like a strange decision. But WhisperingPlaces is being built in the real world.
Real software development isn’t a perfectly straight line from idea to finished product.
Things break. Ideas that looked good turn out not to be good enough. Unexpected problems appear. Sometimes someone even gets hold of something they weren’t supposed to have.
What matters is what happens next.
Every problem we encounter teaches us something about how to build WhisperingPlaces better and occasionally those lessons might be useful to somebody else too.
So from time to time, alongside stories about destinations, overtourism, weather, hidden places and smarter travel, we’ll share some stories from behind the app as well.
Not because everything went perfectly. But because it didn’t.
And sometimes that’s where the interesting stories begin.
Building WhisperingPlaces
WhisperingPlaces is an independent travel app designed to help travellers look beyond the postcard: comparing destinations, checking conditions before booking, discovering places and making more informed travel decisions.
We’re still building it.
And apparently, the journey behind a travel app can occasionally be almost as unpredictable as travelling itself.