How to create products users love: applying Emotional Design and UX heuristics in real projects
Jonathan Felipe de Oliveira | Mar 27, 2026
As a software developer, I know how hard it is to contain the urge to start coding as soon as we can. After the first sprint planning, our fingers – uncontrolled, hungry creatures – want to start smashing the keyboard, translating our ideas into code fastly and furiously.
Despite how great we feel while developing, it’s always a good idea to take a step back, especially when building something that could be used by many different users – like an API is. A. In this post, I’ll show you why and how to design a properly-thought API.
API is a generic term to define an Application Program Interface, in other words, how a user (human or machine) interacts with a program. In the web development world, an API is generally a website with a collection of endpoints that respond to client requests with structured text data.
Another concept that’s widely used and discussed by web developers is the one of a RESTFul Web API. It was defined by Roy Fielding as an architecture style that provides a well-established communication protocol between client and server. It outlines some constraints: stateless communication, respect of the underlying technology (generally HTTP) and the use of hypermedia as the engine of application state. In other words, it proposes some patterns for building a web API. For simplicity’s sake, I’ll be referring to Web APIs simply as APIs throughout this post.
Let’s see an example of an API response:
{
"data": [
{
"story": "Jonatas Baldin was writing a blog post.",
"created_time": "2017-15-01T00:02:57+0000",
"id": "624510964324764_1046909755418214"
},
]
}
This snippet of data, called JSON, is an example of how a smartphone sees a Facebook status message, gathered from the Facebook API. Pretty neat, right?
Now imagine that you are an engineer at Facebook, responsible for this API. You wake up one day and decide to change the id field name to message_id. Well, this small change could break Facebook. For real. All devices that depend on the previously-defined structure would now stop being able to collect and display the content to the user. Definitely not a great day at work.
A bad API design – or the lack of it – will, sooner or later, cause all kinds of trouble:

An API is a contract between your application and its users. It can’t be changed abruptly without causing chaos for those who already signed it and it shouldn’t be built without forethought. This is where design enters: the creation of a plan or convention for the construction of an object, system or measurable human interaction.
Before diving into API code, let’s get a glimpse of the Hypertext Transfer Protocol. HTTP, as the name suggests, is used to transfer data on the web. It has a set of rules on how clients and servers should exchange information. Its main components are:
2xx statuses means success, 4xx means client errors and 5xx means service errors. You can get a full list here or here.Let’s see an HTTP request/response example:
Client request:
GET /users/1 HTTP/1.1
Host: www.example.org/users
Server response:
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sun, 19 Feb 2017 00:43:51 GMT
{
"id": 1,
"first_name": "Jonatas",
"fast_name": "Baldin",
"role": "Caker"
}
There are some specifications to help you out when designing your API. The most used ones are Swagger with pure JSON, RAML with YAML notation and API Blueprint backed by the markdown syntax. I felt in love with the latter: even though it is the new cool kid in the neighborhood, it’s already mature enough and delightful to work with. That’s the one I’ll be covering here.
From the official website:
API Blueprint is simple and accessible to everybody involved in the API lifecycle. Its syntax is concise yet expressive. With API Blueprint you can quickly design and prototype APIs to be created or document and test already deployed mission-critical APIs.
It’s an open source, focused on collaboration, easy to learn and well-documented specification created by Apiary with design-first in its core, surrounded by awesome tools: from mock server generators to full-feature life-cycle solutions.
In addition to Blueprint, there’s MSON (Markdown Syntax Object Notation), which defines data structures in a human-readable way. Instead of writing manually the endpoints body data, you represent them in reusable objects. Pretty nifty, huh?
Here’s what you need to know to get started:
Besides that, there’s Apiary. It’s a collaborative platform to create, render, test and serve your API. They have a free plan for public projects and you can sign up directly from your GitHub account to create your own designs.
Here’s a Blueprint code sample:
FORMAT: 1A
HOST: http://cakes.ckl.io/
# Cakes API
Cakes is an API used to store and consume information about the most loved Cakes here at Cheesecake Labs.
# Group Cakes
## Cakes [/cakes/]
### List all Cakes [GET]
+ Response 200 (application/json)
+ Attributes (array[Cake])
# Data Structures
## Cake (object)
+ id: `1` (string, required) - The unique ID of a Cake.
+ name: `Cheesecake` (string, required) - The name of a Cake.
+ rating: `5/5` (string, optional) - The rating of a Cake.
If you access the project above, you’ll see a prettily-rendered page. Now the awesome part: a mock server is automatically created for every project – look at this! See the magic? No code was needed to make it work. Anyone with basic knowledge of HTTP and Blueprint can create a mock API and get feedback from customers.
The example above is as simple as it can get. You can check the Blueprint tutorials and documentation to go deeper into its syntax and read the specs here. Also, this is an open-source project – any contribution from the community is welcomed.
Congratulations! Now you are armed with the knowledge necessary to design your APIs. But before you start rocking your systems, here are some little tips to keep on your toolbelt:
We have walked a long path together, from understanding what is an API and why its design matters, passing by the HTTP protocol and landing on Blueprint API, giving you the foundation to start creating your own designs. I’ll list some amazing dos and don’ts. Note that these aren’t rules, just best practices you generally find on the web.
Treat endpoint actions as CRUD(L) operations
Our /cakes/ endpoint may have Create, Read, Update, Delete and List operations. You can construct these actions with HTTP verbs and the URL, like:
GET /cakes/POST /cakes/GET /cakes/1/PATCH /cakes/1/DELETE /cakes/1/
Correctly use the HTTP methods
GET is for getting, POST if for posting. Don’t use POST if you just want a list of Cakes.
HTTP has methods, use them!
POST /cakes/createCake
You don’t need to specify the action in the URL, we already know that POST creates something.
POST /cakes/
Cleaner URL, also telling us that probably the other methods will work as expected, like GET /cakes.
Singular or Plural? Plural!
GET /cakes should return a list of Cakes, so GET /cake/1 should return the first Cake, right? Unfortunately, no. Even though it makes sense in our language, it will just confuse clients and developers with one more endpoint.
Searching, ordering, limiting? Use query parameters!
This feature allows you to specify some filtering on List endpoints, here’s an example:
GET /cakes/?name=apple
If implemented, should list all the Cakes with apple in the name.
GET /cakes/?name=apple&rating=4
You can also concatenate parameters with &, search for apple and a 4 rating.
Return. Errors. With. 4xx.
If you want to take just one thing from this article, make sure it’s this one: everybody freaking hates a response with HTTP 2xx and a message of error! Use the correct codes:
401: Unauthorized access, where the authorization process wasn’t done correctly.
403: Forbidden access, the client is authorized, but has no access to the resource.
404: The famous not found, indicating the resource is not available.
Describe your errors with clarity
When something fails, inform the client about what happened and how it can recover. Here’s a nice way to do it:
{
"error": {
"type": "Authentication Error",
"details": "Authentication could not be established with the given username and password",
}
}
Everyone understands that.
I’m a teapot
Implement the status 418 in a HTTP response. You know, just for fun!
Resources are like object classes
The API endpoints will respond with a resource representation. Think about these resources as object classes, they then to represent things in the real world.
I could write a lot of tips here, but this post would become a book. And there’s already a good one, Build APIs You Won’t Hate by Phil Sturgeon.
Trust me on this, using a Design-first philosophy will give you better nights of sleep. Here are some advantages and characteristics of a good API:
At the end of the day, your API is a new little language you’ll have to teach to other people.

