Quickstart
Get up and running with P-API in just a few minutes. This guide covers authentication, file uploads, and making your first image generation requests.
Getting Your API Key
Section titled “Getting Your API Key”Create your API key yourself in the Pruna dashboard:
- Sign up or log in at dashboard.pruna.ai.
- Go to API Keys and accept the Terms of Service and the DPA.
- If your account is billed with credits, add a payment method in Billing.
- Click Create New API Key in API Keys.
- Copy the key and store it securely.
Once you have your API key, include it in the apikey header for all requests:
curl -H "apikey: YOUR_API_KEY" https://api.pruna.ai/v1/<endpoint> <body>Your First Request: Generate an Image
Section titled “Your First Request: Generate an Image”Let's generate an image using the P-Image model. We'll use synchronous mode (Try-Sync: true) to get results immediately:
curl -X POST https://api.pruna.ai/v1/predictions \-H "apikey: YOUR_API_KEY" \-H "Model: p-image" \-H "Try-Sync: true" \-H "Content-Type: application/json" \-d '{"input": {"prompt": "A majestic lion standing on a rocky cliff at sunset, photorealistic, 4k","aspect_ratio": "16:9"}}'Response (if completed within 60 seconds):
{"status": "succeeded","generation_url": "https://api.pruna.ai/v1/predictions/delivery/xezq/abc123.../output.jpg"}Download your image:
curl -H "apikey: YOUR_API_KEY" \ https://api.pruna.ai/v1/predictions/delivery/xezq/abc123.../output.jpg \ -o my-image.jpg
File Upload & Image Editing
Section titled “File Upload & Image Editing”To edit images with P-Image-Edit, you'll first need to upload your reference images:
Step 1: Upload Your Images
Section titled “Step 1: Upload Your Images”Upload first image
Section titled “Upload first image”curl -X POST https://api.pruna.ai/v1/files \-H "apikey: YOUR_API_KEY" \-F "content=@my-photo.jpg" \> upload1.jsonResponse:
{"id": "file-abc123","urls": {"get": "https://api.pruna.ai/v1/files/file-abc123"}}Upload second image (optional, p-image-edit supports 1-5 images)
Section titled “Upload second image (optional, p-image-edit supports 1-5 images)”curl -X POST https://api.pruna.ai/v1/files \-H "apikey: YOUR_API_KEY" \-F "content=@another-photo.jpg" \> upload2.jsonResponse:
{"id": "file-abc123","urls": {"get": "https://api.pruna.ai/v1/files/file-def456"}}Step 2: Edit Your Images
Section titled “Step 2: Edit Your Images”Use the uploaded file URLs in your editing request:
curl -X POST https://api.pruna.ai/v1/predictions \-H "apikey: YOUR_API_KEY" \-H "Model: p-image-edit" \-H "Try-Sync: true" \-H "Content-Type: application/json" \-d '{"input": {"prompt": "Transform into a watercolor painting style with vibrant colors","images": ["https://api.pruna.ai/v1/files/file-abc123","https://api.pruna.ai/v1/files/file-xyz789"],"reference_image": "1","aspect_ratio": "16:9"}}'Response:
{"status": "succeeded","generation_url": "https://api.pruna.ai/v1/predictions/delivery/xezq/def456.../output.jpg"}Asynchronous Workflow (For Longer Requests)
Section titled “Asynchronous Workflow (For Longer Requests)”Some models or complex requests may take longer than 60 seconds. For these, use the asynchronous workflow to avoid timeouts:
Step 1: Submit Request (Without Try-Sync)
Section titled “Step 1: Submit Request (Without Try-Sync)”curl -X POST https://api.pruna.ai/v1/predictions \-H "apikey: YOUR_API_KEY" \-H "Model: p-image-edit" \-H "Content-Type: application/json" \-d '{"input": {"prompt": "Complex artistic transformation with multiple effects","images": ["https://api.pruna.ai/v1/files/file-abc123"]}}'Response:
{"id": "1zww7deyssrme0csqwr90phzzr","model": "p-image-edit","input": { ... },"get_url": "https://api.pruna.ai/v1/predictions/status/1zww7deyssrme0csqwr90phzzr"}Step 2: Check Status
Section titled “Step 2: Check Status”Poll the status endpoint to check progress:
curl -H "apikey: YOUR_API_KEY" \https://api.pruna.ai/v1/predictions/status/1zww7deyssrme0csqwr90phzzrResponse (Starting):
{"status": "starting","message": "Generation in progress"}Response (Processing):
{"status": "processing","message": "Generation in progress"}Response (Completed):
"status": "succeeded","generation_url": "https://api.pruna.ai/v1/predictions/delivery/xezq/52UGYRrRfqViaKmvYsEnENTh0qLDAWHptQ8jOnEHu7XC6AtKA/output.mp4"}Response (Failed):
{"status": "failed","message": "Prediction failed","error": "Number of samples, -5, must be non-negative.","moderation": null}Response (Blocked by content moderation):
{"status": "failed","message": "Prediction failed","error": "Prediction failed: Content moderation: Blocked by the safety filter (copyright_detected). You can disable it through the API with enable_copyright_filter=false.","moderation": { "blocked": true, "phase": "input", "categories": ["copyright_detected"], "reason": "Blocked by content policy (copyright_detected). ...", "can_disable": true, "message": "Blocked by the safety filter (copyright_detected). You can disable it through the API with enable_copyright_filter=false."}}moderation is set when content moderation blocked the request, and null for any other failure. categories lists what was detected, for example copyright_detected when enable_copyright_filter is on. can_disable is false when a category is always enforced, so no request parameter can lift the block. message is the same short explanation as the error text. This works the same for every model.
Step 3: Download Result
Section titled “Step 3: Download Result”curl -H "apikey: YOUR_API_KEY" \https://api.pruna.ai/v1/predictions/delivery/xezq/abc123.../output.jpg \-o result.jpgWhen to Use Each Workflow
Section titled “When to Use Each Workflow”Asynchronous Mode (recommended)
- ✅ Video generation models (wan-i2v, wan-t2v, vace)
- ✅ Complex image processing that may take longer
- ✅ When you want to avoid timeout issues
- ✅ When processing multiple requests in parallel (causing a spike in usage will trigger infrastructure scaling and queuing of your requests)
Synchronous Mode (Try-Sync: true)
- ✅ Fast models like p-image, p-image-edit, wan-image-small
- ✅ Simple requests with quick processing times
- ✅ When you need immediate results in a single request
- ❌ Not recommended for video models or complex edits that may take ~10 seconds or more
In synchronous mode, a prediction blocked by content moderation returns HTTP 422 (see Blocked requests), any other failure HTTP 500, and a canceled prediction HTTP 499, each with the same body as the status endpoint above. A 422 with a non-null moderation is a block; do not retry it unchanged.
Blocked requests
Section titled “Blocked requests”Content moderation can block a request. The prediction then fails with status: "failed" and a non-null moderation object, as in "Response (Blocked by content moderation)" above.
- Without
Try-Sync, the status endpoint returns that body. - With
Try-Sync: true, the create call usually returns HTTP 422 with that body. If the block lands just after the gateway answers, the create call returns HTTP 201 with anidandget_urlinstead. Poll the status endpoint, which then returns themoderationobject.
The error text names the parameter that lifts the block, and each model page lists it. When moderation.can_disable is false, the category is always enforced and no parameter lifts it. Do not retry a blocked request unchanged.
Note: use the synchronous mode at your own risk, you may encounter timeouts / 504 errors. Async mode is safer, but the sync mode gets you the results faster and with less code.
Rate Limits
Section titled “Rate Limits”Different models have different rate limits:
- P-Models (p-image, p-image-edit): 500 requests/minute
- Other Image Models (flux-dev, qwen-image, etc.): 150 requests/minute
- Video Models (wan-i2v, wan-t2v, vace): 30 requests/minute
- Status Endpoint: 30,000 requests/minute
- Delivery Endpoint: 10,000 requests/minute
Next Steps
Section titled “Next Steps”- Explore all /models and their capabilities
- Learn about /api-reference for fine-tuning results
- Check out /examples for inspiration
Need help? Contact us.