Toolmingo
Guides12 min read

What Is an API? A Complete Beginner's Guide (2025)

Learn what an API is, how APIs work, the different types of APIs (REST, GraphQL, gRPC, WebSockets), and how to use them — with real code examples in JavaScript, Python, and curl.

API stands for Application Programming Interface. In plain terms: an API is a contract that lets two pieces of software talk to each other. One side asks for something; the other side responds — without either side knowing (or caring) how the other is built internally.

If you've ever logged in with Google, checked the weather on a phone app, or embedded a map in a website, you've used an API.


API in 30 seconds

Term What it means
API Application Programming Interface — a contract for software to communicate
Request A message from the caller asking for data or an action
Response The answer — usually data (JSON, XML) or a status confirmation
Endpoint A specific URL or address the API exposes (e.g. /users/42)
Client The app or code making the request
Server The app or service receiving and responding to requests
Authentication Proof of identity sent with a request (API key, token)
# The simplest API call — asking GitHub for a user profile
curl https://api.github.com/users/torvalds
# Returns JSON: name, followers, public repos, etc.

A real-world analogy

Think of a restaurant:

  • You (the client) sit at a table and want food.
  • The menu is the API — it lists what you can order and the exact wording to use.
  • The waiter is the API layer — they carry your order to the kitchen and bring back the food.
  • The kitchen is the server — it does the actual work (cooking), but you never go there yourself.

You don't need to know how the kitchen operates. You just read the menu (the API documentation) and place your order (make a request).


How an API request works — step by step

Client                        Server
  │                              │
  │  1. Client sends a request   │
  │  GET /weather?city=London    │
  │ ─────────────────────────►  │
  │                              │
  │  2. Server authenticates,    │
  │     finds the data           │
  │                              │
  │  3. Server sends a response  │
  │  { "temp": 15, "sky": "cloudy" }
  │ ◄─────────────────────────  │
  │                              │
  │  4. Client uses the data     │

