DEV Community

Nico Reyes
Nico Reyes

Posted on

Auth token worked in Postman. Python said 401.

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...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}"}
Enter fullscreen mode Exit fullscreen mode

Worked immediately.

What Would've Helped

Logging the raw bytes would've shown it faster:

print(repr(token))  # shows \n characters
Enter fullscreen mode Exit fullscreen mode

Or just always strip tokens when reading from files or env vars:

import os
token = os.getenv("API_TOKEN", "").strip()
Enter fullscreen mode Exit fullscreen mode

Not sure why Postman doesn't show warnings about trailing whitespace in auth headers tho. Would've saved me 2 hours

Top comments (0)