“If an API exists, someone, somewhere is using it in ways you never intended.“ – Some unfortunate developer, probably.
The Curse of Hyrum’s Law
Hyrum’s Law states:
“With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your API will be depended upon by somebody.“
In simple terms: No matter how much you document, clarify, and warn users, someone WILL find a way to depend on the exact quirks of your API that you didn’t even know existed.
And in fintech, where money is involved, this can go from funny to catastrophic in a matter of milliseconds.
A Fintech Developer’s Worst Nightmare
As fintech developers, we don’t just write APIs; we also have to deal with the potato APIs developed by others. You know the ones:
- Accept payments in mystery currencies.
- Fail silently but still process transactions.
- Have undocumented endpoints that someone, somewhere swears by.
- Require a SOAP request formatted in Morse code to get a proper response.
Example 1: The Mystery of the Potato Transactions
Imagine you’re integrating a third-party payment API. Their documentation is crystal clear:
- process_payment(amount, currency, user_id)
- Accepts payments in USD, EUR, and GBP.
- Returns 200 OK on success.
Everything seems fine… until one day, customer support sends you a message:
“Hey, why did we just process a payment for 3.5 potatoes?“
Wait… what? Potatoes?! 🤨
After digging through logs, you discover that some brilliant developer at this third-party vendor was sending currency values like this:
{
"amount": 3.5,
"currency": "potatoes"
}
Their API, being very forgiving (or outright lazy), defaulted to processing payments in USD when it didn’t recognize a currency. So, congratulations! You just inherited a black-market potato economy. 🥔💸
How Did This Happen?
- The API never documented what happens when an invalid currency is sent.
- Someone noticed this behavior and depended on it.
- Now, if they fix it, everything breaks.
The "Fix" That Broke the World
Determined to solve this madness, the third-party vendor finally pushes a quick fix:
if currency not in ["USD", "EUR", "GBP"]:
return error("Invalid currency")
They deploy it. Life is good.
…until they get a flood of complaints from angry users:
- “Why are our payments failing now?! We’ve been using currency: “potatoes” for years!”
- “Our entire accounting system runs on this behavior!”
- “WHO REMOVED POTATOES FROM THE SYSTEM?!”
And just like that, fixing the bug is now the bug.
Example 2: The Webhook That Never Gave Up
Let’s say you’re working with a bank’s payment gateway that notifies merchants when a payment is successful. Their API promises:
- Webhook URL receives a POST request once per transaction.
- The body contains { “status”: “success”, “transaction_id”: “12345” }.
All seems fine, until one merchant complains:
“Hey, why are we getting 1,000 webhook calls for the same payment?”
Wait… what? 🤨
Turns out:
- If the webhook response isn’t exactly 200 OK, the API keeps retrying forever.
- Some merchants’ systems take too long to process, so they return 504 Gateway Timeout.
- The API doesn’t care—it just keeps sending, like a desperate ex who won’t let go.
So now, you have merchants accidentally processing the same payment 1,000 times because they weren’t ready for this level of clinginess.
Fixing it means:
- Breaking systems that depend on retries.
- Angry merchants who now have to process payments manually.
- Thousands of duplicated transactions that need reversing.
Hyrum’s Law strikes again.
Example 3: The "Invisible" API Parameter
You’re working with a fraud detection API that evaluates transactions. The docs say:
- You must send { “amount”: 100.00, “currency”: “USD” }.
- The API will respond with { “fraud_score”: 0.3 }.
Then, a random fintech startup complains:
“Ever since your last update, our fraud detection is totally broken!”
Wait… what? 🤨
After hours of debugging, you realize:
- The API used to accept an undocumented field { “is_suspicious”: true }.
- Even though it was never in the docs, somebody found it.
- They built their entire fraud system around it.
- The last API update removed it… and now their fraud detection is useless.
So now, you either: ✅ Bring back the undocumented behavior and let people keep relying on it. ❌ Keep it removed and let businesses crumble.
Congratulations! You now have a Schrödinger’s API—if you change it, you break people’s apps, but if you don’t, you’re stuck with it forever.
Lessons From The API Abyss
So, what can we learn from this tragic yet hilarious situation?
1. Every tiny behavior in an API will be relied upon by someone, even if it was never documented.
If an API does anything, someone will find a way to depend on it—whether it was intentional or not.
2. Deprecating a feature is harder than launching a rocket.
Once users depend on an undocumented quirk, removing it will cause an uproar. Even if it was never meant to be used that way.
3. Versioning is your best friend.
Instead of outright breaking things, introduce v2 of your API with stricter checks. Let people migrate at their own pace.
4. When integrating third-party APIs, always expect the unexpected.
Assume that every external API has some potato behavior hidden within it. Always test with edge cases, broken inputs, and ridiculous data.
Final Thoughts: The API You Deserve vs. The API You Get
As fintech developers, we dream of building clean, predictable APIs. But reality is messy, full of potatoes and chaos.
So the next time you’re about to push a “harmless” API update or integrate with a third-party service, just remember:
👉 Somewhere, somehow, someone has built an entire empire on undocumented side effects.
And no matter what you do, Hyrum’s Law will make sure they find a way to break things.
Happy coding (/nerding)! 🤓