An API response standard defines how an API should consistently return successful results, errors, messages, validation errors, and additional information to the client.
An API response standard is a predefined structure used by an API when returning data to a client.
{
"success": true,
"message": "Students retrieved successfully",
"data": []
}
The same basic structure should be followed throughout the application.
Standard responses provide:
{
"success": true,
"message": "Student found",
"data": {
"id": 1,
"name": "Rahul",
"email": "rahul@example.com"
}
}
The success field tells the client whether the operation was successful.
The success field normally contains a Boolean value.
"success": true
For an error:
"success": false
React Native can use this field to determine whether the API operation succeeded.
The message field provides a human-readable description of the result.
{
"success": true,
"message": "Student added successfully"
}
Messages should be short, meaningful, and easy to understand.
The data field contains the actual result returned by the API.
{
"success": true,
"message": "Student details",
"data": {
"id": 10,
"name": "Amit",
"course": "React Native"
}
}
When returning multiple records, the data field can contain an array.
{
"success": true,
"message": "Students retrieved successfully",
"data": [
{
"id": 1,
"name": "Rahul"
},
{
"id": 2,
"name": "Amit"
}
]
}
Errors should also follow a predictable structure.
{
"success": false,
"message": "Student not found",
"data": null
}
This allows the mobile application to handle errors consistently.
JSON response data should be combined with the appropriate HTTP status code.
http_response_code(200);
echo json_encode([
"success" => true,
"message" => "Student found",
"data" => $student
]);
The status code describes the HTTP result while the JSON explains the result.
| Status | Meaning |
|---|---|
| 200 | Successful request |
| 201 | Resource created |
| 204 | Successful request with no response body |
Select the status code according to the operation being performed.
| Status | Use |
|---|---|
| 400 | Bad request |
| 401 | Authentication required or failed |
| 403 | Access forbidden |
| 404 | Resource not found |
| 422 | Validation error |
| 500 | Server error |
Validation errors should provide useful information about invalid fields.
{
"success": false,
"message": "Validation failed",
"errors": {
"name": "Name is required",
"email": "Invalid email address"
}
}
The errors field can contain field-specific validation messages.
{
"success": false,
"message": "Please correct the errors",
"errors": {
"email": "Email is required",
"password": "Password is required"
}
}
This structure is especially useful for React Native forms.
A login API can return:
{
"success": true,
"message": "Login successful",
"data": {
"token": "JWT_TOKEN_HERE",
"user": {
"id": 5,
"name": "Rahul",
"email": "rahul@example.com"
}
}
}
Sensitive information such as passwords should never be returned.
{
"success": false,
"message": "Invalid email or password",
"data": null
}
A 401 Unauthorized status can be used for failed authentication.
If a requested student does not exist:
http_response_code(404);
echo json_encode([
"success" => false,
"message" => "Student not found",
"data" => null
]);
When a new resource is created, return status code 201.
http_response_code(201);
echo json_encode([
"success" => true,
"message" => "Student created successfully",
"data" => [
"id" => $studentId
]
]);
http_response_code(200);
echo json_encode([
"success" => true,
"message" => "Student updated successfully",
"data" => $student
]);
Returning the updated resource can make it easier for the mobile application to update its local state.
A delete endpoint can return a simple success response.
http_response_code(200);
echo json_encode([
"success" => true,
"message" => "Student deleted successfully",
"data" => null
]);
List APIs can return pagination information using a meta object.
{
"success": true,
"message": "Students retrieved successfully",
"data": [
{
"id": 1,
"name": "Rahul"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 50,
"total_pages": 5
}
}
A reusable PHP function can help keep responses consistent.
function sendResponse(
$status,
$success,
$message,
$data = null,
$errors = null
) {
http_response_code($status);
echo json_encode([
"success" => $success,
"message" => $message,
"data" => $data,
"errors" => $errors
]);
exit;
}
Success example:
sendResponse(
200,
true,
"Student found",
$student
);
Error example:
sendResponse(
404,
false,
"Student not found"
);
React Native can read the standard response using Fetch.
const response = await fetch(API_URL);
const result = await response.json();
if (result.success) {
console.log(result.data);
} else {
console.log(result.message);
}
const result = await response.json();
if (!result.success) {
if (result.errors) {
console.log(result.errors);
}
console.log(result.message);
}
The same approach can be reused for registration, login, profile, student management, and other forms.
try {
const response = await axios.get(API_URL);
if (response.data.success) {
console.log(response.data.data);
}
} catch (error) {
console.log("API request failed");
}
A consistent response format makes Axios handling predictable.
Avoid returning completely different structures from different endpoints.
// Bad example
{
"status": "ok",
"student": {}
}
{
"result": true,
"userData": {}
}
Different structures increase the amount of special handling required in the mobile application.
TypeScript can define a reusable response structure.
interface ApiResponse<T> {
success: boolean;
message: string;
data: T | null;
errors?: Record<string, string>;
}
This can be reused for different API response types.
Test every endpoint in Postman and verify both the HTTP status code and JSON response structure.
{
"success": true,
"message": "Request completed successfully",
"data": {},
"errors": null,
"meta": {}
}
Not every field must contain meaningful data for every endpoint. For example, a simple detail response may not require pagination metadata.
A complete list response can combine the standard fields with pagination.
{
"success": true,
"message": "Students retrieved successfully",
"data": [
{
"id": 1,
"name": "Rahul",
"course": "React Native"
},
{
"id": 2,
"name": "Amit",
"course": "JavaScript"
}
],
"errors": null,
"meta": {
"page": 1,
"limit": 10,
"total": 25,
"total_pages": 3
}
}
This type of predictable structure is useful when connecting a PHP/MySQL REST API with a React Native mobile application.
Question: Which field is normally used to contain the actual result returned by an API?