> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pictory.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Image Generation Job

> Retrieve the status and output of an AI image generation job

## Overview

This endpoint retrieves the current status and output of an AI image generation job using its unique job ID. While the generation is in progress, it returns the job status. Once the image generation completes, it returns the output including the image URL, dimensions, and AI credits consumed.

<Note>
  A valid API key is required to use this endpoint. Obtain your API key from the [API Access page](https://app.pictory.ai/api-access) in your Pictory dashboard.
</Note>

***

## API Endpoint

```http theme={null}
GET https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}
```

***

## Request Parameters

### Path Parameters

<ParamField path="jobid" type="uuid" required>
  The unique identifier (UUID) of the image generation job. This is the `jobId` returned by the [Generate Image](/api-reference/ai-studio/generate-image) endpoint.

  **Example:** `"4d82d040-4394-4371-867d-72ae1dd62b6d"`
</ParamField>

### Headers

<ParamField header="Authorization" type="string" required>
  API key for authentication (starts with `pictai_`)

  ```
  Authorization: YOUR_API_KEY
  ```
</ParamField>

***

## Response

### In-Progress Response

Returned while the image is being generated:

<ResponseField name="job_id" type="string">
  The unique identifier of the image generation job
</ResponseField>

<ResponseField name="success" type="boolean">
  `true` while the job is processing
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="status" type="string">
    `"in-progress"` while the image is still being generated
  </ResponseField>
</ResponseField>

### Completed Response

Returned when the image has been generated successfully:

<ResponseField name="job_id" type="string">
  The unique identifier of the image generation job
</ResponseField>

<ResponseField name="success" type="boolean">
  `true` when the job has completed successfully
</ResponseField>

<ResponseField name="data" type="object">
  Contains the image generation output.

  <ResponseField name="status" type="string">
    `"completed"` when the image has been generated successfully
  </ResponseField>

  <ResponseField name="url" type="string">
    Direct download URL for the generated image file (PNG)
  </ResponseField>

  <ResponseField name="width" type="number">
    Width of the generated image in pixels
  </ResponseField>

  <ResponseField name="height" type="number">
    Height of the generated image in pixels
  </ResponseField>

  <ResponseField name="aiCreditsUsed" type="number">
    Number of AI credits consumed for this image generation
  </ResponseField>
</ResponseField>

### Failed Response

Returned when the image generation job has failed:

<ResponseField name="job_id" type="string">
  The unique identifier of the image generation job
</ResponseField>

<ResponseField name="success" type="boolean">
  `false` when the job has failed
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="status" type="string">
    `"failed"` when the image generation has failed
  </ResponseField>

  <ResponseField name="error_code" type="string">
    Error code identifying the failure type (e.g., `"5001"`)
  </ResponseField>

  <ResponseField name="error_message" type="string">
    Descriptive message explaining the cause of the failure
  </ResponseField>
</ResponseField>

### Response Examples

<ResponseExample>
  ```json 200 - In Progress theme={null}
  {
      "job_id": "4d82d040-4394-4371-867d-72ae1dd62b6d",
      "success": true,
      "data": {
          "status": "in-progress"
      }
  }
  ```

  ```json 200 - Completed theme={null}
  {
      "job_id": "4d82d040-4394-4371-867d-72ae1dd62b6d",
      "success": true,
      "data": {
          "width": 1280,
          "aiCreditsUsed": 2,
          "height": 720,
          "url": "https://example.cloudfront.net/images/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890/f8e7d6c5-b4a3-2190-fedc-ba0987654321.png",
          "status": "completed"
      }
  }
  ```

  ```json 200 - Failed theme={null}
  {
      "job_id": "4d82d040-4394-4371-867d-72ae1dd62b6d",
      "success": false,
      "data": {
          "status": "failed",
          "error_code": "5001",
          "error_message": "Image generation failed due to an internal error."
      }
  }
  ```

  ```json 200 - Invalid Job ID theme={null}
  {
      "id": "4d82d040-4394-4371-867d-72ae1dd62b6d",
      "success": false,
      "data": {
          "error_code": "5000",
          "error_message": "JOB_NOT_FOUND"
      }
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
      "message": "Unauthorized"
  }
  ```
</ResponseExample>

***

## Status Codes

| Status Code | Description                                                                                                                              |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **200**     | Request processed successfully. Check the `status` field in `data` to determine the job state (`in-progress`, `completed`, or `failed`). |
| **401**     | Unauthorized. The API key in the `Authorization` header is missing or invalid.                                                           |
| **404**     | Job not found. The provided `jobid` does not match any existing job.                                                                     |
| **500**     | Internal server error. Retry the request after a brief delay.                                                                            |

***

## Completed Response Fields

| Field           | Description                                           |
| --------------- | ----------------------------------------------------- |
| `url`           | Direct download link for the generated PNG image file |
| `width`         | Width of the generated image in pixels                |
| `height`        | Height of the generated image in pixels               |
| `aiCreditsUsed` | Number of AI credits consumed for this generation     |

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key and use the `jobId` returned from the [Generate Image](/api-reference/ai-studio/generate-image) endpoint.
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.pictory.ai/pictoryapis/v1/jobs/4d82d040-4394-4371-867d-72ae1dd62b6d' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'accept: application/json' | python -m json.tool
  ```

  ```python Python theme={null}
  import requests
  import time

  def poll_image_job(api_key, job_id, max_wait=300, poll_interval=15):
      """
      Poll for image generation job completion.

      Args:
          api_key: Your Pictory API key
          job_id: The image generation job ID
          max_wait: Maximum wait time in seconds (default 5 minutes)
          poll_interval: Polling interval in seconds (default 15 seconds)
      """
      url = f"https://api.pictory.ai/pictoryapis/v1/jobs/{job_id}"
      headers = {
          "Authorization": api_key,
          "accept": "application/json"
      }

      start_time = time.time()

      while time.time() - start_time < max_wait:
          response = requests.get(url, headers=headers)
          data = response.json()

          if not data.get("success"):
              error_data = data.get("data", {})
              print(f"Job failed: {error_data.get('error_message', 'Unknown error')}")
              return data

          status = data.get("data", {}).get("status")

          if status == "in-progress":
              print("Image generation in progress...")
              time.sleep(poll_interval)
              continue

          if status == "completed":
              result = data["data"]
              print(f"Image generated successfully!")
              print(f"Image URL: {result.get('url')}")
              print(f"Dimensions: {result.get('width')}x{result.get('height')}")
              print(f"AI Credits Used: {result.get('aiCreditsUsed')}")
              return data

          if status == "failed":
              error_msg = data["data"].get("error_message", "Unknown error")
              print(f"Image generation failed: {error_msg}")
              return data

          print(f"Unexpected status: {status}")
          return data

      print("Timeout waiting for image generation")
      return None

  # Usage
  result = poll_image_job("YOUR_API_KEY", "4d82d040-4394-4371-867d-72ae1dd62b6d")
  ```

  ```javascript JavaScript theme={null}
  async function pollImageJob(apiKey, jobId, maxWait = 300000, pollInterval = 15000) {
    const url = `https://api.pictory.ai/pictoryapis/v1/jobs/${jobId}`;
    const startTime = Date.now();

    while (Date.now() - startTime < maxWait) {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Authorization': apiKey,
          'accept': 'application/json'
        }
      });

      const data = await response.json();

      if (!data.success) {
        console.log(`Job failed: ${data.data?.error_message || 'Unknown error'}`);
        return data;
      }

      const status = data.data?.status;

      if (status === 'in-progress') {
        console.log('Image generation in progress...');
        await new Promise(resolve => setTimeout(resolve, pollInterval));
        continue;
      }

      if (status === 'completed') {
        console.log('Image generated successfully!');
        console.log(`Image URL: ${data.data.url}`);
        console.log(`Dimensions: ${data.data.width}x${data.data.height}`);
        console.log(`AI Credits Used: ${data.data.aiCreditsUsed}`);
        return data;
      }

      if (status === 'failed') {
        console.log(`Image generation failed: ${data.data?.error_message}`);
        return data;
      }

      console.log(`Unexpected status: ${status}`);
      return data;
    }

    console.log('Timeout waiting for image generation');
    return null;
  }

  // Usage
  const result = await pollImageJob('YOUR_API_KEY', '4d82d040-4394-4371-867d-72ae1dd62b6d');
  ```

  ```php PHP theme={null}
  <?php
  function pollImageJob($apiKey, $jobId, $maxWait = 300, $pollInterval = 15) {
      $url = "https://api.pictory.ai/pictoryapis/v1/jobs/{$jobId}";
      $startTime = time();

      while (time() - $startTime < $maxWait) {
          $ch = curl_init($url);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
              'Authorization: ' . $apiKey,
              'accept: application/json'
          ]);

          $response = curl_exec($ch);
          curl_close($ch);

          $data = json_decode($response, true);

          if (!$data['success']) {
              echo "Job failed: " . ($data['data']['error_message'] ?? 'Unknown error') . "\n";
              return $data;
          }

          $status = $data['data']['status'] ?? null;

          if ($status === 'in-progress') {
              echo "Image generation in progress...\n";
              sleep($pollInterval);
              continue;
          }

          if ($status === 'completed') {
              echo "Image generated successfully!\n";
              echo "Image URL: " . ($data['data']['url'] ?? '') . "\n";
              echo "Dimensions: " . ($data['data']['width'] ?? 0) . "x" . ($data['data']['height'] ?? 0) . "\n";
              echo "AI Credits Used: " . ($data['data']['aiCreditsUsed'] ?? 0) . "\n";
              return $data;
          }

          if ($status === 'failed') {
              echo "Image generation failed: " . ($data['data']['error_message'] ?? 'Unknown error') . "\n";
              return $data;
          }

          echo "Unexpected status: {$status}\n";
          return $data;
      }

      echo "Timeout waiting for image generation\n";
      return null;
  }

  // Usage
  $result = pollImageJob('YOUR_API_KEY', '4d82d040-4394-4371-867d-72ae1dd62b6d');
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "encoding/json"
      "fmt"
      "io"
      "net/http"
      "time"
  )

  func pollImageJob(apiKey, jobID string, maxWait, pollInterval time.Duration) (map[string]interface{}, error) {
      url := fmt.Sprintf("https://api.pictory.ai/pictoryapis/v1/jobs/%s", jobID)
      startTime := time.Now()

      for time.Since(startTime) < maxWait {
          req, _ := http.NewRequest("GET", url, nil)
          req.Header.Set("Authorization", apiKey)
          req.Header.Set("accept", "application/json")

          client := &http.Client{}
          resp, err := client.Do(req)
          if err != nil {
              return nil, err
          }

          body, _ := io.ReadAll(resp.Body)
          resp.Body.Close()

          var data map[string]interface{}
          json.Unmarshal(body, &data)

          success, _ := data["success"].(bool)
          if !success {
              fmt.Println("Job failed")
              return data, nil
          }

          jobData, _ := data["data"].(map[string]interface{})
          status, _ := jobData["status"].(string)

          if status == "in-progress" {
              fmt.Println("Image generation in progress...")
              time.Sleep(pollInterval)
              continue
          }

          if status == "completed" {
              fmt.Println("Image generated successfully!")
              if url, ok := jobData["url"].(string); ok {
                  fmt.Printf("Image URL: %s\n", url)
              }
              return data, nil
          }

          if status == "failed" {
              if msg, ok := jobData["error_message"].(string); ok {
                  fmt.Printf("Image generation failed: %s\n", msg)
              }
              return data, nil
          }

          fmt.Printf("Unexpected status: %s\n", status)
          return data, nil
      }

      return nil, fmt.Errorf("timeout waiting for image generation")
  }

  func main() {
      result, err := pollImageJob(
          "YOUR_API_KEY",
          "4d82d040-4394-4371-867d-72ae1dd62b6d",
          5*time.Minute,
          15*time.Second,
      )
      if err != nil {
          fmt.Println("Error:", err)
          return
      }

      if success, ok := result["success"].(bool); ok && success {
          data := result["data"].(map[string]interface{})
          if imageURL, ok := data["url"].(string); ok {
              fmt.Printf("\nImage: %s\n", imageURL)
          }
      }
  }
  ```
</CodeGroup>

***

## Polling Best Practices

<Warning>
  Use a polling interval of **10–30 seconds** when checking job status. Polling too frequently may result in rate limiting.
</Warning>

1. **Use webhooks when possible.** Configure a `webhook` URL in the original generate image request to receive automatic notification when the job completes, rather than polling.

2. **Implement timeouts.** Set a reasonable maximum wait time. Image generation typically completes within a few minutes.

3. **Handle failures gracefully.** Inspect `error_code` and `error_message` in failed responses to determine the cause and whether the request can be retried.
