Python API Authentication
Table of Contents + −
In the last lesson you learned POST Requests, where you sent data to a server. But most real APIs will not just let anyone send requests. They first want to know who you are. That checking step is called authentication, and this lesson shows you how to do it from Python.
🤔 Why APIs Need Authentication
Imagine an API that returns the weather. If it is free and open, anyone can call it as much as they like. Now imagine an API that returns your private email, or one that charges money per call. The server cannot just trust every request. It needs to know who is calling.
Here is the pain. You write your code, send a request, and the server replies with 401 Unauthorized. Your code is fine. The server simply does not know who you are yet.
Authentication fixes that. You attach a secret value to your request that proves who you are. The server checks it, then either lets you in or turns you away.
APIs use authentication to:
- Know which account is making the request
- Control what you are allowed to see or change
- Count your usage and bill you for it
- Block you if you misuse the service
🧩 API Keys and Tokens in Plain Words
Two words come up everywhere here: API key and token. They sound technical but the idea is simple.
An API key is like a password the API gives you. It is one long string of letters and numbers. You sign up for the service, it hands you a key, and you send that key with every request. Think of it like the membership card you show at a gym door. The card says “this person is allowed in”.
A token is almost the same idea, but it usually expires. A token is a string that proves you are logged in right now. It often stops working after some time, so you have to get a fresh one. Think of it like a hotel key card. It opens your room this week, then the hotel deactivates it after you check out.
The most common token style you will see is called a Bearer token. “Bearer” just means “whoever carries this is allowed in”. So the request is basically saying: the person carrying this token has access.
Note
You do not need to memorize the difference perfectly. In practice both an API key and a token are just a secret string you attach to your request. The API’s documentation tells you which one it wants and where to put it.
📍 Where the Secret Goes
There are two common places to put your secret: in a header, or as a query parameter in the URL. The API docs tell you which one to use.
| Place | What it looks like | When |
|---|---|---|
| Header | Authorization: Bearer YOUR_TOKEN | Most modern APIs, more secure |
| Query parameter | ?api_key=YOUR_KEY in the URL | Some simpler APIs |
The header way is preferred. A URL can get saved in browser history and server logs, so putting a secret in the URL is a bit riskier.
🔑 Sending a Token in a Header
Let’s send a Bearer token using the requests library. The requests library is third-party, so install it first if you have not already.
This command installs the library you need.
pip install requestsNow here is a request that sends a token in the Authorization header.
import requests
# This is a placeholder. Never put a real key here.token = "YOUR_TOKEN_HERE"
headers = { "Authorization": f"Bearer {token}"}
response = requests.get( "https://api.example.com/profile", headers=headers)
print(response.status_code)print(response.json())Let’s walk through it line by line.
headersis a dictionary. The key is"Authorization"and the value is the wordBearer, a space, then your token.- We use an f-string so the token gets dropped right into the text.
requests.get(...)makes the call and we passheaders=headersso the secret travels with the request.response.status_codetells us if it worked.200means success.401means the server rejected our secret.response.json()turns the reply into a Python dictionary.
The output below is representative example output, since the real reply depends on the live server and your account.
Output
200{'id': 4821, 'name': 'Alex Rivera', 'plan': 'pro'}🔑 Sending a Key as a Query Parameter
Some older or simpler APIs want the key in the URL instead. The requests library makes this clean with the params argument, so you do not have to glue the URL together by hand.
This request sends the key as a query parameter.
import requests
api_key = "YOUR_KEY_HERE"
params = { "api_key": api_key, "city": "London"}
response = requests.get( "https://api.example.com/weather", params=params)
print(response.status_code)print(response.json())The params dictionary becomes the part after the ? in the URL. So requests builds https://api.example.com/weather?api_key=YOUR_KEY_HERE&city=London for you.
Here is representative example output for that call.
Output
200{'city': 'London', 'temp_c': 14, 'condition': 'Cloudy'}⚠️ Never Hard-Code Your Real Key
This is the most important part of the whole lesson, so read it slowly.
The biggest mistake new and experienced developers both make is writing the real secret key directly in the code. Then they push that code to GitHub. Now the key is public. Bots scan GitHub all day looking for leaked keys. Within minutes someone can grab your key, run up a huge bill on your account, or steal your data.
So the rule is simple. The real key never lives in your code. It lives outside, in an environment variable, and your code reads it from there.
An environment variable is a value stored in your computer’s environment, separate from your code files. Your program can read it, but it is not written inside any file you commit to git.
You read it in Python with os.environ.
import osimport requests
# ✅ Good: read the secret from the environment, not from the codetoken = os.environ["API_TOKEN"]
headers = {"Authorization": f"Bearer {token}"}
response = requests.get("https://api.example.com/profile", headers=headers)print(response.status_code)Before running it, you set the variable in your terminal once.
On macOS or Linux you would run this in the terminal.
export API_TOKEN="your-real-token-here"On Windows PowerShell you would run this instead.
$env:API_TOKEN = "your-real-token-here"Now compare the wrong way and the right way side by side.
import os
# ❌ Avoid: the real secret sits in the code and can leak to gittoken = "sk_live_8h2Xa91kLmZ0qPv"
# ✅ Good: the code only names the variable, the secret stays outsidetoken = os.environ["API_TOKEN"]If os.environ["API_TOKEN"] cannot find the variable, it raises a KeyError. To handle that nicely, use os.environ.get with a check.
This version gives a clear message instead of crashing with a confusing error.
import os
token = os.environ.get("API_TOKEN")
if token is None: print("API_TOKEN is not set. Please set it before running.")else: print("Token loaded. Length:", len(token))Caution
Never print the actual secret to the screen or into logs. Printing its length, like above, is fine for checking it loaded. Printing the real value can leak it into log files that other people can read.
⚠️ Common Mistakes
A few things trip people up again and again. The big one is putting the real key straight in the code and then pushing it to GitHub, which makes the key public. Watch out for these too.
- Forgetting the word
Bearerand the space before the token.AuthorizationwantsBearer YOUR_TOKEN, not just the token alone. - Using a token that has expired and wondering why you get
401. Tokens often expire, so you may need a fresh one. - Adding a
.envfile with your secrets but forgetting to list it in.gitignore, so git commits it anyway.
Here is the expired or missing-key case. The server rejects you.
Output
401{'error': 'Invalid or expired credentials'}✅ Best Practices
Keep a few simple habits and you will stay safe. The main one is to read every secret from os.environ and never from a string in your code. Here are the rest.
- Add
.envand any key files to.gitignorebefore your first commit. - Send secrets in the header when the API allows it, not in the URL.
- Treat tokens as short-lived. Refresh them when they expire instead of hard-coding one.
- If a key ever leaks, revoke it in the API dashboard right away and create a new one.
Tip
A handy library called python-dotenv lets you keep your secrets in a .env file and load them automatically. It is third-party. Install it with pip install python-dotenv. Just remember to add .env to your .gitignore.
🧩 What You’ve Learned
You now know how to prove who you are to an API and keep your secret safe.
- ✅ Authentication lets an API know who is calling and what they can access.
- ✅ An API key is like a password the API gives you; a token is similar but usually expires.
- ✅ You attach the secret in a header, often as
Authorization: Bearer YOUR_TOKEN, or sometimes as a query parameter. - ✅ The
requestslibrary sends headers withheaders=and query parameters withparams=. - ✅ Real keys never live in your code. You read them from an environment variable with
os.environand keep them out of git.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does API authentication let the server do?
Why: Authentication is how the server identifies the caller and decides what they are allowed to do.
- 2
Which header format is the standard way to send a bearer token?
Why: The Authorization header expects the word Bearer, a space, then the token.
- 3
Where should your real API key live?
Why: Keep the real secret outside your code in an environment variable so it never gets committed to git.
- 4
In the requests library, how do you send a key as a query parameter?
Why: The params argument builds the part of the URL after the question mark for you.
🚀 What’s Next?
You can now reach protected APIs and get a reply back. The next step is making sense of that reply, since most APIs answer in JSON.