REST APIs communicate almost exclusively in JSON. Understanding the patterns, conventions, and common structures makes building and consuming APIs significantly faster.
Anatomy of a JSON API request
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
Accept: application/json
{
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "user"
}
Standard response structure
// Success response (201 Created)
{
"data": {
"id": "usr_abc123",
"name": "Alice Johnson",
"email": "alice@example.com",
"createdAt": "2023-11-14T22:13:20Z"
},
"meta": {
"requestId": "req_xyz789"
}
}
// Error response (422 Unprocessable Entity)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
}
HTTP methods and their JSON patterns
// GET — retrieve data (no body)
GET /api/v1/users/123
Response: { "data": { "id": "123", "name": "Alice" } }
// POST — create resource
POST /api/v1/users
Body: { "name": "Alice", "email": "alice@example.com" }
Response (201): { "data": { "id": "usr_new", ...created fields } }
// PUT — replace entire resource
PUT /api/v1/users/123
Body: { "name": "Alice Updated", "email": "alice@example.com" }
// PATCH — partial update
PATCH /api/v1/users/123
Body: { "name": "Alice Updated" } // only changed fields
// DELETE — remove resource (usually no body)
DELETE /api/v1/users/123
Response (204): no body
Pagination JSON pattern
GET /api/v1/users?page=2&per_page=20
{
"data": [...20 users...],
"pagination": {
"page": 2,
"per_page": 20,
"total": 150,
"total_pages": 8,
"has_next": true,
"has_prev": true,
"next_url": "/api/v1/users?page=3&per_page=20"
}
}
Consuming a REST API in JavaScript
class APIClient {
constructor(baseURL, token) {
this.baseURL = baseURL;
this.headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
};
}
async get(path) {
const res = await fetch(this.baseURL + path, { headers: this.headers });
if (!res.ok) throw await this.parseError(res);
return res.json();
}
async post(path, body) {
const res = await fetch(this.baseURL + path, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(body)
});
if (!res.ok) throw await this.parseError(res);
return res.json();
}
async parseError(res) {
const json = await res.json().catch(() => ({}));
return new Error(json.error?.message || `HTTP ${res.status}`);
}
}
const client = new APIClient('https://api.example.com', token);
const { data: user } = await client.get('/v1/users/123');
const { data: newUser } = await client.post('/v1/users', { name: 'Alice' });Try it free — JSON Formatter
Inspect and format your API responses instantly.