Skip to content

API Routes

Plugins can expose HTTP handlers with @api or the initializer context.

ts
import { BasePlugin, api, definePlugin } from "@ps-generator-bridge/sdk/plugin";

class PaintPlugin extends BasePlugin {
  @api("/status")
  status() {
    return { ok: true };
  }
}

export default definePlugin("paint", (context) => new PaintPlugin(context));

The route is mounted under the plugin id:

text
GET /paint/status

HTTP Method

Use the object form to choose a method:

ts
@api({ method: "POST", url: "/create" })
create(params: unknown) {
  return { ok: true };
}

Plain-object plugins register the same routes during synchronous initialization:

ts
import type { PluginInitContext } from "@ps-generator-bridge/sdk/plugin";

export default function init(context: PluginInitContext) {
  context.api("/status", () => ({ ok: true }));
  context.api({ method: "POST", url: "/create" }, () => ({ ok: true }));
  return {};
}

Route paths must start with /. Supported methods are GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. Duplicate or malformed routes fail plugin activation before the plugin becomes available.

Route Collisions

Plugin ids reserve their first path segment. A module API route cannot use the same first segment as a loaded plugin id.

This keeps plugin HTTP routes under:

text
/{pluginId}/...

and prevents global module routes from stealing plugin namespaces.

Built-In Module Routes

The generator also exposes built-in module HTTP routes under the reserved /action, /document, /layer, /image, and /selection segments. These routes are second entry points for existing Protocol methods and reuse the same result shapes as the corresponding WebSocket request methods.

MethodRouteInput
POST/action/auto-cutoutNo body required
POST/action/remove-backgroundNo body required
GET/document/currentNone
POST/document/exportJSON body with required filePath and optional export fields
POST/document/saveJSON body with optional savePath
GET/layer/infoOptional id, index, getChildren, and getGeneratorSettings query parameters
GET/layer/by-id/:layerIDOptional getChildren query parameter
GET/layer/by-index/:layerIndexOptional getChildren query parameter
GET/layer/current-previewNone
POST/layer/import-imageLayerImportImageParams JSON body; image is required
POST/image/export-layerJSON body with required layerSpec; optional documentId and settings
POST/image/export-layer-with-selected-pathJSON body with required numeric layerSpec; optional documentId and expand
GET/image/preview/:layerSpecOptional documentId query parameter
POST/image/export-documentJSON body with optional documentId and settings
GET/selection/areaNone
GET/selection/pathOptional expand query parameter

POST bodies must be JSON objects. Numeric path and query parameters accept numeric strings; parameters documented as integers reject fractional values. Boolean query parameters accept true, false, 1, or 0. Invalid JSON, missing required fields, and invalid parameter values return 400 with a Protocol error body.

Image export routes return WsImageResult. Its data field is either a data:image/png;base64,... URI or, when COS upload is enabled, an HTTPS URL. The preview route always returns a data URI. The remaining fields contain the image bounds, width, and height.

Error Responses

Module routes serialize errors with the same ProtocolError shape used by WebSocket responses. The HTTP status is selected from the Protocol error code:

HTTP statusProtocol errors
400BadRequest, including malformed JSON and invalid parameters
404PluginNotFound, DocumentNotFound, LayerNotFound
409NoDocument, PhotoshopBusy
503PhotoshopUnavailable
500Other server and JSX failures

Long-lived event capabilities, such as selection:change, stay on WebSocket event subscription instead of HTTP.