News icon

Kimi K3 is now available on Runpod

Getting started with Pruna P-Video-Edit using a Public Endpoint

Learn how to edit videos with Pruna P-Video-Edit using Runpod’s public endpoint, Playground, curl, and Python.

Getting started with Pruna P-Video-Edit using a Public Endpoint

P-Video-Edit is Pruna AI’s instruction-driven video editing model. Upload a source video up to 15 seconds long and give one text instruction; the model then produces an edited video. You can also optionally include up to four reference images to support reference-based edits.

Runpod has a public endpoint available for this model. This gives you instant API access to a pre-deployed API for calling this endpoint. You don’t need deployment or infrastructure; all you need is to create an API key and make a request.

How to get started with P-Video-Edit

Before integrating P-Video-Edit into your application, it’s helpful to experiment with the model and explore its capabilities. This blog post walks you through how to do so.

On Runpod’s Playground

To get started, you can use the Playground. If you click on The Hub, under “Public Endpoints,” you will see a listing for “P-Video-Edit”. You can edit parameters, add your own images, and make the request directly.

Runpod P-Video-Edit Playground showing a prompt, upload fields, and generated SUV video

The response you get back should look like this once it’s completed:

{
  "delayTime": 8607,
  "executionTime": 252132,
  "id": "sync-a574c4ff-2001-4b59-b689-488ea7363ab0-u2",
  "output": {
    "cost": 0.2268,
    "result": "https://image.runpod.ai/p-video/edit/a920b5c19c714e3d9f2af475fbd34049/result.mp4"
  },
  "status": "COMPLETED",
  "workerId": "phsmefxookxvwp"
}

Curl request

To get started making requests with this endpoint, you can use curl. Video editing can take several minutes, so this example uses Runpod’s asynchronous workflow instead of waiting for one long-lived HTTP request.

The first request sends the input to /run. Runpod accepts the job immediately and returns an id, but the video is not ready yet. The script saves that ID and sends a GET request to /status/{job_id} every five seconds. While the job is queued or running, it prints the current status. When the status changes to COMPLETED, the generated video URL is available at output.result.

This example uses jq to read the JSON responses. Make sure it is installed, then set RUNPOD_API_KEY in your environment before running the script:

export RUNPOD_API_KEY="YOUR_API_KEY"

Keeping the API key in an environment variable prevents it from being copied directly into the script.

BASE_URL="https://api.runpod.ai/v2/p-video-edit"

RUN_RESPONSE=$(curl --silent --show-error --fail \
  --request POST \
  --url "$BASE_URL/run" \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $RUNPOD_API_KEY" \
  --data '{
    "input": {
      "prompt": "Add the roof cargo box shown in the reference image to the SUV. Match its shape, matte-black material and proportions. Keep it rigidly attached and correctly aligned to the vehicle roof throughout the camera movement. Preserve the vehicle body, windows, trim, wheels, pedestrian, environment and lighting.",
      "video": "https://image.runpod.ai/test/pruna/p-video-edit/test.mp4",
      "prompt_upsampling": true,
      "draft": false,
      "save_audio": true,
      "seed": 0,
      "images": [
        "https://image.runpod.ai/uploads/907XnLTSFm/f876233c-8d67-45b5-a347-9b063795fe74.png",
        "https://image.runpod.ai/uploads/dWeJxLfk_B/b8fa8e1c-0f75-43c2-9440-4c6ec15c5183.png",
        "https://image.runpod.ai/uploads/qq7zw1TW9m/567cbf13-0745-4e38-879b-f730a00d5d76.png"
      ]
    }
  }')

JOB_ID=$(printf '%s' "$RUN_RESPONSE" | jq --raw-output '.id // empty')

if [ -z "$JOB_ID" ]; then
  printf 'The job submission did not return an ID:\n%s\n' "$RUN_RESPONSE" >&2
  exit 1
fi

printf 'Job submitted: %s\n' "$JOB_ID"

