What an API is and why you build one
An API (process Programming Interface) is a set of rules that lets one piece of software talk to another. When you build an API, you are creating a way for other programs — or other parts of your own program — to request data or trigger actions without needing to know how your code works inside.
Most APIs you encounter work over the web using HTTP requests. A client (like a browser or mobile app) sends a request to your API, your server processes it, and sends back a response. You build an API when you want to let external applications use your data or services, or when you want to separate the front-end code (what users see) from the back-end code (where the work happens).
The most common type of API you will build is a REST API, which uses standard HTTP methods (GET, POST, PUT, DELETE) to perform operations. This guide covers how to build one from the ground up.
Key Takeaways
- A REST API uses HTTP methods to let other programs request or change data on your server without needing direct access to your code.
- You need a server framework (like Express for Node.js, Flask for Python, or Laravel for PHP), a way to store data (a database), and a tool to test your endpoints as you build.
- Each API endpoint is a URL that responds to a specific HTTP method and returns data in JSON format, which most programming languages can read.
- Testing your API with Postman or your browser's developer tools lets you verify each endpoint works before other developers use it.
- Documentation that shows what each endpoint does, what data it expects, and what it returns is as important as the code itself.
Choose a server framework and set up your project
You cannot build an API without a server framework — the software that listens for incoming requests and sends responses. The framework you choose depends on what programming language you already know or want to learn.
Node.js with Express is the most common choice for beginners. Node.js lets you write server code in JavaScript, and Express is a lightweight framework that handles routing (matching URLs to code) and responses. To start, install Node.js from nodejs.org, then create a new folder for your project and run npm init in your terminal to create a package.json file. Then install Express with npm install express.
Python with Flask is another popular option, especially if you know Python. Flask is simpler than Django (a larger framework) and good for learning. Install Flask with pip install flask after you have Python installed.
PHP with Laravel works if you are already using PHP for a website. Laravel handles routing and database connections with less boilerplate code than older PHP frameworks.
Whichever you choose, create a main file (like server.js for Express or app.py for Flask) where your API will start. This file will define your endpoints and tell the server what port to listen on (usually port 3000 or 5000 for local testing).
Define your endpoints and HTTP methods
An endpoint is a URL path that your API responds to. Each endpoint handles one type of request. For example, if you are building an API for a to-do list, you might have endpoints like /todos (to get all to-dos or create a new one) and /todos/1 (to get, update, or delete the to-do with ID 1).
Each endpoint responds to one or more HTTP methods. GET retrieves data without changing anything. POST creates new data. PUT or PATCH updates existing data. DELETE removes data. A single URL can have multiple methods — GET /todos returns all to-dos, while POST /todos creates a new one.
In Express, you define an endpoint like this: your code listens for a GET request to /todos, and when it arrives, your function runs and sends back a JSON response. In Flask, you use a decorator to mark which URL and method each function handles. The pattern is the same in every framework: match the incoming request to a function, run that function, and return data as JSON.
Start with the endpoints you actually need. Do not build every possible endpoint at once. Build one (like GET /todos), test it, then add the next one.
Connect a database to store and retrieve data
Your API needs somewhere to store data so it persists after the server restarts. A database is that storage. The two main types are relational databases (like PostgreSQL or MySQL, which store data in tables with rows and columns) and document databases (like MongoDB, which store data as JSON-like documents).
For a beginner API, PostgreSQL or MySQL are reliable choices. You can install PostgreSQL locally or use a free tier on a service like Render or Railway. Once your database is running, you need a library in your code to connect to it and run queries. In Node.js, use a library like pg (for PostgreSQL) or mysql2. In Python, use psycopg2 or SQLAlchemy.
Alternatively, use an ORM (Object-Relational Mapping) library like Sequelize (Node.js) or SQLAlchemy (Python). An ORM lets you write database operations in your programming language instead of writing raw SQL, which is faster to learn.
Your endpoint functions will now query the database. When someone calls GET /todos, your code runs a SELECT query, gets the results, and sends them back as JSON. When someone calls POST /todos with new data, your code runs an INSERT query to store it.
Test your endpoints with Postman or your browser
Postman is the standard tool for testing APIs while you build them. read it from postman.com, then create a new request. Enter your endpoint URL (like http://localhost:3000/todos), choose the HTTP method (GET, POST, etc.), and click Send. Postman shows you the response your API sent back, the status code (200 for success, 404 for not found, 500 for server error), and the response time.
For straightforward GET requests, you can also test in your browser by typing the URL directly in the address bar. Your browser will show the JSON response. For POST, PUT, or DELETE requests, you need Postman or a similar tool because browsers only send GET requests from the address bar.
When testing a POST request, Postman lets you add data in the request body (usually as JSON). For example, to create a new to-do, you send JSON like {"title": "Buy milk", "done": false} to the POST /todos endpoint. Your API receives it, stores it in the database, and sends back the new to-do with an ID assigned.
Test every endpoint and every HTTP method. Try sending bad data (like a missing required field) and verify your API returns a clear error message. Test with an ID that does not exist and verify it returns a 404 status code. This testing now saves you from bugs later.
Return data in JSON format and set the right status codes
JSON (JavaScript Object Notation) is the standard format for API responses. It is human-readable and every programming language can parse it. When your endpoint sends data back, format it as JSON: {"id": 1, "title": "Buy milk", "done": false} for a single to-do, or [{...}, {...}] for a list.
HTTP status codes tell the client whether the request succeeded or what went wrong. Always set the right one. 200 OK means the request succeeded and you are returning data. 201 Created means a POST request succeeded and a new resource was created. 400 Bad Request means the client sent invalid data (like a missing required field). 404 Not Found means the resource does not exist. 500 Internal Server Error means something broke in your code.
In Express, you set the status code with res.status(200).json({...}). In Flask, you return a tuple like return {...}, 200. Sending the right status code helps other developers (or your front-end code) know what happened without having to read the response body.
When an error occurs, return a JSON object that explains it: {"error": "To-do not found"} instead of just a status code. This makes debugging much easier for whoever uses your API.
Document what each endpoint does
Documentation is not optional. Without it, other developers will not know how to use your API, and you will forget how it works in three months. Write documentation that shows the endpoint URL, the HTTP method, what data it expects, what it returns, and example requests and responses.
The simplest approach is a README file in your project folder with a table or list of endpoints. For example:
GET /todos — Returns all to-dos. No request body needed. Returns a JSON array of to-do objects. POST /todos — Creates a new to-do. Request body: {"title": "string", "done": "boolean"}. Returns the new to-do object with an ID. GET /todos/:id — Returns a single to-do by ID. Returns the to-do object or a 404 error if not found.
For a more professional API, use Swagger (also called OpenAPI). Swagger is a standard format for API documentation that also generates an interactive interface where developers can test your endpoints without leaving the documentation. Tools like Swagger UI read a Swagger file and display it as a web page.
Include example responses so developers know exactly what shape the data will be. Include error responses too — what does the API return if someone tries to create a to-do without a title?
Deploy your API so others can use it
While you are building, your API runs on your local machine (localhost). To let other people use it, you need to deploy it to a server that is always running and has a public URL.
Render, Railway, Heroku, and AWS all host APIs. Render and Railway have free tiers and are beginner-friendly. You connect your code repository (like GitHub), and the service automatically deploys it whenever you push changes. You also need to deploy your database — most of these services offer managed databases.
Before deploying, make sure your code does not have hardcoded secrets (like database passwords). Use environment variables instead. Create a .env file locally with your secrets, and tell your hosting service what those variables should be in production.
After deployment, test your API again using the public URL instead of localhost. Verify that all endpoints work, that the database is connected, and that errors are handled gracefully.
Frequently Asked Questions
What is the difference between REST and GraphQL?
REST uses multiple endpoints, each returning a fixed set of data. GraphQL uses a single endpoint where the client specifies exactly what data it wants. GraphQL is more flexible but harder to learn. Start with REST.
Do I need authentication if my API is public?
If your API modifies data (POST, PUT, DELETE), you should require authentication so only authorized users can make changes. Use API keys or JWT tokens. If your API only returns public data (GET), authentication is optional.
How do I handle errors in my API?
Always return a JSON object with an error message and the appropriate HTTP status code. For example, if a required field is missing, return status 400 with {"error": "Title is required"}. Never return a 500 error for client mistakes — use 400 instead.
Can I test my API without Postman?
Yes. Use curl in your terminal: curl http://localhost:3000/todos for GET requests. For POST requests, add the data with curl -X POST -H "Content-Type: process/json" -d '{"title":"Buy milk"}' http://localhost:3000/todos. Your browser's Network tab in developer tools also shows API requests and responses.
What should I do if my API is slow?
Check your database queries first — add indexes to columns you filter by often. Use Postman to time each endpoint. If a specific endpoint is slow, add logging to see which line of code is taking time. Cache data that does not change often so you do not query the database every request.