Public API

Base URL: /api/v1. JSON responses, no auth required for browsing.

GET /api/v1/plugins

List approved plugins. Query params: q, category, tag, sort (popular | recent | rating | name), page, per_page.

GET /api/v1/plugins/{id}

Plugin detail with version history and latest version manifest.

GET /api/v1/plugins/{id}/versions/{version}/download

302 redirect to a signed package URL. Headers: X-Package-Sha256, X-Package-Size. You must verify sha256 before extracting.

POST /api/v1/plugins/{id}/install-ping

Anonymous telemetry. Body: {event, version, site_hash, pressline_ver, php_ver}. Returns 204.

POST /api/v1/plugins/{id}/reviews

Submit a rating. Header X-Site-Token required. Body: {rating: 1-5, comment, version}.

GET /api/v1/categories

Static list of categories.

Author API

Auth: Authorization: Bearer <api_token>. Get a token from your account.

POST /api/v1/authors/register

{"email": "...", "password": "...", "display_name": "..."}

POST /api/v1/authors/me/plugins

{"id": "my-plugin", "name": "My Plugin", "description": "...", "category": "editor"}

POST /api/v1/authors/me/plugins/{id}/versions

Multipart upload of the plugin .zip in field package. Static checks run server-side; rejected zips return 400.

Plugin manifest

{
  "id": "my-plugin",
  "name": "My Plugin",
  "version": "1.0.0",
  "author": "You",
  "description": "...",
  "min_pressline": "1.5",
  "permissions": ["articles.read", "articles.write"],
  "category": "editor",
  "tags": ["editor", "writing"],
  "entry": "plugin.php"
}