How to Use API in Python

What you’ll build or solve

You’ll call a web API from Python, send parameters or JSON data, and read the response safely.

When this approach works best

Using an API in Python works well when you:

  • Pull data from a service, like user profiles, product catalogs, or exchange rates.
  • Send data to a service, like creating a support ticket or logging an event.
  • Automate a workflow, like syncing records between two tools on a schedule.

Avoid this approach when the data lives in a database you can access directly, or when a service provides an official SDK that already handles auth, retries, and pagination for you.

Prerequisites

  • Python installed
  • You know how to run a Python script
  • Basic understanding of dictionaries (for JSON)

Step-by-step instructions

1) Make a GET request and read the response

Most APIs return JSON. Pass headers for auth and params for filtering.

importrequests

url="https://api.example.com/users"
headers= {"Authorization":"Bearer YOUR_TOKEN"}
params= {"limit":5}

response=requests.get(url,headers=headers,params=params,timeout=10)
response.raise_for_status()

print(response.json())

Option A: Store the token outside your code

importos
importrequests

token=os.environ.get("API_TOKEN","")
headers= {"Authorization":f"Bearer{token}"}

response=requests.get(
"https://api.example.com/users",
headers=headers,
params={"limit":5},
timeout=10,
)
response.raise_for_status()

print(response.json())

What to look for:

raise_for_status() turns HTTP errors into exceptions. Without it, a 401 or 404 can look “successful” until you try to use the response.


2) Handle API errors in a predictable way

APIs fail for normal reasons: bad credentials, missing resources, rate limits, and server errors.

importrequests

url="https://api.example.com/users/123"
headers= {"Authorization":"Bearer YOUR_TOKEN"}

try:
response=requests.get(url,headers=headers,timeout=10)

ifresponse.status_code==401:
print("Unauthorized. Check your token.")
elifresponse.status_code==404:
print("Not found. Check the URL or ID.")
else:
response.raise_for_status()
print(response.json())

exceptrequests.exceptions.Timeout:
print("Request timed out. Try again or increase the timeout.")
exceptrequests.exceptions.RequestExceptionase:
print("Request failed:",e)

What to look for:

A 429 status code usually means you hit a rate limit. Back off and retry later instead of sending more requests.


3) Send data with a POST request

For creating or updating data, APIs often expect JSON in the request body. Use json= so Python sends the right format.

importrequests

url="https://api.example.com/tickets"
headers= {"Authorization":"Bearer YOUR_TOKEN"}

payload= {
"title":"Login issue",
"priority":"high",
"customer_email":"mina@example.com",
}

response=requests.post(url,headers=headers,json=payload,timeout=10)
response.raise_for_status()

created=response.json()
print(created)

What to look for:

Some APIs return the created object. Others return only an ID or an empty body. If .json() fails, print response.text[:200].


Examples you can copy

Example 1: Simple health check

importrequests

r=requests.get("https://api.example.com/health",timeout=10)
print(r.status_code==200)

Example 2: Paginate until there are no more results

This example assumes the API uses page and has_more.

importrequests

headers= {"Authorization":"Bearer YOUR_TOKEN"}
page=1
all_users= []

whileTrue:
r=requests.get(
"https://api.example.com/users",
headers=headers,
params={"page":page,"limit":100},
timeout=10,
    )
r.raise_for_status()
data=r.json()

all_users.extend(data.get("items", []))

ifnotdata.get("has_more"):
break

page+=1

print("users:",len(all_users))

Example 3: Handle rate limiting (429) with a short wait

importtime
importrequests

headers= {"Authorization":"Bearer YOUR_TOKEN"}
url="https://api.example.com/reports"

r=requests.get(url,headers=headers,timeout=10)

ifr.status_code==429:
wait_seconds=int(r.headers.get("Retry-After","5"))
time.sleep(wait_seconds)
r=requests.get(url,headers=headers,timeout=10)

r.raise_for_status()
print(r.json())

Example 4: Upload form data (not JSON)

Some APIs use form-encoded data for tokens or legacy endpoints.

importrequests

url="https://api.example.com/token"
payload= {"username":"demo","password":"demo"}

r=requests.post(url,data=payload,timeout=10)
r.raise_for_status()
print(r.json())

Example 5: Use urllib when you can’t install requests (stdlib only)

This is harder to read than requests, but it works on a locked-down system.

importjson
fromurllib.requestimportRequest,urlopen

url="https://api.example.com/status"
req=Request(url,headers={"Accept":"application/json"})

withurlopen(req,timeout=10)asresp:
body=resp.read().decode("utf-8")

data=json.loads(body)
print(data)

Common mistakes and how to fix them

Mistake 1: Sending JSON as a string in data=

What you might do

importrequests
importjson

payload= {"name":"Naomi"}
r=requests.post(
"https://api.example.com/users",
data=json.dumps(payload)
)

Why it breaks

The server may treat the body as form data, or it may reject the content type.

Fix

Use json= so the request is encoded correctly:

importrequests

payload= {"name":"Naomi"}
r=requests.post(
"https://api.example.com/users",
json=payload,
timeout=10
)
r.raise_for_status()
print(r.json())

Mistake 2: Calling .json() on an error response

What you might do

importrequests

r=requests.get("https://api.example.com/secret",timeout=10)
print(r.json())

Why it breaks

The response might be HTML (like an error page) or an empty body. JSON parsing fails.

Fix

Check the status first, then parse:

importrequests

r=requests.get("https://api.example.com/secret",timeout=10)

ifr.ok:
print(r.json())
else:
print("Error:",r.status_code)
print(r.text[:200])

Troubleshooting

If you see ModuleNotFoundError: No module named 'requests', run pip install requests in the same environment you use to run Python.

If you get 401 Unauthorized, the token is missing, expired, or in the wrong header format. Double-check Authorization: Bearer ....

If you get 403 Forbidden, the token may lack permission, or the API blocks your IP or user agent.

If you get 404 Not Found, the endpoint path or resource ID is wrong, or the API version changed.

If you get 429 Too Many Requests, slow down. Use Retry-After if the server sends it.

If you get requests.exceptions.SSLError, a proxy or custom certificate may be involved. Try the same URL in a browser on the same network, then check proxy and certificate settings.

If .json() raises a JSONDecodeError, print response.text[:200] and confirm the API returns JSON for that request.


Quick recap

  • Use requests.get() for GET and requests.post() for POST.
  • Pass headers for auth, and params= for query parameters.
  • Call raise_for_status() to surface HTTP errors early.
  • Use json= to send JSON bodies.
  • Handle common failures like 401, 404, 429, and timeouts with clear messages.