while true; do
  STATUS_RESPONSE=$(curl --silent --show-error --fail \
    --request GET \
    --url "$BASE_URL/status/$JOB_ID" \
    --header "Authorization: Bearer $RUNPOD_API_KEY")

  STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq --raw-output '.status')

  case "$STATUS" in
    COMPLETED)
      printf 'Video URL: %s\n' \
        "$(printf '%s' "$STATUS_RESPONSE" | jq --raw-output '.output.result')"
      break
      ;;
    FAILED|CANCELLED|TIMED_OUT)
      printf 'Job ended with status %s:\n%s\n' \
        "$STATUS" "$STATUS_RESPONSE" >&2
      exit 1
      ;;
    *)
      printf 'Status: %s. Waiting...\n' "$STATUS"
      sleep 5
      ;;
  esac
done

The script prints the job ID as soon as Runpod accepts the request. During processing, you will see status messages such as IN_QUEUE and IN_PROGRESS. A successful job ends by printing a line like this:

Video URL: https://image.runpod.ai/p-video/edit/.../result.mp4

Open or download that URL to retrieve the edited video. If the job reaches FAILED, CANCELLED, or TIMED_OUT instead, the script prints the full status response and exits with an error so the failure is not mistaken for a successful result.

Python

You can follow the same submit-and-poll flow in Python with the requests package. This model isn’t compatible with OpenAI’s SDK, so the example calls the Runpod API directly.

Install requests if it is not already available:

python -m pip install requests

As in the curl example, set RUNPOD_API_KEY in your environment before running the script. The initial POST submits the job and provides its ID. The polling loop then checks the corresponding status route until the job reaches a terminal state. Each HTTP request also uses a 30-second network timeout, which prevents a single stalled connection from hanging indefinitely; it does not limit how long the video job itself can run.

import os
import time

import requests


base_url = "https://api.runpod.ai/v2/p-video-edit"
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {os.environ['RUNPOD_API_KEY']}",
}

payload = {
    "input": {
        "prompt": (
            "Add the roof cargo box shown in the reference image to the SUV. "
            "Match its shape, matte-black material and proportions. Keep it "
            "rigidly attached and correctly aligned to the vehicle roof throughout "
            "the camera movement. Preserve the vehicle body, windows, trim, wheels, "
            "pedestrian, environment and lighting."
        ),
        "video": "https://image.runpod.ai/test/pruna/p-video-edit/test.mp4",
        "prompt_upsampling": True,
        "draft": False,
        "save_audio": True,
        "seed": 0,
        "images": [
            "https://image.runpod.ai/uploads/907XnLTSFm/f876233c-8d67-45b5-a347-9b063795fe74.png",
            "https://image.runpod.ai/uploads/dWeJxLfk_B/b8fa8e1c-0f75-43c2-9440-4c6ec15c5183.png",
            "https://image.runpod.ai/uploads/qq7zw1TW9m/567cbf13-0745-4e38-879b-f730a00d5d76.png",
        ],
    }
}

response = requests.post(
    f"{base_url}/run",
    headers=headers,
    json=payload,
    timeout=30,
)
response.raise_for_status()

job_id = response.json()["id"]
print(f"Job submitted: {job_id}")

while True:
    response = requests.get(
        f"{base_url}/status/{job_id}",
        headers=headers,
        timeout=30,
    )
    response.raise_for_status()

    result = response.json()
    status = result["status"]

    if status == "COMPLETED":
        print(f"Video URL: {result['output']['result']}")
        break

    if status in {"FAILED", "CANCELLED", "TIMED_OUT"}:
        raise RuntimeError(f"Job ended with status {status}: {result}")

    print(f"Status: {status}. Waiting...")
    time.sleep(5)

When the job completes, the script reads result["output"]["result"] and prints the generated video URL. For unsuccessful terminal states, it raises a RuntimeError containing the response body, which gives you the status details needed for troubleshooting.

This polling structure is reusable across Runpod public endpoints. For another endpoint, change base_url, replace the request payload with that model’s input, and update the final output lookup to match its response shape. The /run and /status/{job_id} lifecycle remains the same.

Conclusion

P-Video-Edit is Pruna AI’s instruction-driven video editing model that transforms videos up to 15 seconds using a single text instruction, with optional support for up to four reference images. Be sure to let us know on Discord, in the #built-on-runpod channel, if you build anything with it.

Build what’s next.

Build, train, and scale AI workloads on Runpod with cloud GPUs, Serverless, and Clusters.

Star field background