Most of a modern app is other people's software. Payments are Stripe, email is Resend, the clever text feature is OpenAI's API. You do not build any of it. What you do build is the thin, fragile seam where your server talks to theirs, and that seam is where the outages and the leaked keys live.

The idea

An is how one program asks another to do something. Your server sends a request to an address the other company publishes, attaches an to prove who is asking, and gets an answer back. That key is a password with a spending limit attached, the other company's servers are not always up, and both facts have to be designed for rather than discovered.

code
   YOUR SERVER                                  SOMEONE ELSE'S SERVER
   +---------------------+   POST /v1/charges   +----------------------+
   |  checkout handler   | -------------------> |  Stripe              |
   |                     |   Authorization:     |                      |
   |  key from an env    |   Bearer sk_live_... |  checks the key      |
   |  variable, never    |                      |  checks rate limits  |
   |  in the repo        | <------------------- |  does the work       |
   +---------------------+   200 / 429 / 503    +----------------------+
                                 |
             +-------------------+-------------------+
             |                   |                   |
          200 ok            429 too many        503 / timeout
          continue          requests            they are down
                            wait and retry      show a real error,
                            with a growing      do not silently
                            delay               pretend it worked

How it works

The key identifies your account and carries permissions. Stripe issues a publishable key that is safe in browser code and a secret key that is not, and a secret key in a frontend file lets a stranger issue refunds from your balance. Most services also let you scope a key down: read-only, one product, one domain. Take the narrowest one that does the job.

Rate limits are the second surprise. Every service caps how many requests you may make per minute, and OpenAI additionally caps tokens per minute, so a loop that calls it once per row will stop working somewhere around row two hundred. The signal is HTTP status 429, and the fix is waiting longer between retries rather than retrying harder.

Then there is failure. A request can succeed slowly, fail cleanly, or time out with you never learning whether the other side did the work. That last case is why payment and email calls need to be safe to repeat: if you retry a charge blindly, you charge twice.

What to do

  1. Keep every key in an environment variable, add .env to .gitignore, and use separate test and live keys. Stripe's test keys start with sk_test_, which makes a mistake visible on sight.
  2. Call third-party services from your server, never from browser code. The one exception is a key the vendor explicitly publishes as public, like Stripe's publishable key.
  3. Decide what the user sees when the call fails, before you ship. "Payment could not be completed, you were not charged" is a design decision, and the default is a blank screen.
  4. Rotate a key the moment it might have leaked. Every dashboard has the button, and it takes a minute.

Where it breaks

Your uptime is now the product of everyone else's. If Resend is down your signup email does not arrive, and no amount of correct code on your side changes that. Vendors also change: prices rise, endpoints get deprecated, an API version you depend on gets retired with six months of notice you did not read. And an AI assistant writing integration code often works from the version it was trained on, which for a service that ships weekly can be a year stale. Check the current docs page for anything that moves money.