Most web APIs communicate over HTTP — the same protocol browsers use to load web pages. A request has:

  • Method: what action to perform (GET, POST, PUT, DELETE)
  • URL: where to send it (https://api.example.com/users)
  • Headers: metadata (authentication token, content type)
  • Body: optional data payload (for POST/PUT requests)

The response has:

  • Status code: was it successful? (200 OK, 404 Not Found, 401 Unauthorized)
  • Headers: metadata about the response
  • Body: the actual data, almost always JSON

Types of APIs

There are several styles of APIs. Here are the most common:

Type Protocol Format Best for
REST HTTP JSON (usually) Web services, most public APIs
GraphQL HTTP JSON Flexible queries, mobile apps
gRPC HTTP/2 Protobuf (binary) Microservices, high performance
WebSocket WS / WSS JSON or binary Real-time: chat, live feeds
SOAP HTTP / SMTP XML Legacy enterprise systems
Webhook HTTP callback JSON Event-driven notifications

REST (most common)

REST (Representational State Transfer) organises data around resources (things, like users or orders) accessed through URLs with standard HTTP methods.

GET    /users       → list all users
GET    /users/42    → get user #42
POST   /users       → create a new user
PUT    /users/42    → update user #42
DELETE /users/42    → delete user #42

GraphQL

GraphQL lets the client specify exactly which fields it needs — no more, no less.

query {
  user(id: 42) {
    name
    email
    posts {
      title
    }
  }
}

A single request can fetch nested, related data from multiple resources — no extra round trips.

gRPC

gRPC uses a binary protocol (Protobuf) and HTTP/2, making it much faster than text-based REST — preferred in internal microservices.

WebSocket

WebSockets keep a persistent, two-way connection open between client and server, enabling real-time communication (stock tickers, chat apps, multiplayer games).


Reading API documentation

Every API comes with documentation. The key things to look for:

Section What it tells you
Authentication How to prove who you are (API key? OAuth token?)
Base URL The root address all endpoints share
Endpoints Available routes and what they do
Parameters What data you can pass (query params, body fields)
Response format What data comes back and its shape
Rate limits How many requests you're allowed per minute/day
Error codes What different error responses mean

Making your first API call

With curl (terminal)

# GET request — no authentication required
curl https://jsonplaceholder.typicode.com/todos/1

# Response:
# {
#   "userId": 1,
#   "id": 1,
#   "title": "delectus aut autem",
#   "completed": false
# }

With JavaScript (Fetch API)

// GET request
async function getUser(id) {
  const response = await fetch(`https://api.example.com/users/${id}`, {
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP error: ${response.status}`);
  }

  const user = await response.json();
  return user;
}

// POST request — create a new resource
async function createUser(name, email) {
  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name, email })
  });

  return response.json();
}

With Python (requests library)

import requests

BASE_URL = "https://api.example.com"
HEADERS  = {"Authorization": "Bearer YOUR_TOKEN"}

# GET — fetch a resource
response = requests.get(f"{BASE_URL}/users/42", headers=HEADERS)
response.raise_for_status()      # raises exception on 4xx/5xx
user = response.json()
print(user["name"])

# POST — create a resource
new_user = {"name": "Alice", "email": "alice@example.com"}
response = requests.post(f"{BASE_URL}/users", json=new_user, headers=HEADERS)
response.raise_for_status()
created = response.json()
print(created["id"])             # the ID assigned by the server

API authentication — the most common methods

Sending a request without authentication is like walking into a bank and asking for someone's account balance without showing ID. Most APIs require you to prove who you are.

Method How it works Common use
API Key A secret string in a header or query param Simple server-to-server calls
Bearer Token (JWT) A signed token in the Authorization header User-authenticated apps
OAuth 2.0 A flow where users grant apps permission "Login with Google/GitHub"
Basic Auth Base64-encoded username:password in a header Legacy APIs, internal tools
HMAC Signature Request signed with a shared secret Financial APIs, webhooks
# API Key in a header
GET /data HTTP/1.1
X-API-Key: sk_live_abc123def456

# Bearer Token (JWT)
GET /profile HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

HTTP status codes you'll encounter

2xx  ─ Success
  200 OK              ← Standard success
  201 Created         ← Resource created (after POST)
  204 No Content      ← Success, nothing to return (after DELETE)

3xx  ─ Redirect
  301 Moved Permanently
  302 Found (temporary redirect)

4xx  ─ Client errors (you did something wrong)
  400 Bad Request     ← Invalid data in your request
  401 Unauthorized    ← No / invalid authentication
  403 Forbidden       ← Authenticated but not allowed
  404 Not Found       ← Resource doesn't exist
  409 Conflict        ← Duplicate or constraint violation
  422 Unprocessable   ← Validation error
  429 Too Many Requests ← Rate limit hit

5xx  ─ Server errors (the API has a problem)
  500 Internal Server Error
  502 Bad Gateway
  503 Service Unavailable

Public APIs you can explore right now

You don't need credentials for these — great for learning:

API What it does URL
JSONPlaceholder Fake REST API for testing jsonplaceholder.typicode.com
Open-Meteo Weather forecasts, no key needed open-meteo.com/v1/forecast
GitHub Users, repos, issues api.github.com
Cat Facts Random cat facts catfact.ninja/fact
REST Countries Country data (population, capital…) restcountries.com/v3.1/all
NASA Astronomy Picture of the day api.nasa.gov/planetary/apod
# Get today's weather in London (no key needed)
curl "https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12&current_weather=true"

# Get all repos for a GitHub user
curl https://api.github.com/users/torvalds/repos

Building your own API — a minimal example

Most backend frameworks make it easy to expose your data as an API. Here's a working example in Node.js (Express) and Python (FastAPI):

Node.js / Express

import express from 'express';
const app = express();
app.use(express.json());

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
];

// GET all users
app.get('/users', (req, res) => {
  res.json(users);
});

// GET one user
app.get('/users/:id', (req, res) => {
  const user = users.find(u => u.id === Number(req.params.id));
  if (!user) return res.status(404).json({ error: 'Not found' });
  res.json(user);
});

// POST new user
app.post('/users', (req, res) => {
  const { name } = req.body;
  if (!name) return res.status(400).json({ error: 'name required' });
  const user = { id: users.length + 1, name };
  users.push(user);
  res.status(201).json(user);
});

app.listen(3000, () => console.log('API running on http://localhost:3000'));

Python / FastAPI

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()  # Auto-generates /docs Swagger UI

class User(BaseModel):
    name: str

users = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]

@app.get("/users")
def list_users():
    return users

@app.get("/users/{user_id}")
def get_user(user_id: int):
    user = next((u for u in users if u["id"] == user_id), None)
    if not user:
        raise HTTPException(status_code=404, detail="Not found")
    return user

@app.post("/users", status_code=201)
def create_user(user: User):
    new_user = {"id": len(users) + 1, "name": user.name}
    users.append(new_user)
    return new_user

Private vs Public vs Internal APIs

Type Audience Examples
Public (Open) Anyone Twitter API, Google Maps, Stripe
Partner Approved partners with credentials B2B integrations
Private (Internal) Only within your organisation Your frontend calling your backend
Composite Combines multiple API calls into one BFF (Backend for Frontend) pattern

API rate limiting

Rate limiting controls how many requests a client can make in a time window. When you exceed the limit, the API returns 429 Too Many Requests.

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1720101600
Retry-After: 60

{"error": "Rate limit exceeded. Retry after 60 seconds."}

Best practices when hitting rate limits:

  • Implement exponential back-off — wait, then retry
  • Cache responses when the data doesn't change often
  • Use webhooks instead of polling when the API supports it
  • Read Retry-After headers

Common API mistakes (and how to avoid them)

Mistake Why it's a problem Fix
Hardcoding API keys in source code Keys leak via version control Store in environment variables
Not checking status codes Silently processes error responses as data Check response.ok / raise_for_status()
Fetching more data than needed Slow performance, wastes bandwidth Use query params / GraphQL field selection
No retries on transient failures App breaks on temporary network issues Retry with exponential back-off
Ignoring rate limit headers Gets permanently throttled or banned Respect X-RateLimit-* headers
Building without caching Re-fetches unchanged data on every request Cache responses; use ETags / If-Modified-Since
No timeout set Request hangs forever Set connection + read timeouts
Storing raw API responses in DB Schema changes break your app Map to your own data models

REST vs GraphQL vs gRPC — when to use which

REST GraphQL gRPC
Learning curve Low Medium High
Over-fetching Common Eliminated N/A
Real-time Polling / WebSockets Subscriptions Bidirectional streaming
Type safety Manual / OpenAPI Schema-first Strong (Protobuf)
Browser support Native Native Needs proxy
Best for Public APIs, CRUD Flexible queries, mobile Microservices, internal

API vs SDK — what's the difference?

An API is the raw interface — URLs, methods, authentication. You call it yourself using HTTP.

An SDK (Software Development Kit) is a library that wraps an API and provides a developer-friendly interface in a specific language.

// Using the raw Stripe API directly
const response = await fetch('https://api.stripe.com/v1/charges', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${process.env.STRIPE_KEY}` },
  body: new URLSearchParams({ amount: '1000', currency: 'usd', source: 'tok_visa' })
});

// Using the Stripe SDK (much easier!)
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_KEY);
const charge = await stripe.charges.create({ amount: 1000, currency: 'usd', source: 'tok_visa' });

