All API endpoints in Published CMS must return a **consistent JSON structure** compatible with both human and automated clients (e.g. PHP SDKs, GPT connectors).
---
## π General Format
Every response (success or error) returns JSON like:
```json
{
"success": true,
"message": "Optional human-readable message",
"data": {},
"meta": {}
}
```
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | `bool` | β | Indicates success or failure. |
| `message` | `string` | β | Optional message describing the result. |
| `data` | `array` or `object` | β | The payload β model data, arrays, or paginated items. |
| `meta` | `object` | β | Metadata container (pagination and other info). |
---
## π’ Success Responses
```php
return ApiResponse::success($data, $message = null, $code = 200);
```
**Example:**
```json
{
"success": true,
"message": "Category created successfully.",
"data": {
"id": 12,
"title": "Events",
"slug": "events",
"restricted": 0
}
}
```
---
## π΅ Paginated Responses
Paginated endpoints use:
```php
return ApiResponse::paginated($paginator, $message = null);
```
**Actual JSON output:**
```json
{
"success": true,
"data": [
{ "id": 1, "name": "Alice", "role": "mod" },
{ "id": 2, "name": "Bob", "role": "user" }
],
"meta": {
"pagination": {
"current_page": 1,
"last_page": 3,
"per_page": 15,
"total": 45
}
}
}
```
> β This format aligns with the [JSON:API](https://jsonapi.org/) convention of nesting pagination and metadata inside `meta`.
---
## π‘ Message-Only Responses
For endpoints that only confirm an action:
```php
return ApiResponse::message('Category deleted successfully.');
```
**Example:**
```json
{
"success": true,
"message": "Category deleted successfully."
}
```
---
## π΄ Error Responses
Errors use:
```php
return ApiResponse::error($message, $code = 400, $details = []);
```
**Example:**
```json
{
"success": false,
"message": "Validation failed.",
"data": {
"title": ["The title field is required."]
}
}
```
Laravelβs built-in exception handler automatically wraps validation and auth errors in this structure when exceptions are thrown.
---
## π§© Response Type Reference
| Type | Typical Use | Example Method |
| --- | --- | --- |
| **Success (200)** | Data retrieval | `CategoryController@index` |
| **Created (201)** | New resource | `CategoryController@store` |
| **Updated (200)** | Update actions | `CategoryController@update` |
| **Deleted (200)** | Soft delete | `CategoryController@destroy` |
| **Paginated (200)** | List endpoints | `CategoryController@listUsers` |
| **Message (200)** | Simple confirmation | `CategoryController@suspend` |
| **Error (4xx)** | Validation/conflict | `CategoryService@requestAccess` |
---
## βοΈ Developer Notes
- `ApiResponse` is defined in `App\Support\ApiResponse`.
- Pagination metadata **must** live under `meta.pagination` (not top-level).
- Non-paginated metadata (e.g. counts, filters) can be added to `meta` later.
- Always prefer returning full Eloquent models or collections β `ApiResponse` handles serialization.
- Clients (like the PHP `PublishedClient`) can safely assume:
- `data` contains all useful output,
- `meta.pagination` exists for paginated endpoints,
- and `message` is always a simple string.
---
## π General Format
Every response (success or error) returns JSON like:
```json
{
"success": true,
"message": "Optional human-readable message",
"data": {},
"meta": {}
}
```
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | `bool` | β | Indicates success or failure. |
| `message` | `string` | β | Optional message describing the result. |
| `data` | `array` or `object` | β | The payload β model data, arrays, or paginated items. |
| `meta` | `object` | β | Metadata container (pagination and other info). |
---
## π’ Success Responses
```php
return ApiResponse::success($data, $message = null, $code = 200);
```
**Example:**
```json
{
"success": true,
"message": "Category created successfully.",
"data": {
"id": 12,
"title": "Events",
"slug": "events",
"restricted": 0
}
}
```
---
## π΅ Paginated Responses
Paginated endpoints use:
```php
return ApiResponse::paginated($paginator, $message = null);
```
**Actual JSON output:**
```json
{
"success": true,
"data": [
{ "id": 1, "name": "Alice", "role": "mod" },
{ "id": 2, "name": "Bob", "role": "user" }
],
"meta": {
"pagination": {
"current_page": 1,
"last_page": 3,
"per_page": 15,
"total": 45
}
}
}
```
> β This format aligns with the [JSON:API](https://jsonapi.org/) convention of nesting pagination and metadata inside `meta`.
---
## π‘ Message-Only Responses
For endpoints that only confirm an action:
```php
return ApiResponse::message('Category deleted successfully.');
```
**Example:**
```json
{
"success": true,
"message": "Category deleted successfully."
}
```
---
## π΄ Error Responses
Errors use:
```php
return ApiResponse::error($message, $code = 400, $details = []);
```
**Example:**
```json
{
"success": false,
"message": "Validation failed.",
"data": {
"title": ["The title field is required."]
}
}
```
Laravelβs built-in exception handler automatically wraps validation and auth errors in this structure when exceptions are thrown.
---
## π§© Response Type Reference
| Type | Typical Use | Example Method |
| --- | --- | --- |
| **Success (200)** | Data retrieval | `CategoryController@index` |
| **Created (201)** | New resource | `CategoryController@store` |
| **Updated (200)** | Update actions | `CategoryController@update` |
| **Deleted (200)** | Soft delete | `CategoryController@destroy` |
| **Paginated (200)** | List endpoints | `CategoryController@listUsers` |
| **Message (200)** | Simple confirmation | `CategoryController@suspend` |
| **Error (4xx)** | Validation/conflict | `CategoryService@requestAccess` |
---
## βοΈ Developer Notes
- `ApiResponse` is defined in `App\Support\ApiResponse`.
- Pagination metadata **must** live under `meta.pagination` (not top-level).
- Non-paginated metadata (e.g. counts, filters) can be added to `meta` later.
- Always prefer returning full Eloquent models or collections β `ApiResponse` handles serialization.
- Clients (like the PHP `PublishedClient`) can safely assume:
- `data` contains all useful output,
- `meta.pagination` exists for paginated endpoints,
- and `message` is always a simple string.