Jobs
Monitor and retrieve results from image generation jobs.
GET
/v1/jobs/{job_id}Get the status and results of a generation job.
Headers
Authorization: Bearer YOUR_API_KEY
Path Parameters
| Parameter | Type | Description |
|---|---|---|
job_id | string | The job ID returned from the generate endpoint. |
Example Request
curl "https://api.productai.photo/v1/jobs/job_abc123xyz" \ -H "Authorization: Bearer YOUR_API_KEY"
Response - Pending/Processing
{
"job_id": "job_abc123xyz",
"status": "processing",
"progress": 45,
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"model": "nanobanana2",
"num_images": 2
}Response - Completed
{
"job_id": "job_abc123xyz",
"status": "completed",
"progress": 100,
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"completed_at": "2024-01-15T10:30:35Z",
"model": "nanobanana2",
"num_images": 2,
"images": [
{
"url": "https://cdn.productai.photo/generated/img_001.jpg",
"width": 1024,
"height": 1024
},
{
"url": "https://cdn.productai.photo/generated/img_002.jpg",
"width": 1024,
"height": 1024
}
],
"tokens_used": 10
}Response - Failed
{
"job_id": "job_abc123xyz",
"status": "failed",
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"failed_at": "2024-01-15T10:30:15Z",
"error": {
"code": "generation_failed",
"message": "Unable to process the input image"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
job_id | string | Unique job identifier. |
status | string | One of: pending, processing, completed, failed |
progress | integer | Progress percentage (0-100). |
images | array | Generated images (only present when completed). |
images[].url | string | CDN URL of the generated image. |
tokens_used | integer | Number of credits consumed. |
error | object | Error details (only present when failed). |
GET
/v1/jobsList all jobs for the authenticated user.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Number of jobs to return. Max: 100. |
offset | integer | 0 | Number of jobs to skip. |
status | string | all | Filter by status. |
Example Request
curl "https://api.productai.photo/v1/jobs?limit=10&status=completed" \ -H "Authorization: Bearer YOUR_API_KEY"
Success Response (200 OK)
{
"jobs": [
{
"job_id": "job_abc123xyz",
"status": "completed",
"model": "nanobanana2",
"num_images": 2,
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:30:35Z"
}
],
"total": 156,
"limit": 10,
"offset": 0,
"has_more": true
}Polling Pattern
Poll the job status endpoint until the job completes. Recommended polling interval: 2-5 seconds.
Python
import requests
import time
def wait_for_job(job_id, api_key, timeout=120):
url = f"https://api.productai.photo/v1/jobs/{job_id}"
headers = {"Authorization": f"Bearer {api_key}"}
start = time.time()
while time.time() - start < timeout:
response = requests.get(url, headers=headers)
job = response.json()
if job["status"] == "completed":
return job["images"]
elif job["status"] == "failed":
raise Exception(job["error"]["message"])
time.sleep(3)
raise TimeoutError("Job did not complete in time")
# Usage
images = wait_for_job("job_abc123xyz", "YOUR_API_KEY")
for img in images:
print(img["url"])JavaScript
async function waitForJob(jobId, apiKey, timeout = 120000) {
const url = `https://api.productai.photo/v1/jobs/${jobId}`;
const start = Date.now();
while (Date.now() - start < timeout) {
const response = await fetch(url, {
headers: { "Authorization": `Bearer ${apiKey}` }
});
const job = await response.json();
if (job.status === "completed") return job.images;
if (job.status === "failed") throw new Error(job.error.message);
await new Promise(r => setTimeout(r, 3000));
}
throw new Error("Job timed out");
}
// Usage
const images = await waitForJob("job_abc123xyz", "YOUR_API_KEY");
images.forEach(img => console.log(img.url));Webhooks
Instead of polling, you can provide a webhook_url when creating a job. We'll POST the completed job to your endpoint.
Webhook Payload
POST https://your-server.com/webhook
Content-Type: application/json
X-ProductAI-Signature: sha256=...
{
"event": "job.completed",
"job_id": "job_abc123xyz",
"status": "completed",
"images": [
{"url": "https://cdn.productai.photo/generated/img_001.jpg", "width": 1024, "height": 1024}
],
"tokens_used": 5,
"completed_at": "2024-01-15T10:30:35Z"
}