What Are API Calls? How to Make One, With Examples
An API call is a request one program sends to another program's API to get data or trigger an action, followed by the response that comes back. On the web, an API call is almost always an HTTP request: your code sends a method (like GET), a URL, some headers and sometimes a JSON body, and the server replies with a status code and usually JSON. To make an API call you need the endpoint URL, any required API key, and a tool to send the request: curl, a REST client, or a few lines of JavaScript or Python.
Below: how API calls work, the parts of a request, and working API call examples you can run right now with curl, JavaScript fetch and Python requests, plus how to handle errors and rate limits.
How API calls work
Every web API call is one round trip:
- Your client builds a request: method + URL + headers (+ body).
- It's sent over HTTPS to the API server.
- The server authenticates you, runs the operation, and builds a response.
- The response comes back: a status code (
200,404,429...), headers, and a body, usually JSON. - Your code parses the body and checks the status before trusting it.
When people say "this app makes 10,000 API calls a day", they mean 10,000 of those round trips. Many APIs bill or rate-limit by the number of calls.
The anatomy of an API request
| Part | What it is | Example |
|---|---|---|
| Method | The action | GET read, POST create, PUT/PATCH update, DELETE remove |
| URL (endpoint) | Where the resource lives | https://api.open-meteo.com/v1/forecast |
| Query parameters | Options after ? |
?latitude=52.52&longitude=13.41 |
| Headers | Metadata | Accept: application/json, Authorization: Bearer <token> |
| Body | Data you send (POST/PUT/PATCH) | {"title": "Hello"} |
And the response:
| Part | What it tells you |
|---|---|
| Status code | 2xx success, 4xx your request was wrong, 5xx the server failed (RFC 9110) |
| Headers | Content type, caching, rate-limit info, Retry-After |
| Body | The data, or an error message |
How to make an API call in 5 steps
Step 1: Pick an API and read its docs
Find the base URL, the endpoint you need, and whether it needs a key. For practice, use an API with no key. Open-Meteo is a free weather API that needs no signup for non-commercial use (as of October 2026, under 10,000 calls per day per its terms). DevHunt keeps a list of more no-key options on its free APIs page, including free weather APIs.
Step 2: Get credentials (if required)
Most production APIs need an API key or OAuth token, sent in a header such as Authorization: Bearer YOUR_KEY or x-api-key: YOUR_KEY. Keep keys in environment variables, never in front-end code or Git.
Step 3: Make the call with curl
curl ships with macOS, Linux and Windows 10+, so it's the fastest way to test any API call:
curl "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m,wind_speed_10m"
Response (trimmed):
{
"latitude": 52.5126,
"longitude": 13.4195,
"current_units": { "temperature_2m": "°C", "wind_speed_10m": "km/h" },
"current": { "time": "2026-10-11T10:30", "temperature_2m": 11.7, "wind_speed_10m": 12.9 }
}
Add -i to see the status line and headers, which is where most debugging starts.
Step 4: Make the same call in code
JavaScript (browser or Node.js 18+, where fetch is built in):
const url = new URL("https://api.open-meteo.com/v1/forecast");
url.search = new URLSearchParams({
latitude: "52.52",
longitude: "13.41",
current: "temperature_2m,wind_speed_10m",
});
const res = await fetch(url, { headers: { Accept: "application/json" } });
if (!res.ok) {
throw new Error(`API call failed: ${res.status} ${res.statusText}`);
}
const data = await res.json();
console.log(`Now: ${data.current.temperature_2m}°C`);
Note the res.ok check. A fetch() promise does not reject on 404 or 500; it only rejects on network failures, so you must check the status yourself (MDN).
Python (pip install requests):
import requests
resp = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={"latitude": 52.52, "longitude": 13.41, "current": "temperature_2m,wind_speed_10m"},
timeout=10,
)
resp.raise_for_status() # raises for 4xx/5xx
data = resp.json()
print("Now:", data["current"]["temperature_2m"], "°C")
Always pass a timeout: by default requests waits indefinitely for a server that never answers (Requests docs).
Step 5: Send data with a POST request
Reading is GET; creating is usually POST with a JSON body. JSONPlaceholder is a free fake API that accepts writes (and pretends to save them):
curl -X POST "https://jsonplaceholder.typicode.com/posts" \
-H "Content-Type: application/json" \
-d '{"title": "My first API call", "body": "Hello", "userId": 1}'
const res = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "My first API call", body: "Hello", userId: 1 }),
});
console.log(res.status); // 201 Created
console.log(await res.json()); // { title: ..., body: ..., userId: 1, id: 101 }
A 201 Created status means the server made a new resource. For an authenticated API, the usual change is one more header: Authorization: Bearer YOUR_API_KEY.
Handling errors and rate limits
Real API calls fail. Handle these cases explicitly:
| Status | Meaning | What to do |
|---|---|---|
400 |
Bad request (malformed JSON, missing field) | Fix the request; don't retry. See 400 Bad Request in REST APIs |
401 / 403 |
Missing/invalid key, or not allowed | Check credentials and scopes |
404 |
Wrong URL or resource doesn't exist | Check the path and IDs |
429 |
Too many requests | Wait, then retry; honor Retry-After |
500-504 |
Server-side problem | Retry with backoff, a few times at most |
A small retry helper that respects Retry-After (in seconds) and backs off exponentially:
async function callApi(url, options = {}, maxRetries = 3) {
for (let attempt = 0; ; attempt++) {
const res = await fetch(url, options);
const retryable = res.status === 429 || res.status >= 500;
if (!retryable || attempt === maxRetries) return res;
const retryAfter = Number(res.headers.get("Retry-After"));
const waitMs = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 500;
await new Promise((r) => setTimeout(r, waitMs));
}
}
Only auto-retry POST calls if the API supports idempotency keys; otherwise a retry can create the same order twice.
Tools that make API calls easier
- curl: always available, great for quick checks and for sharing reproducible requests.
- REST clients (Postman, Insomnia, Bruno, Hoppscotch): save requests, environments and auth. Compared in the best REST clients for developers; free options are on free Postman alternatives.
- SDKs: for big APIs (Stripe, AWS, OpenAI, Anthropic) the official SDK handles auth, retries and pagination for you. See what an SDK is.
FAQ
What are API calls in simple terms?
An API call is your program asking another program for something through its API, like "give me today's weather for Berlin", and getting an answer back. On the web it's an HTTP request and response, usually with JSON data.
What is an example of an API call?
GET https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m is a real API call: it asks Open-Meteo for the current temperature in Berlin and returns JSON. You can paste it into a browser or run it with curl.
How do I use an API for the first time?
Read the API's docs to find an endpoint, get a key if one is required, test one request with curl or a REST client, then move the same request into your code with fetch (JavaScript) or requests (Python), checking the status code before using the data.
What's the difference between an API call and an API request?
In everyday use they mean the same thing. Strictly, the request is what you send, and the call is the whole round trip including the response.
Why do APIs limit the number of calls?
To protect the server and share capacity fairly, and often for billing. When you exceed a limit you'll get 429 Too Many Requests; slow down, cache responses you reuse, and honor the Retry-After header.