Auth token worked in Postman. Python said 401.
Tested an API endpoint in Postman. Token worked perfectly. Copied the exact same token to Python script and got instant 401 Unauthorized.
Spent way too long thinking the API was rejecting my script.
Building a scraper for a client portal that needed Bearer token auth. Got the token from their developer console, threw it into Postman:
GET /api/v1/orders
Authorization: Bearer eyJhbGc...
Response: 200 OK. Perfect.
Copied token to Python:
import requests
token = "eyJhbGc..."
headers = {"Authorization": f"Bearer {token}"}
response = requests.get("https://api.example.com/orders", headers=headers)
print(response.status_code) # 401
Why.
Tried Everything
Thought maybe requests library had weird header handling. Tried adding User-Agent, Content-Type, bunch of random headers people suggested on StackOverflow. Still 401.
Checked token expiration. Valid for 24 hours. Generated new one just in case. Same result.
Logged the actual request with print(response.request.headers). Headers looked identical to Postman. Made no sense.
Trailing Newline
Turns out when I copied the token from their dev console, it had a trailing newline character. Postman trims input automatically so you never see it.
Python didn't trim it. So the Authorization header was literally:
Bearer eyJhbGc...\n
API rejected it because the token validation was checking exact string match.
Fixed it with .strip():
token = "eyJhbGc...".strip() # strip whitespace
headers = {"Authorization": f"Bearer {token}"}
Worked immediately.
What Would've Helped
Logging the raw bytes would've shown it faster:
print(repr(token)) # shows \n characters
Or just always strip tokens when reading from files or env vars:
import os
token = os.getenv("API_TOKEN", "").strip()
Not sure why Postman doesn't show warnings about trailing whitespace in auth headers tho. Would've saved me 2 hours
Top comments (0)