slides
Skill: Slide Editing
Description
Modify slides after generation. This skill documents the public API at /api/v2/projects/{projectId}/slides (PublicApiSlideController). All slide endpoints require projectId and slideId in the path. Authenticate with X-API-KEY header.
TypeScript types (request / response)
Mirrors PublicApiSlideController (/api/v2/projects/{projectId}/slides) data classes.
// Shared: cropped region for region-based editing. Must lie fully within image bounds.
// Constraints: x >= 0, y >= 0, width > 0, height > 0; x + width <= image width, y + height <= image height.
type CroppedRegion = {
x: number;
y: number;
width: number;
height: number;
};
// --- Edit Slide Image (POST) — async, poll jobs ---
type SlideImageEditRequest = {
/** AI instruction for the edit (required, non-blank) */
instruction: string;
/** Path to input image in project working dir (required, non-blank) */
input_image_path: string;
/** Optional extra reference image paths */
other_reference_image_paths?: string[];
/** Optional region to edit; only this region is modified */
cropped_region?: CroppedRegion;
};
// --- Accept Image Edit (POST) ---
type AcceptImageEditRequest = {
live_object_id: string; // UUID from image-edit or object-removal response (required)
target_node_id?: string;
override_image_path?: string; // Optional path to use instead of workflow output
};
// --- Revert Slide (POST) ---
type RevertSlideRequest = {
history_entry_id: string; // UUID from slide history (required)
node_id?: string;
};
// --- Object Removal (POST) — async, poll jobs ---
type ObjectRemovalRequest = {
input_image_path: string; // required, non-blank
mask_path?: string;
cropped_region?: CroppedRegion;
};
// --- Extract Text (POST) — async, poll jobs ---
type ExtractTextRequest = {
node_id?: string;
node_image_path?: string;
};
// --- Save Konva Nodes (PUT) ---
type SaveKonvaNodesRequest = {
konva_nodes: Record<string, unknown>; // required
konva_order: string[]; // required
base_snapshot_id?: string; // UUID, optional
};
// --- Responses ---
type TriggerWorkflowResponse = {
activity_id: string; // UUID – poll GET /api/v2/jobs/{activityId}
workflow_type: string;
live_object_id: string; // UUID – pass to accept-image-edit when done
};
type AcceptImageEditResponse = {
id: string; // slide UUID
slide_section_id: string;
image_path: string | null;
status: string;
};
Edit Slide Image (async)
Request body: SlideImageEditRequest. Response: TriggerWorkflowResponse.
Triggers AI-powered slide image editing. Upload input image first, then call with instruction and input_image_path. Poll GET /api/v2/jobs/{activityId} for status; when DONE, call accept-image-edit with live_object_id.
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/image-edit" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"instruction":"Make the background blue","input_image_path":"/slides/slide-1.png"}'
With optional region and reference images:
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/image-edit" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"instruction":"Replace this area","input_image_path":"/slides/slide-1.png","cropped_region":{"x":0,"y":0,"width":200,"height":100},"other_reference_image_paths":["/ref.png"]}'
Accept Image Edit
Request body: AcceptImageEditRequest. Response: AcceptImageEditResponse.
Call after the image-edit or object-removal workflow completes successfully. Use live_object_id from the trigger response.
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/accept-image-edit" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"live_object_id":"<live_object_uuid>"}'
Revert Slide
Request body: RevertSlideRequest. Response: AcceptImageEditResponse.
Reverts the slide to a previous version using history_entry_id from slide history.
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/revert" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"history_entry_id":"<history_entry_uuid>"}'
Remove Objects (async)
Request body: ObjectRemovalRequest. Response: TriggerWorkflowResponse.
Triggers AI-powered object removal. Optional mask_path for mask-based removal. Poll jobs; when DONE, call accept-image-edit with live_object_id.
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/object-removal" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"input_image_path":"/slides/slide-1.png"}'
With mask:
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/object-removal" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"input_image_path":"/slides/slide-1.png","mask_path":"/masks/mask.png"}'
Extract Text (async)
Request body: ExtractTextRequest (optional). Response: TriggerWorkflowResponse.
Performs OCR, removes text from image via inpainting, creates editable Konva text nodes. Poll GET /api/v2/jobs/{activityId} for status.
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/extract-text" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{}'
With optional node:
curl -X POST "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/extract-text" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"node_id":"node-1","node_image_path":"/nodes/node1.png"}'
Save Konva Nodes
Request body: SaveKonvaNodesRequest. Response: 200, no body.
Persists Konva canvas nodes and order (positions, layer order, flattened image path).
curl -X PUT "$LAYERPROOF_BASE_URL/api/v2/projects/<project_id>/slides/<slide_id>/konva-nodes" \
-H "Content-Type: application/json" \
-H "X-API-KEY: $LAYERPROOF_API_KEY" \
-d '{"konva_nodes":{},"konva_order":[]}'
Agent behavior
When the user asks to edit slides (image edit, accept edit, revert, remove objects, extract text, save canvas), do the following.
1. Choose the right endpoint
| User intent | Endpoint | Method |
|---|---|---|
| Edit slide image with AI instruction | /api/v2/projects/{projectId}/slides/{slideId}/image-edit |
POST |
| Accept edited image after workflow completes | /api/v2/projects/{projectId}/slides/{slideId}/accept-image-edit |
POST |
| Revert slide to previous version | /api/v2/projects/{projectId}/slides/{slideId}/revert |
POST |
| Remove objects from slide image (AI) | /api/v2/projects/{projectId}/slides/{slideId}/object-removal |
POST |
| Extract text from slide (OCR + inpainting) | /api/v2/projects/{projectId}/slides/{slideId}/extract-text |
POST |
| Save Konva canvas nodes/order | /api/v2/projects/{projectId}/slides/{slideId}/konva-nodes |
PUT |
All paths require projectId and slideId (replace placeholders with actual UUIDs).
2. Build and run the request
Step 1 — Check environment variables first. Before running any curl command, verify both LAYERPROOF_BASE_URL and LAYERPROOF_API_KEY are set on the user's machine:
if [[ -z "${LAYERPROOF_BASE_URL}" ]]; then
echo "ERROR: LAYERPROOF_BASE_URL is not set."
return 1
fi
if [[ -z "${LAYERPROOF_API_KEY}" ]]; then
echo "ERROR: LAYERPROOF_API_KEY is not set."
return 1
fi
If running from a project directory with a .env.local file, load it first:
if [[ -f .env.local ]]; then
set -a
source .env.local
set +a
fi
Step 2 — Auth: Every request must include X-API-KEY: $LAYERPROOF_API_KEY. Read LAYERPROOF_BASE_URL and LAYERPROOF_API_KEY from the environment; if missing, tell the user to set them.
Step 3 — Path: Resolve project_id and slide_id from context (e.g. from project/slide-deck list or user input). If missing, ask the user.
Step 4 — POST/PUT: Build JSON body from the types above. Use -X POST or -X PUT, -H "Content-Type: application/json", and -d '...'. Run the curl and show the result.
3. After async endpoints (image-edit, object-removal, extract-text)
- Response includes
activity_idandlive_object_id. Tell the user the workflow was started. - Suggest polling
GET $LAYERPROOF_BASE_URL/api/v2/jobs/<activity_id>untilstatusisDONEorCANCELED. - For image-edit and object-removal: when DONE, tell the user to call accept-image-edit with
live_object_idto apply the result.
4. Response handling
- Always show the raw JSON response in a JSON code block; do not convert to a table.
- If the response contains a URL for an image (e.g.
image_path), show the image and the JSON. - On error (4xx/5xx), show the response body and status code; suggest fixing API key, projectId/slideId, or request body.
5. Example workflows
Workflow A — User: "Edit slide image in project X, slide Y: make the background darker."
- Choose
POST /api/v2/projects/{projectId}/slides/{slideId}/image-edit. - Resolve projectId and slideId (from user or ask).
- Build body:
{"instruction":"Make the background darker","input_image_path":"/path/to/slide/image"}(user may need to provide image path). - Run curl; show JSON. Mention polling jobs with
activity_idand calling accept-image-edit withlive_object_idwhen done.
Workflow B — User: "Edit two slides: darker background on slide 1, remove the logo from slide 3; then revert slide 1 if I don’t like it."
- Resolve projectId; get slide ids from slide-deck GET deck (e.g.
slides[0].id,slides[2].id). - For slide 1: POST
.../slides/{slideId1}/image-editwith{"instruction":"Make the background darker"}; captureactivity_id_1andlive_object_id_1. For slide 3: POST.../slides/{slideId3}/object-removalwith region/instruction; captureactivity_id_3andlive_object_id_3. - Poll
GET /api/v2/jobs/{activity_id_1}and.../jobs/{activity_id_3}until both DONE. If either fails, report which slide and reason. - POST
.../slides/{slideId1}/accept-image-editwith{"live_object_id":"<live_object_id_1>"}; POST.../slides/{slideId3}/accept-image-editwith{"live_object_id":"<live_object_id_3>"}. Show updated slide images (GET deck or slide detail). - If user says "revert slide 1": GET slide history (if available) for slideId1 to get
history_entry_id; POST.../slides/{slideId1}/revertwith{"history_entry_id":"<id>"}. Confirm with GET deck.
Workflow C — User: "Extract text from slide 2 and replace the old text (OCR + inpainting)."
- Resolve projectId and slideId for slide 2. POST
.../slides/{slideId}/extract-text(body per API); captureactivity_id. - Poll
GET /api/v2/jobs/{activity_id}until DONE. When DONE,outputmay contain extracted text or updated asset reference. - If a follow-up accept or apply step is required (e.g. accept-image-edit), use the returned
live_object_id; otherwise show the result (e.g. updated slide or transcript) from GET deck.
Response format (required)
- (if response contains url to show image) please show image and show json response instead of table
- Always show the raw JSON response (verbatim) in a JSON code block.
- If the response contains a URL for an image, render/show the image and also show the JSON response (do not convert to a table).
More from compilet-dev/agent-skill-layerproof
jobs
Public API job status polling (X-API-KEY). Poll async operations (outline, slides, exports, etc.) by activityId. Types follow PublicApiJobController (/api/v2/jobs/{activityId}).
27exports
Public API export (X-API-KEY). Export PNG ZIP, PPTX, or video (async), get status, cancel. PublicApiExportController.
27project-files
Public API project file management (X-API-KEY). Prepare upload/update, confirm, AI files, subdirectories, resolve assets/paths, preview URL, get, download, delete. PublicApiProjectFileController.
27themes
Public API theme management (X-API-KEY). List, get, save, update, delete, generate, regenerate, apply, unapply. PublicThemeController (/api/v2/themes).
26workspaces
Public API workspace management (X-API-KEY). Create, list, get, update, delete workspaces. Types follow PublicApiWorkspaceController (/api/v2/workspaces).
26public-files
Public API reference files (X-API-KEY). Prepare upload, confirm, delete, get download URL. Use s3_key from prepare in outline generation. Types follow PublicApiFileController (/api/v2/files).
26