Skip to content
Back to skills

Slides

ASecurity

Public API slide editing (X-API-KEY). Edit slide images with AI, accept/revert edits, object removal, text extraction, save Konva nodes. Types follow PublicApiSlideController (/api/v2/projects/{projectId}/slides).

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 26, 2026
ai-agentstypescriptgobashnodeapi

Works with

  • api

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add compilet-dev/agent-skill-layerproof --skill slides --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Slides?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Slides
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/compilet-dev-slides/badge)](https://www.skillsdirectory.com/skills/compilet-dev-slides)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: slides
description: Public API slide editing (X-API-KEY). Edit slide images with AI, accept/revert edits, object removal, text extraction, save Konva nodes. Types follow PublicApiSlideController (/api/v2/projects/{projectId}/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.

```typescript
// 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;
  /** Optional mask image path for targeted editing */
  mask_image_path?: string;
  /** Optional model preset for image generation */
  model_preset?: string | null;
  /** Optional OpenAI GPT image quality (e.g. "auto", "high", "low") */
  openai_gpt_image_quality?: string | null;
};

// --- 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`.

```bash
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:

```bash
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.

```bash
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.

```bash
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`.

```bash
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:

```bash
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.

```bash
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:

```bash
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).

```bash
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:

```bash
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:
```bash
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_id` and `live_object_id`. Tell the user the workflow was started.
- Suggest polling `GET $LAYERPROOF_BASE_URL/api/v2/jobs/<activity_id>` until `status` is `DONE` or `CANCELED`.
- For image-edit and object-removal: when DONE, tell the user to call **accept-image-edit** with `live_object_id` to 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."

1. Choose `POST /api/v2/projects/{projectId}/slides/{slideId}/image-edit`.
2. Resolve projectId and slideId (from user or ask).
3. Build body: `{"instruction":"Make the background darker","input_image_path":"/path/to/slide/image"}` (user may need to provide image path).
4. Run curl; show JSON. Mention polling jobs with `activity_id` and calling accept-image-edit with `live_object_id` when 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."

1. Resolve projectId; get slide ids from slide-deck GET deck (e.g. `slides[0].id`, `slides[2].id`).
2. For slide 1: POST `.../slides/{slideId1}/image-edit` with `{"instruction":"Make the background darker"}`; capture `activity_id_1` and `live_object_id_1`. For slide 3: POST `.../slides/{slideId3}/object-removal` with region/instruction; capture `activity_id_3` and `live_object_id_3`.
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.
4. POST `.../slides/{slideId1}/accept-image-edit` with `{"live_object_id":"<live_object_id_1>"}`; POST `.../slides/{slideId3}/accept-image-edit` with `{"live_object_id":"<live_object_id_3>"}`. Show updated slide images (GET deck or slide detail).
5. If user says "revert slide 1": GET slide history (if available) for slideId1 to get `history_entry_id`; POST `.../slides/{slideId1}/revert` with `{"history_entry_id":"<id>"}`. Confirm with GET deck.

**Workflow C — User**: "Extract text from slide 2 and replace the old text (OCR + inpainting)."

1. Resolve projectId and slideId for slide 2. POST `.../slides/{slideId}/extract-text` (body per API); capture `activity_id`.
2. Poll `GET /api/v2/jobs/{activity_id}` until DONE. When DONE, `output` may contain extracted text or updated asset reference.
3. 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).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.