# CMS Pages API Documentation

## Overview
The Pages API provides access to CMS page content including page metadata, HTML/block content, and hierarchical page structures. All endpoints require company authentication and return fresh data without caching.

## Authentication
All requests require the following headers:

| Header | Required | Description |
|--------|----------|-------------|
| `X-Company-Hash` | Yes | Unique company identifier |
| `Accept` | Yes | `application/json` |

**Missing or invalid company hash returns `422 Unprocessable Entity`**

---

## Endpoints

### 1. List All Pages (Paginated)
```
GET /api/cms/pages
```

Returns a paginated list of all pages for the authenticated company.

**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | integer | 1 | Page number for pagination |
| `per_page` | integer | 15 | Items per page (max 100) |
| `status` | string | `published` | Filter by status (`published`, `draft`, `all`) |

**Response:**
```json
{
  "success": true,
  "message": "Pages fetched successfully",
  "data": {
    "pages": [
      {
        "id": 1,
        "title": "Home",
        "slug": "home",
        "parent_id": null,
        "status": "published",
        "created_at": "2025-01-10T14:30:00Z",
        "updated_at": "2026-01-15T09:20:00Z"
      },
      {
        "id": 2,
        "title": "About Us",
        "slug": "about-us",
        "parent_id": null,
        "status": "published",
        "created_at": "2025-01-12T10:15:00Z",
        "updated_at": "2026-01-14T16:45:00Z"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 15,
      "total": 24,
      "total_pages": 2,
      "has_more": true
    }
  }
}
```

---

### 2. Get Page by ID
```
GET /api/cms/pages/{id}
```

Retrieves a single page with full content by its ID.

**Path Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | Page ID |

**Response:**
```json
{
  "success": true,
  "message": "Page fetched successfully",
  "data": {
    "page": {
      "id": 1,
      "title": "Home",
      "slug": "home",
      "content": [
        {
          "type": "heading",
          "level": 1,
          "text": "Welcome to Our Site"
        },
        {
          "type": "paragraph",
          "text": "This is the homepage content..."
        },
        {
          "type": "image",
          "src": "https://cdn.example.com/hero.jpg",
          "alt": "Hero banner"
        }
      ],
      "meta": {
        "title": "Home | Company Name",
        "description": "Welcome to our website",
        "keywords": ["home", "welcome"],
        "og_image": "https://cdn.example.com/og-home.jpg"
      },
      "parent_id": null,
      "status": "published",
      "author_id": 5,
      "created_at": "2025-01-10T14:30:00Z",
      "updated_at": "2026-01-15T09:20:00Z"
    }
  }
}
```

---

### 3. Get Page by Slug
```
GET /api/cms/pages/slug/{slug}
```

Retrieves a single page with full content by its URL slug.

**Path Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `slug` | string | Yes | Page URL slug (e.g., `about-us`) |

**Response:**
```json
{
  "success": true,
  "message": "Page fetched successfully",
  "data": {
    "page": {
      "id": 2,
      "title": "About Us",
      "slug": "about-us",
      "content": [
        {
          "type": "heading",
          "level": 1,
          "text": "About Our Company"
        },
        {
          "type": "paragraph",
          "text": "We are a leading provider..."
        }
      ],
      "meta": {
        "title": "About Us | Company Name",
        "description": "Learn about our company"
      },
      "parent_id": null,
      "status": "published",
      "author_id": 3,
      "created_at": "2025-01-12T10:15:00Z",
      "updated_at": "2026-01-14T16:45:00Z"
    }
  }
}
```

**Error Response (Page Not Found):**
```json
{
  "success": false,
  "message": "Page not found"
}
```

---

### 4. Get Pages for Menu
```
GET /api/cms/pages/menu
```

Returns a flat list of pages suitable for building navigation menus. Only includes published pages with basic information.

**Response:**
```json
{
  "success": true,
  "message": "Menu pages fetched successfully",
  "data": {
    "pages": [
      {
        "id": 1,
        "title": "Home",
        "slug": "home",
        "parent_id": null,
        "order": 1
      },
      {
        "id": 2,
        "title": "About Us",
        "slug": "about-us",
        "parent_id": null,
        "order": 2
      },
      {
        "id": 3,
        "title": "Our Team",
        "slug": "team",
        "parent_id": 2,
        "order": 1
      },
      {
        "id": 4,
        "title": "Contact",
        "slug": "contact",
        "parent_id": null,
        "order": 3
      }
    ]
  }
}
```

---

### 5. Get Page Tree (Hierarchical)
```
GET /api/cms/pages/tree
```

Returns pages organized in a hierarchical tree structure with parent-child relationships.

**Response:**
```json
{
  "success": true,
  "message": "Page tree fetched successfully",
  "data": {
    "tree": [
      {
        "id": 1,
        "title": "Home",
        "slug": "home",
        "parent_id": null,
        "children": []
      },
      {
        "id": 2,
        "title": "About Us",
        "slug": "about-us",
        "parent_id": null,
        "children": [
          {
            "id": 3,
            "title": "Our Team",
            "slug": "team",
            "parent_id": 2,
            "children": []
          },
          {
            "id": 5,
            "title": "Our History",
            "slug": "history",
            "parent_id": 2,
            "children": []
          }
        ]
      },
      {
        "id": 4,
        "title": "Contact",
        "slug": "contact",
        "parent_id": null,
        "children": []
      }
    ]
  }
}
```

---

## Response Fields

### Page Object Fields

| Field | Type | Description |
|-------|------|-------------|
| `id` | integer | Unique page identifier |
| `title` | string | Page title |
| `slug` | string | URL-friendly identifier (e.g., `about-us`) |
| `content` | array | Array of content blocks (see Content Structure) |
| `meta` | object | SEO and metadata information |
| `parent_id` | integer\|null | Parent page ID (null for top-level pages) |
| `status` | string | Publication status (`published`, `draft`) |
| `author_id` | integer | User ID of the page author |
| `order` | integer | Sort order (menu endpoint only) |
| `created_at` | string | ISO 8601 timestamp |
| `updated_at` | string | ISO 8601 timestamp |
| `children` | array | Child pages (tree endpoint only) |

### Content Structure

The `content` field is an array of block objects. Each block has a `type` field and type-specific properties:

**Heading Block:**
```json
{
  "type": "heading",
  "level": 1,
  "text": "Section Title"
}
```

**Paragraph Block:**
```json
{
  "type": "paragraph",
  "text": "Lorem ipsum dolor sit amet..."
}
```

**Image Block:**
```json
{
  "type": "image",
  "src": "https://cdn.example.com/image.jpg",
  "alt": "Description",
  "width": 1200,
  "height": 800
}
```

**HTML Block:**
```json
{
  "type": "html",
  "html": "<div class='custom'>...</div>"
}
```

### Meta Object

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | SEO page title (used in `<title>` tag) |
| `description` | string | Meta description for search engines |
| `keywords` | array | SEO keywords |
| `og_image` | string | Open Graph image URL for social sharing |
| `canonical_url` | string | Canonical URL (if different from default) |

---

## Error Responses

### 404 Not Found
```json
{
  "success": false,
  "message": "Page not found"
}
```

### 422 Unprocessable Entity (Invalid Company Hash)
```json
{
  "success": false,
  "message": "Missing or invalid X-Company-Hash header."
}
```

### 400 Bad Request
```json
{
  "success": false,
  "message": "Invalid parameter: per_page must be between 1 and 100"
}
```

---

## Behavior Notes

- **No Caching**: All endpoints return fresh data directly from the database
- **Company Scoping**: All pages are filtered by the authenticated company
- **Slug Format**: Slugs are lowercase, hyphenated URLs (e.g., `about-our-team`)
- **Parent-Child**: Pages can be nested up to 3 levels deep
- **Published Only**: Most endpoints return only `published` pages unless filtered
- **Timestamps**: All timestamps are in UTC (ISO 8601 format)

---

## Example Usage

### JavaScript (Fetch API)
```javascript
const companyHash = 'abc123def456';

// Get page by slug
const response = await fetch('https://api.example.com/api/cms/pages/slug/about-us', {
  headers: {
    'X-Company-Hash': companyHash,
    'Accept': 'application/json'
  }
});

const data = await response.json();
console.log(data.data.page.title); // "About Us"
```

### cURL
```bash
curl -X GET "https://api.example.com/api/cms/pages/slug/about-us" \
  -H "X-Company-Hash: abc123def456" \
  -H "Accept: application/json"
```

### PHP
```php
$companyHash = 'abc123def456';

$response = Http::withHeaders([
    'X-Company-Hash' => $companyHash,
    'Accept' => 'application/json',
])->get('https://api.example.com/api/cms/pages/slug/about-us');

$page = $response->json()['data']['page'];
echo $page['title']; // "About Us"
```
