38 38. APIs, API Keys, and Third-Party Services
Modern apps rarely build everything themselves. They “rent” capabilities - payments, logins, email, maps, AI - from specialized companies through APIs. This page explains why, how API keys work and how to keep them safe, how to call an API yourself with curl, and how “Log in with Google” works.
38.1 Why apps use third-party services
Building secure payments or a login system yourself is slow, hard and risky. Specialist companies do it better, and you pay per use or per month. A typical app might use:
| Need | Example services | What you get |
|---|---|---|
| Payments | Stripe | Card payments, subscriptions, receipts, fraud checks |
| Login | Google sign-in, Supabase Auth, Auth0, Clerk | “Log in with Google”, password resets |
| Database and file storage | Supabase, Firebase | A hosted database and file storage (see Hosting and Deployment) |
| Resend, SendGrid, Postmark | Confirmation emails, reminders | |
| Maps | Google Maps Platform | Maps, directions, address lookup |
| AI | Claude API, OpenAI API | Writing, summarizing, classifying, chatting |
Your code talks to these services through their APIs - HTTP requests and JSON responses, just like your own back end (see What Happens on the Server). Most services also offer an SDK: a package (installed with npm, for example) that wraps their API in ready-made functions.
38.2 API keys
An API key is a long string of characters that identifies your app and your account to a service. Most API keys are secret - passwords for programs. The service uses the key to know who is calling, what that caller may do, how much it may use, and whom to bill. Keys often have recognizable prefixes, such as sk-ant- (Claude) or sk_test_ and pk_test_ (Stripe).
Many services show a secret key only once, when you create it. Copy it straight into your project’s .env file (below); if you lose it, create a new one.
38.2.1 Publishable keys vs. secret keys
Some services give you two kinds of keys: a publishable key, made to appear in web pages where anyone can read it, and a secret key, which has full power and belongs only on the server. Unless a service explicitly says a key is safe to publish, treat it as secret. The next chapter, Publishable and Secret Keys, explains the difference, why the server holds the secret keys, and where each key of the course’s task app lives.
38.2.2 Where keys live
Never put a secret key in your code files, in Git, in front-end code, in a screenshot or in a chat message. Instead:
On your computer: put keys in a
.envfile (some frameworks use.env.local) in the project folder and make sure Git ignores it. Your code reads the values as environment variables (see Environment Variables and .gitignore and Keeping Secrets Out of Git).# .env.local - never commit this file STRIPE_SECRET_KEY=sk_test_... ANTHROPIC_API_KEY=sk-ant-...Commit a
.env.examplefile with the same names but no values, so teammates know what to set. (New Next.js projects git-ignore every.env*file, this one included, so first add the line!.env.exampleto.gitignore.)In production: enter the same names and values in your hosting service’s environment variable settings (see Hosting and Deployment).
Some frameworks copy certain environment variables into the JavaScript sent to every visitor’s browser - in Next.js, any variable whose name starts with NEXT_PUBLIC_ (in Vite, VITE_). That is right for a publishable key and a disaster for a secret key. Never give a secret one of those names.
38.2.3 If a key leaks
If a secret key ends up in a public place (a pushed commit, a screenshot, a chat), assume it has been copied - bots constantly scan public repositories for keys. Rotate it immediately: in the service’s dashboard, revoke (delete or “roll”) the key and create a new one, then update your .env file and your host’s settings. Deleting the commit is not enough once it has been pushed. Then check the service’s usage and billing pages for activity you don’t recognize.
38.2.4 Costs and spending limits
Many APIs are usage-based: you pay per request, per email, per payment or - for AI - per token. A bug that calls an API in a loop, or a leaked key, can produce a large bill. Protect yourself:
- Use test modes while developing (for example Stripe’s sandbox keys, which start with
sk_test_and never move real money). - Set spending limits and budget alerts wherever the service offers them.
- Use separate keys for development and production, so you can revoke one without breaking the other.
- Limit how often your users can trigger expensive calls.
When you call an API too often, it may answer 429 Too Many Requests (a rate limit); a missing or wrong key usually gets 401 Unauthorized.
38.3 Try it: call an API with curl
These two public APIs need no key (checked October 6, 2026). Run the commands in Mac Terminal or Git Bash. (On Windows use Git Bash, not PowerShell, where curl can behave differently.)
1. JSONPlaceholder - fake data for practicing:
curl https://jsonplaceholder.typicode.com/todos/1Output:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
It is one JSON object with four fields: two numbers, a text value (the title is fake Latin) and a true/false value.
2. Open-Meteo - real weather data (free for non-commercial use). The URL contains ? and &, so it must be in quotes:
curl "https://api.open-meteo.com/v1/forecast?latitude=40.71&longitude=-74.01¤t=temperature_2m&temperature_unit=fahrenheit"Output (one long line; your numbers will differ):
{"latitude":40.710335,"longitude":-73.99308,"generationtime_ms":0.028848648071289062,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":27.0,"current_units":{"time":"iso8601","interval":"seconds","temperature_2m":"°F"},"current":{"time":"2026-10-06T14:45","interval":900,"temperature_2m":54.8}}
The query string asked for New York City’s coordinates, the current temperature 2 meters above the ground (temperature_2m), in Fahrenheit. In the answer, current_units says the unit is °F and current holds the value (54.8). Times are in GMT. You can also paste the URL into your browser’s address bar: the browser sends the same GET request and displays the JSON.
3. Sending data with POST. JSONPlaceholder also accepts a POST and answers as if it had saved your data (it doesn’t really):
curl -i -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title": "Club fair", "body": "Sign up!", "userId": 1}'Output (headers shortened):
HTTP/2 201
content-type: application/json; charset=utf-8
...
{
"title": "Club fair",
"body": "Sign up!",
"userId": 1,
"id": 101
}
-X POST sets the method, -H adds a header (here: “the body is JSON”), and -d supplies the body. The JSON is in single quotes because it contains double quotes (see Single Quotes vs. Double Quotes), and the \ at the end of a line continues the command on the next line. Status 201 Created and the new id show the “creation” worked.
38.4 The Claude API
As of Oct 6, 2026 · Official docs: Claude API documentation · Get your API key · Pricing · Rate and spend limits · Why the API is billed separately
The Claude API lets developers build Claude into their own apps: your back end sends the conversation to Anthropic’s servers and gets Claude’s reply back as JSON. A club app could use it to draft event descriptions or answer members’ questions. A call looks like this (adapted from the example on the API documentation’s home page):
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}]
}'Notice that the key is not typed into the command: $ANTHROPIC_API_KEY reads it from an environment variable (inside double quotes, so the shell fills it in). Claude’s answer comes back inside the JSON’s content, and a usage section reports how many tokens the call used.
What to know before you use it:
- Separate from a Claude subscription. API use is set up and paid for in the Claude Console (
platform.claude.com), usually with prepaid usage credits. A Pro or Max subscription does not include API access. - Pay per token. You pay for input tokens (what you send) and output tokens (what Claude writes), priced per million tokens, at different prices for different models (current prices: see Claude Models, Plans, and Usage Limits).
- Keys: create one in the Console under Settings → API keys. It starts with
sk-ant-and is shown only once. Store it in the environment variableANTHROPIC_API_KEY, which the official SDKs read automatically. It is a secret key: server only. - Limits: the Console’s Billing page lets you set a monthly spend limit below your account’s cap - set one before you experiment.
38.5 OAuth: “Log in with Google”
OAuth (short for Open Authorization) is the standard behind buttons such as “Log in with Google” and screens such as “Allow this app to see your calendar”. It works like a valet key: the app gets limited access without ever seeing your password.
- Your app sends the user to Google’s sign-in page.
- The user signs in at Google and approves what your app asked for (for example, name and email address).
- Google sends the user back to your app, at a redirect URL you registered in advance, with a one-time code.
- Your back end exchanges that code with Google - using your app’s secret - for proof of who the user is.
To set this up, you register your app with Google and receive a client ID (public) and a client secret (server only), and you list the redirect URLs Google may send users back to - typically one for localhost and one for your real domain. If a URL isn’t on that list, Google refuses with a redirect_uri_mismatch error. In practice, a login service such as Supabase Auth handles most of these steps for you.
Practice Questions
Easy
Question 1 · Short answer
What is an API key, and what does the service use it for?
Question 2 · Matching
Match each need with a service that provides it.
| Need | Service | |
|---|---|---|
| 1. Accept card payments | A. Resend | |
| 2. Send reminder emails | B. Claude API | |
| 3. “Log in with Google” | C. Stripe | |
| 4. Generate event descriptions | D. Google sign-in (OAuth) |
Question 3 · Multiple choice
During local development, where should your app’s secret API key be stored?
- In a JavaScript file, in a variable named
apiKey - In a
.envfile that is listed in.gitignore - In the project’s
README.md, so teammates can find it - In a variable named
NEXT_PUBLIC_API_KEY
Question 4 · True or false
A Claude Pro subscription includes access to the Claude API.
Question 5 · Fill in the blank
With “Log in with Google”, the user types their password into ______’s page, and your app receives ______ instead of the password.
Medium
Question 6 · Read the JSON
In the Open-Meteo output on this page: what was the temperature, in which unit, and in which time zone is the time value?
Question 7 · Find the bug
Maria (Mac) types this and gets zsh: no matches found:
curl https://api.open-meteo.com/v1/forecast?latitude=40.71&longitude=-74.01¤t=temperature_2mWhat is wrong, and what would the same command do in Sam’s Git Bash?
Question 8 · Write the command
Write a curl command that gets user number 3 from JSONPlaceholder (the address pattern is the same as for todo number 1).
Question 9 · Short answer
In the POST example on this page, explain -X POST, -H "Content-Type: application/json", -d '...', and why the JSON is in single quotes.
Question 10 · Scenario
A teammate’s .env.local contains NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_.... What is wrong, and how should it be fixed?
Question 11 · Short answer
How is the Claude API priced? What are input tokens and output tokens?
Question 12 · Scenario
Your app’s call to an API returns 401. Later, under heavy use, it returns 429. What does each most likely mean?
Hard
Question 13 · Scenario
Sam accidentally committed his ANTHROPIC_API_KEY and pushed to a public GitHub repository. Ten minutes later he deleted the file and pushed again. Is he safe? What should he do?
Question 14 · Scenario
The club app will use the Claude API to draft event descriptions. Should the browser call the Claude API directly, or should your back end? Describe the flow.
Question 15 · Long answer
Your app uses a paid AI API. Describe at least four things you would do to avoid a surprise bill.
Question 16 · Scenario
“Log in with Google” works on http://localhost:3000, but on the deployed site Google shows redirect_uri_mismatch. What is the likely cause and fix?
Question 17 · Hands-on
Change the Open-Meteo command to show the current temperature in your city (look up its latitude and longitude). Then ask Claude Code to write a small script that prints just the temperature in a friendly sentence. Read the script before running it: which URL does it call, and does it need a key?