Both do the same thing. The SDK handles authentication, error parsing, and TypeScript types automatically.


Frequently Asked Questions

Q: Do I need to learn APIs to become a developer? Yes — APIs are the backbone of modern software. Whether you're building front-end apps that talk to a backend, or backend services that call third-party tools (payment processors, email services, AI models), you'll use APIs daily.

Q: Is an API the same as a URL? No. A URL is an address. An endpoint is a URL that an API exposes to receive requests. An API is the full set of endpoints, authentication rules, and data contracts — it can have dozens or hundreds of endpoints.

Q: What is a REST API vs a regular API? "API" is the broad term — any interface for software communication. REST is a specific style of API that uses HTTP and organises data around resources. Most web APIs you encounter are REST APIs.

Q: What language should I use to call an API? Any modern language works: JavaScript (fetch or axios), Python (requests or httpx), Go (net/http), PHP (curl), Ruby (net/http), Java (HttpClient), and many others. The API doesn't know or care which language you use — it only sees HTTP requests.

Q: What is an API key and is it safe to share? An API key is a unique identifier (usually a random string) that proves your identity to an API. Never share it publicly — treat it like a password. Never commit it to GitHub or hard-code it in client-side JavaScript that users can see. Use environment variables on the server.

Q: How do I know what an API can do? Read its documentation and use its interactive docs if available (Swagger UI, Postman collections). Most modern APIs provide an OpenAPI spec (a JSON/YAML file describing all endpoints, parameters, and responses) that you can import into tools like Postman or Insomnia.


Key takeaways

  • An API is a contract that lets two pieces of software communicate without knowing each other's internals.
  • Most modern web APIs use HTTP and return JSON — that's called a REST API.
  • Every API call has a request (method + URL + headers + optional body) and a response (status code + body).
  • Authentication (API keys, Bearer tokens, OAuth) proves who you are.
  • Rate limits control how many requests you can make — always respect them.
  • Read the documentation: endpoints, parameters, authentication, and error codes are all there.

The best way to learn APIs is to call a few real ones. Start with a free, keyless API like JSONPlaceholder or Open-Meteo, make some requests with curl or your favourite language, and inspect what comes back.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools