actuel-inactuel/site/plugins/loop/docs/05-api.md
isUnknown ab7fd8b2ea
All checks were successful
Deploy / Deploy to Production (push) Successful in 6s
add kirby-loop plugin with French translations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 21:41:50 +01:00

7.1 KiB

title
API Reference

Kirby Loop provides a RESTful API for managing comments and feedback. All endpoints include CSRF protection.

Authentication

All API endpoints require authentication, controlled by the moinframe.loop.public configuration option:

  • Default (private): Only authenticated Kirby users can access the API
  • Public mode: Anyone can access the API

CSRF Protection

All API requests must include a valid CSRF token in the request header:

fetch('/loop/comments/page-id', {
    headers: {
        'X-CSRF-Token': '<csrf-token>'
    }
});

Base URL Structure

Single Language Sites

/loop/comments/{pageId}
/loop/comment/new
/loop/comment/reply
/loop/comment/resolve
/loop/comment/unresolve
/loop/guest/name

Multi-Language Sites

/{language}/loop/comments/{pageId}
/{language}/loop/comment/new
/{language}/loop/comment/reply
/{language}/loop/comment/resolve
/{language}/loop/comment/unresolve
/{language}/loop/guest/name

Where {language} is the language code (e.g., en, de).

Endpoints

GET /loop/comments/{pageId}

Retrieve all comments for a specific page.

Parameters:

  • pageId (string): The page ID or 'home' for the homepage

Response:

{
    "status": "ok",
    "comments": [
        {
            "id": 1,
            "author": "John Doe",
            "url": "https://example.com/page",
            "page": "page-uuid",
            "comment": "This needs to be updated",
            "selector": ".header h1",
            "selectorOffsetX": 10,
            "selectorOffsetY": 20,
            "pagePositionX": 150,
            "pagePositionY": 300,
            "timestamp": 1640995200,
            "lang": "en",
            "status": "OPEN",
            "replies": [
                {
                    "id": 1,
                    "author": "jane.smith",
                    "comment": "I'll fix this",
                    "parentId": 1,
                    "timestamp": 1640995800
                }
            ]
        }
    ]
}

Error Responses:

  • 400: Page not found
  • 401: Unauthorized (if authentication required)
  • 403: CSRF token invalid

POST /loop/comment/new

Create a new comment on a page.

Request Body:

{
    "comment": "This section needs clarification",
    "url": "https://example.com/page",
    "selector": ".content p:nth-child(3)",
    "selectorOffsetX": 15,
    "selectorOffsetY": 25,
    "pagePositionX": 200,
    "pagePositionY": 450,
    "pageId": "projects/project-alpha"
}

Required Fields:

  • comment (string): The comment text (HTML stripped and sanitized)
  • url (string): The full URL where the comment was made
  • selector (string): CSS selector for the commented element
  • selectorOffsetX (number): X offset within the selected element
  • selectorOffsetY (number): Y offset within the selected element
  • pagePositionX (number): X position on the page
  • pagePositionY (number): Y position on the page
  • pageId (string): Kirby page ID or 'home'

Response:

{
    "status": "ok",
    "comment": {
        "id": 15,
        "author": "John Doe",
        "url": "https://example.com/page",
        "page": "page-uuid",
        "comment": "This section needs clarification",
        "selector": ".content p:nth-child(3)",
        "selectorOffsetX": 15,
        "selectorOffsetY": 25,
        "pagePositionX": 200,
        "pagePositionY": 450,
        "timestamp": 1640995200,
        "lang": "en",
        "status": "OPEN",
        "replies": []
    }
}

Error Responses:

  • 400: Missing required fields, invalid selector format, or invalid data
  • 401: Unauthorized
  • 403: CSRF token invalid or disabled
  • 404: Page not found

POST /loop/comment/reply

Add a reply to an existing comment.

Request Body:

{
    "comment": "I'll handle this update",
    "parentId": 15
}

Required Fields:

  • comment (string): The reply text (HTML stripped and sanitized)
  • parentId (number): ID of the parent comment

Response:

{
    "status": "ok",
    "reply": {
        "id": 3,
        "author": "John Doe",
        "comment": "I'll handle this update",
        "parentId": 15,
        "timestamp": 1640995800
    }
}

Error Responses:

  • 400: Missing required fields
  • 401: Unauthorized
  • 403: CSRF token invalid or disabled

POST /loop/comment/resolve

Mark a comment as resolved.

Request Body:

{
    "id": 15
}

Required Fields:

  • id (number): The comment ID to resolve

Response:

{
    "status": "ok",
    "success": true
}

Error Responses:

  • 400: Missing comment ID
  • 401: Unauthorized
  • 403: CSRF token invalid or disabled

POST /loop/comment/unresolve

Mark a resolved comment as unresolved.

Request Body:

{
    "id": 15
}

Required Fields:

  • id (number): The comment ID to unresolve

Response:

{
    "status": "ok",
    "success": true
}

Error Responses:

  • 400: Missing comment ID
  • 401: Unauthorized
  • 403: CSRF token invalid or disabled

POST /loop/guest/name

Set a guest name for non-authenticated users (when public mode is enabled).

Request Body:

{
    "name": "John Doe"
}

Required Fields:

  • name (string): The guest user's name

Response:

{
    "status": "ok",
    "name": "John Doe"
}

Error Responses:

  • 400: Missing or empty name
  • 401: Unauthorized
  • 403: CSRF token invalid or disabled

Data Models

Comment Object

interface Comment {
    id: number;
    author: string;           // Resolved display name (user name, email prefix, or guest name)
    url: string;             // Full URL where comment was made
    page: string;            // Page UUID
    comment: string;         // Sanitized comment text
    selector: string;        // CSS selector for target element
    selectorOffsetX: number; // X offset within element (float)
    selectorOffsetY: number; // Y offset within element (float)
    pagePositionX: number;   // X position on page (float)
    pagePositionY: number;   // Y position on page (float)
    timestamp: number;       // Unix timestamp
    lang: string;           // Language code
    status: string;          // Status: OPEN, RESOLVED
    replies: Reply[];        // Array of replies
}

Reply Object

interface Reply {
    id: number;
    author: string;     // Resolved display name (user name, email prefix, or guest name)
    comment: string;    // Sanitized reply text
    parentId: number;   // Parent comment ID
    timestamp: number;  // Unix timestamp
}

Error Handling

The api endpoints return consistent error responses. For more details, switch on the debug mode in your Kirby Installation.

{
    "status": "error",
    "message": "Human-readable error message",
    "code": "ERROR_CODE"  // Optional error code
}

Common Error Codes

  • CSRF_INVALID: CSRF token is missing or invalid
  • PAGE_NOT_FOUND: Specified page doesn't exist
  • FIELD_REQUIRED: Required field is missing
  • UNAUTHORIZED: Authentication required but not provided
  • INVALID_SELECTOR: Invalid selector format
  • INVALID_NAME: Invalid guest name
  • DISABLED: Tool is disabled