ProductAIDocs
Get API Key

API Reference

Jobs

Monitor and retrieve results from image and video generation jobs — by polling or via webhooks.

GET/v1/api/job/{job_id}

Get the status and result of a generation job. Works for both image and video jobs.

Path parameters

job_idintegerrequired
The job ID (data.id) returned from Generate Image, Generate Video, or Upscale. Returns 400 if the job doesn't exist or belongs to another account.

Response fields

data.idinteger
Job identifier.
data.statusstring
One of: NOT_STARTED, RUNNING, COMPLETED, ERROR.
data.promptstring
The prompt used for this job.
data.image_urlstring
URL of the generated file — only present when the job is COMPLETED. For video jobs this is the video file URL.
Request
curl "https://api.productai.photo/v1/api/job/287344" \
  -H "x-api-key: YOUR_API_KEY"
Response · 200 OK
{
  "status": "OK",
  "data": {
    "id": 287344,
    "status": "RUNNING",
    "prompt": "Place the product on a marble table with soft lighting"
  }
}

Polling pattern

Poll the job endpoint until the status is COMPLETED or ERROR. Recommended interval: 2-5 seconds for images; video jobs can take a few minutes, so poll less aggressively or use webhooks.

import requests
import time

def wait_for_job(job_id, api_key, timeout=300):
    url = f"https://api.productai.photo/v1/api/job/{job_id}"
    headers = {"x-api-key": api_key}

    start = time.time()
    while time.time() - start < timeout:
        response = requests.get(url, headers=headers)
        job = response.json()["data"]

        if job["status"] == "COMPLETED":
            return job["image_url"]
        elif job["status"] == "ERROR":
            raise Exception(f"Job {job_id} failed")

        time.sleep(3)

    raise TimeoutError("Job did not complete in time")

# Usage
image_url = wait_for_job(287344, "YOUR_API_KEY")
print(image_url)

Webhooks

Instead of polling, set a webhook URL on the API Access page. We'll POST the result of every job to that endpoint as it completes. Your endpoint should return 200 to acknowledge receipt.

status is success or error. On error, image_url is omitted.

Webhook payload
POST https://your-server.com/webhook
Content-Type: application/json

{
  "status": "success",
  "image_url": "https://…s3.amazonaws.com/generations/287344/result.png",
  "job_id": "287344"
}

Static source IPs

All webhook requests originate from two static addresses. If your firewall restricts inbound traffic, allowlist both — deliveries are load balanced across the pair, so any individual request may come from either one.

Webhook source IPs
54.88.136.216
54.84.188.199

Verifying your endpoint

When you save a webhook URL we immediately send a test request from the same addresses, so it doubles as a check that your allowlist is correct.
Validation request
POST https://your-server.com/webhook
User-Agent: ProductAI-Webhook-Validator/1.0

{
  "test": true,
  "message": "Webhook validation test from ProductAI"
}