Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To make an API call in Python, send an HTTP request to the documented endpoint, check the response status, and then parse the response body in the format the API returns. For most everyday calls, the third-party requests library is concise; Python’s built-in urllib.request works without installing a dependency.

What an API call does

An API call is an HTTP request to a server endpoint. Your program chooses a method such as GET to retrieve data or POST to submit it, supplies any required path or query parameters and authentication, and receives a response.

The response has three useful parts: a status code that signals the HTTP outcome, headers that provide metadata such as content type, and a body containing the returned representation. A body that looks like JSON does not by itself mean the request succeeded; servers can return JSON error details with an error status.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose Requests or urllib

Consideration Requests urllib.request
Dependency Install the third-party requests package. Included in Python’s standard library.
Typical interface Concise methods and arguments such as params, json, auth, and timeout. Build a Request object and use urlopen; handlers and openers provide more control.
Documented capabilities Sessions, connection pooling, cookies, proxies, streaming, and authentication helpers. Handlers for authentication, redirects, cookies, and proxies.
Timeouts and errors Set a timeout and check status with methods such as raise_for_status(). Set a timeout and handle HTTPError and URLError.

Use Requests when you want a compact interface for common API work. Choose urllib when avoiding an external dependency matters or when its lower-level request and handler model suits your program. In either case, follow the API’s documentation for authentication, limits, expected status codes, and retries.

Make a GET request with Requests

Install Requests in your project environment with python -m pip install requests. The example below reads a bearer token from an environment variable, sends a query parameter, applies a timeout, checks for an HTTP error, and parses JSON:

import os
import requests

url = "https://api.example.com/v1/items"
headers = {"Authorization": f"Bearer {os.environ['API_TOKEN']}"}

response = requests.get(
    url,
    params={"limit": 20},
    headers=headers,
    timeout=10,
)
response.raise_for_status()
data = response.json()
print(data)

Replace the example endpoint and parameters with those documented by the API you are calling. The params argument lets Requests encode query values into the URL rather than requiring you to assemble the query string yourself. A timeout prevents the program from waiting indefinitely for a response.

Send a JSON POST request

For an API that expects a JSON request body, pass a Python dictionary with json=. Requests serializes it as JSON and sets the appropriate content type:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
payload = {"name": "Ada", "active": True}
response = requests.post(
    url,
    json=payload,
    headers=headers,
    timeout=10,
)
response.raise_for_status()
created = response.json()
print(created)

Use the method and fields the endpoint specifies. A POST endpoint may return a JSON object, an empty body, or another representation; only call response.json() when the response is actually JSON.

Make a request with Python’s standard library

urllib.request avoids an installed HTTP-library dependency. This GET example uses a fixed query string, asks for JSON, and catches HTTP errors before general URL/network errors:

import json
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen

request = Request(
    "https://api.example.com/v1/items?limit=20",
    headers={"Accept": "application/json"},
)

try:
    with urlopen(request, timeout=10) as response:
        data = json.load(response)
        print(data)
except HTTPError as exc:
    print("HTTP failure", exc.code)
except URLError as exc:
    print("Network failure", exc.reason)

HTTPError is a subclass of URLError, so catch it first when using separate handlers. For dynamic query values, encode them rather than concatenating unescaped input into a URL. A JSON POST can be built with a Request whose body is encoded JSON bytes and whose headers specify Content-Type: application/json; follow the endpoint’s documented method and body format.

Authenticate without exposing secrets

Authentication is API-specific. Use the documented scheme: common options include a bearer token or API-key header, HTTP Basic authentication, and OAuth. Do not assume that an API key belongs in a query parameter when its documentation calls for a header.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Keep credentials in environment variables or a secret manager, not committed source code.
  • Do not print tokens, include them in exception messages, or write them to logs.
  • Keep TLS certificate verification enabled. Disabling verification hides certificate problems while weakening the connection’s security.
  • Send only the headers and credentials the endpoint requires.

Check status, parse data, and handle errors

Check HTTP success before trusting the body

With Requests, call response.raise_for_status() or explicitly compare the status against the endpoint’s documented success codes before treating the body as a successful result. Calling response.json() only attempts to decode JSON; it does not establish that the HTTP request succeeded.

For code that needs to branch on response details, inspect response.status_code and relevant headers. For example, a content-type header can help determine whether JSON parsing is appropriate. If the API supplies a request ID in a response header, record it with safe diagnostic context so an administrator can correlate a failure without exposing credentials.

Separate transport, HTTP, and parsing failures

  • Connection or timeout failure: the client could not complete the exchange. Check the network, hostname, TLS setup, and timeout value.
  • HTTP error status: the server replied, but the status indicates a problem such as invalid authentication or a request limit. Inspect the status and documented error response.
  • Malformed or unexpected body: the response was not valid JSON or did not contain the fields your program expects. Handle parsing separately and validate needed fields before using them.

Catch the library’s relevant exceptions around the request and parsing steps, and log only safe details such as endpoint, status, and request ID. Avoid logging authorization headers or full URLs if they contain sensitive values.

Retries, timeouts, and reliable API use

Set an explicit timeout on network calls. The right duration depends on the endpoint and operation; the API’s own guidance and your application’s latency requirements should determine it. Requests documents automatic keep-alive and connection pooling, and sessions can be useful when making multiple calls that share connection settings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not retry every failure indiscriminately. Follow the API’s retry guidance and rate limits, especially for status codes such as 429 and temporary server failures. A retry can repeat an operation: for a non-idempotent request such as a payment or create operation, retry only when the API documents a safe mechanism, such as idempotency keys. Apply a bounded retry policy with a delay appropriate to the service rather than looping without limit.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common API-call failures

Symptom Likely cause What to check or do
401 Unauthorized Missing, invalid, expired, or incorrectly formatted credentials. Check the API’s required authentication scheme, token validity, and header name. Keep the token secret while debugging.
403 Forbidden The credentials were accepted but lack access, or a policy blocks the request. Check account permissions, scopes, resource access, and the API’s error details.
429 Too Many Requests The service’s rate limit was reached. Honor the API’s limit and retry instructions, including any wait information in response headers.
Timeout The server or network did not respond within the configured interval. Verify the endpoint and connectivity; set a realistic timeout and use an API-specific retry policy for transient failures.
Connection or TLS error Network resolution, connectivity, or certificate validation failed. Check hostname, network access, and certificate configuration. Do not turn off TLS verification as a workaround.
JSON decoding error The body is empty, malformed, or not JSON. Check status and content type first; inspect a safely captured response body if appropriate, and parse only documented JSON responses.
Request rejected as invalid Wrong method, parameter location, field type, or body format. Compare method, URL, query parameters, headers, and JSON schema with the endpoint documentation.

Or skip the browser setup

If the API call you need is a website screenshot rather than a general REST endpoint, ScreenshotNeo returns a screenshot or PDF from one GET request. Its API also accepts Python calls with Requests:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

See the ScreenshotNeo API documentation for parameters and response details. Cookie banners are accepted and removed before capture, along with supported newsletter popups and chat widgets; those cleanup steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, with response headers identifying the page verdict and billing status. An MCP server provides screenshot tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for ScreenshotNeo: 1,000 screenshots a month, no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Does response.json() mean the API call worked?

No. It only parses a JSON body. Check the HTTP status first, then validate the parsed data.

Should I use a session for repeated Requests calls?

Requests documents sessions and connection pooling. A session is useful when calls share settings or connections; for a single straightforward call, the direct method is simpler.

Can I disable certificate verification to fix an SSL error?

That is not a safe fix. Keep verification on and investigate the certificate, hostname, or network configuration causing the error.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.