API Documentation
Integrate Canvasvid into your own applications. Available to Pro subscribers.
Authentication
All API requests require a valid API key sent in the Authorization header.
API keys are available to Pro subscribers only. Generate your key from Settings in the Canvasvid dashboard.
Header format
Authorization: Bearer cvid_live_your_api_key_here
Keep your API key secret. Do not expose it in client-side code, public repositories, or browser requests. Use it only from your server.
Base URL
https://us-central1-canvasvid.cloudfunctions.net/api
All endpoint paths below are relative to this base URL.
Response Format
All responses are JSON with a standard envelope:
Success (2xx)
{
"ok": true,
"data": {
"id": "abc123",
"status": "pending"
}
} Error (4xx / 5xx)
{
"ok": false,
"error": {
"code": "insufficient_credits",
"message": "Not enough credits."
}
} Error Codes
| HTTP | Code | Description |
|---|---|---|
| 400 | invalid_argument | Missing or invalid request parameter |
| 401 | unauthorized | Invalid API key or inactive subscription |
| 402 | insufficient_credits | Not enough credits for this operation |
| 404 | not_found | Resource not found or not owned by you |
| 429 | rate_limited | Too many requests — wait and retry |
| 500 | internal | Unexpected server error |
Rate Limits
Each endpoint has a per-user rate limit using a sliding window. Exceeding the limit returns a 429 response.
| Endpoint | Limit | Window |
|---|---|---|
| POST /v1/generations | 20 requests | 60 seconds |
| GET /v1/generations/:id | 60 requests | 60 seconds |
| GET /v1/generations | 30 requests | 60 seconds |
| POST /v1/tool-runs | 30 requests | 60 seconds |
| GET /v1/tool-runs/:id | 60 requests | 60 seconds |
| GET /v1/account/credits | 60 requests | 60 seconds |
Endpoints
/v1/generations
Create a new image or video generation. The generation runs asynchronously — poll GET /v1/generations/:id to check status.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| productImageUrl | string | Yes | Public URL of the product image |
| style | string | Yes | clean, lifestyle, bold, or aesthetic |
| mode | string | No | image (default), video, both, mockup |
| imageRatio | string | No | 1:1 (default), 4:5, 9:16, 16:9 |
| imageCount | number | No | 3 (default), 6, or 9 |
| customPrompts | string[] | No | Custom prompts for each image variation |
| locale | string | No | en (default) or id |
Response
{
"ok": true,
"data": {
"id": "gen_abc123",
"status": "pending"
}
} /v1/generations/:id
Get the status and results of a generation. Poll this endpoint until status is completed or failed.
Response (completed)
{
"ok": true,
"data": {
"id": "gen_abc123",
"status": "completed",
"mode": "image",
"style": "clean",
"createdAt": "2025-01-15T10:30:00Z",
"completedAt": "2025-01-15T10:31:15Z",
"results": {
"images": ["https://...image1.png", "https://...image2.png"],
"captions": ["Caption for image 1", "Caption for image 2"],
"hashtags": ["#product", "#design"]
},
"creditsCost": 5
}
}
Status values: pending → processing → completed | failed
/v1/generations List your generations with cursor-based pagination.
Query Parameters
| limit | number | Items per page (1–100, default 20) |
| startAfter | string | Generation ID to start after (from nextCursor) |
Response
{
"ok": true,
"data": {
"items": [
{ "id": "gen_abc", "status": "completed", "mode": "image", "style": "clean", "createdAt": "..." }
],
"hasMore": true,
"nextCursor": "gen_abc"
}
} /v1/tool-runs
Execute a tool (e.g., remove background, upscale, face swap). Some tools complete synchronously; others return status: "processing" — poll GET /v1/tool-runs/:id.
Request Body
| featureId | string | Required | Tool identifier (see Credit Costs) |
| input | object | Required | Tool-specific input (e.g., {"imageUrl": "https://..."}) |
Response
{
"ok": true,
"data": {
"id": "run_xyz789",
"featureId": "remove-background",
"status": "completed",
"creditsCost": 1,
"output": { "imageUrl": "https://...result.png" }
}
} /v1/tool-runs/:id Get the status and output of a tool run.
Response
{
"ok": true,
"data": {
"id": "run_xyz789",
"featureId": "upscale",
"status": "completed",
"creditsCost": 2,
"output": { "imageUrl": "https://...upscaled.png" },
"createdAt": "2025-01-15T10:30:00Z",
"completedAt": "2025-01-15T10:30:12Z"
}
} /v1/account/credits Check your current credit balance.
Response
{
"ok": true,
"data": {
"creditsRemaining": 142
}
} Credit Costs
Each tool deducts credits from your balance. Here are the most common tools:
| Tool (featureId) | Credits |
|---|---|
| remove-background | 1 |
| upscale | 2 |
| restore-photo | 3 |
| remove-object | 3 |
| face-swap | 3–5 |
| edit-photo | 4 |
| expand-photo | 4 |
| text-to-image | 4–10 |
| merge-photos | 5 |
| product-with-model | 6 |
| carousel-creator | 8–12 |
| image-to-video | 10–18 |
| product-video | 12 |
| storyboard-video | 20 |
Tools not listed here typically cost 3–5 credits. The exact cost is returned in the creditsCost field of every response.
Code Examples
cURL
Create a generation
curl -X POST https://us-central1-canvasvid.cloudfunctions.net/api/v1/generations \
-H "Authorization: Bearer cvid_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"productImageUrl": "https://example.com/product.jpg",
"style": "clean",
"mode": "image",
"imageCount": 3
}' Check generation status
curl https://us-central1-canvasvid.cloudfunctions.net/api/v1/generations/gen_abc123 \ -H "Authorization: Bearer cvid_live_your_key"
Remove background from an image
curl -X POST https://us-central1-canvasvid.cloudfunctions.net/api/v1/tool-runs \
-H "Authorization: Bearer cvid_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"featureId": "remove-background",
"input": { "imageUrl": "https://example.com/photo.jpg" }
}' JavaScript / Node.js
const API_KEY = "cvid_live_your_key";
const BASE = "https://us-central1-canvasvid.cloudfunctions.net/api";
// Create a generation
const res = await fetch(`${BASE}/v1/generations`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
productImageUrl: "https://example.com/product.jpg",
style: "clean",
mode: "image",
imageCount: 3,
}),
});
const { data } = await res.json();
console.log("Generation ID:", data.id);
// Poll for results
async function waitForCompletion(genId) {
while (true) {
const res = await fetch(`${BASE}/v1/generations/${genId}`, {
headers: { "Authorization": `Bearer ${API_KEY}` },
});
const { data } = await res.json();
if (data.status === "completed") return data.results;
if (data.status === "failed") throw new Error(data.errorMessage);
await new Promise((r) => setTimeout(r, 5000)); // wait 5s
}
}
const results = await waitForCompletion(data.id);
console.log("Images:", results.images); Python
import requests
import time
API_KEY = "cvid_live_your_key"
BASE = "https://us-central1-canvasvid.cloudfunctions.net/api"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
# Create a generation
res = requests.post(f"{BASE}/v1/generations", headers=HEADERS, json={
"productImageUrl": "https://example.com/product.jpg",
"style": "clean",
"mode": "image",
"imageCount": 3,
})
gen_id = res.json()["data"]["id"]
print(f"Generation ID: {gen_id}")
# Poll for results
while True:
res = requests.get(f"{BASE}/v1/generations/{gen_id}", headers=HEADERS)
data = res.json()["data"]
if data["status"] == "completed":
print("Images:", data["results"]["images"])
break
elif data["status"] == "failed":
print("Error:", data["errorMessage"])
break
time.sleep(5)
# Run a tool
res = requests.post(f"{BASE}/v1/tool-runs", headers=HEADERS, json={
"featureId": "remove-background",
"input": {"imageUrl": "https://example.com/photo.jpg"},
})
print("Result:", res.json()["data"])