If more tips could fit a book, talking about all aspects of API Design would fit a library. I’ll leave you, my patient reader, with some amazing references on further topics:
API Design matters. It tends to stop people from just hacking things together to take a step back and see the bigger picture. Here at Cheesecake Labs we do our best to develop APIs following the best practices. We know that it seems time-consuming, but in the long run it pays off!
API is a generic term for Application Program Interface, defining how a user (human or machine) interacts with a program. In web development, an API is generally a website with a collection of endpoints that respond to client requests with structured text data. A RESTful Web API, defined by Roy Fielding, is an architecture style that provides a well-established communication protocol between client and server, with constraints such as stateless communication, respect of the underlying technology (generally HTTP), and the use of hypermedia as the engine of application state.
A bad API design, or the lack of it, can cause absence of consistency, difficulty to scale, a steep learning curve, and performance issues. APIs tend to be forever, and an API is a contract between your application and its users that can't be changed abruptly without causing chaos for those who already signed it.
The main components are: URL (the address of your endpoint), Request methods (GET to retrieve, POST to create, PUT and PATCH to update, DELETE to remove), Headers (information about the client or server, like content type and authentication token), Body (the data exchanged, typically JSON), and Status code (a three-digit number indicating request status, where 2xx means success, 4xx means client errors, and 5xx means service errors).
The most used specifications are Swagger with pure JSON, RAML with YAML notation, and API Blueprint backed by markdown syntax. API Blueprint is an open source specification created by Apiary, focused on collaboration, with design-first at its core. It also includes MSON (Markdown Syntax Object Notation) for defining data structures in a human-readable way. Apiary is a collaborative platform to create, render, test, and serve your API, with a free plan for public projects.
Treat endpoint actions as CRUD(L) operations using HTTP verbs with the URL; correctly use HTTP methods (don't use POST to get a list); don't specify the action in the URL since HTTP methods already indicate it; use plural resource names (e.g., /cakes); use query parameters for searching, ordering, and limiting; return errors with 4xx status codes (401 for unauthorized, 403 for forbidden, 404 for not found); describe errors clearly so clients know what happened and how to recover; and think of resources as object classes representing things in the real world.
Believes in love-driven development. Linux guy and Python addicted. Enthusiast in DevOps culture and open-source projects.