Skip to main content
GET
/
pictoryapis
/
v1
/
jobs
/
{jobid}
Get Transcription Job by ID
curl --request GET \
  --url https://api.pictory.ai/pictoryapis/v1/jobs/{jobid} \
  --header 'Authorization: <authorization>'
import requests

url = "https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}"

headers = {"Authorization": "<authorization>"}

response = requests.get(url, headers=headers)

print(response.text)
const options = {method: 'GET', headers: {Authorization: '<authorization>'}};

fetch('https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("Authorization", "<authorization>")

res, _ := http.DefaultClient.Do(req)

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

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}")
.header("Authorization", "<authorization>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'

response = http.request(request)
puts response.read_body
{
    "job_id": "cbbc5305-3c1c-46f0-bdde-468e5ecd763f",
    "success": true,
    "data": {
        "status": "in-progress"
    }
}
{
    "success": true,
    "data": {
        "transcript": [
            {
                "uid": "1c01b891-9cfe-452d-8eb9-d1c82f58b44f",
                "speakerId": 1,
                "words": [
                    {
                        "uid": "21247197-328d-4fa7-9e97-b8f661093438",
                        "word": "",
                        "start_time": 0,
                        "end_time": 0.64,
                        "sentence_index": 0,
                        "is_pause": true,
                        "pause_size": "small",
                        "state": "active",
                        "speakerId": 1
                    },
                    {
                        "uid": "031b6091-08c5-436d-ad92-7da64ebbb9c5",
                        "word": "Click",
                        "start_time": 0.64,
                        "end_time": 0.96,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "6fdf6f9e-8b50-4e32-b09b-9d59a8e4d18c",
                        "word": "the",
                        "start_time": 0.96,
                        "end_time": 1.12,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "bfad854f-9a5e-4dd3-b6cf-afba0f8a0c9e",
                        "word": "play",
                        "start_time": 1.12,
                        "end_time": 1.36,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "1e56a014-74f0-4753-bfd5-1a6c6f91d40b",
                        "word": "button",
                        "start_time": 1.36,
                        "end_time": 1.68,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "c8ec17f0-d3cc-4445-9b5d-83de96cc3d28",
                        "word": "to",
                        "start_time": 1.68,
                        "end_time": 1.92,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "b6d56fc4-32e1-4121-9254-09db58f4861b",
                        "word": "watch",
                        "start_time": 1.92,
                        "end_time": 2.159,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "4f55e95c-e337-422c-9df0-753dbda7071e",
                        "word": "the",
                        "start_time": 2.159,
                        "end_time": 2.399,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "804a4882-ac3f-4972-814b-69c29b0eaab6",
                        "word": "tutorial.",
                        "start_time": 2.399,
                        "end_time": 2.899,
                        "speakerId": 1,
                        "sentence_index": 0
                    }
                ]
            },
            {
                "uid": "bdd8ec04-abeb-4c23-8187-b8a16239b4e3",
                "speakerId": 1,
                "words": [
                    {
                        "uid": "eaf3f3f9-a90d-42e2-9e47-c75719b58480",
                        "word": "It's",
                        "start_time": 5.04,
                        "end_time": 5.359,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "3f859d6e-39d2-4dfc-94d6-0dc99711e988",
                        "word": "Jimmy",
                        "start_time": 5.359,
                        "end_time": 5.68,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "7eae2d17-f3ff-4f09-aa7f-71969c6f0bc4",
                        "word": "from",
                        "start_time": 5.68,
                        "end_time": 5.92,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "b0dbd4b8-2aaa-4a87-9cc9-11385f2199f6",
                        "word": "Victory,",
                        "start_time": 5.92,
                        "end_time": 6.399,
                        "speakerId": 1,
                        "sentence_index": 2
                    }
                ]
            }
        ],
        "url": "https://pictory-api-prod.s3.us-east-2.amazonaws.com/2sc7gb6gnnobemlp4jf6u3fdh8/e778154d-56c5-4e00-a2ec-0c06fced116a.mp4",
        "mediaInfo": {
            "duration": 451.16,
            "width": 1920,
            "aspect_ratio": "sixteen-nine",
            "aspect_ratio_value": 1.7777777777777777,
            "height": 1080
        },
        "txt": "Click the play button to watch the tutorial. Hey. It's Jimmy from Victory, and this is a demo of the AI video editor tool...",
        "srt": "1\n00:00:00,640 --> 00:00:02,899\nClick the play button to watch the tutorial.\n\n2\n00:00:04,639 --> 00:00:06,879\nHey. It's Jimmy from Victory, and this is\n\n3\n00:00:06,879 --> 00:00:09,939\na demo of the AI video editor tool.\n...",
        "vtt": "WEBVTT\n\n1\n00:00:00.640 --> 00:00:02.899\n- Click the play button to watch the tutorial.\n\n2\n00:00:04.639 --> 00:00:06.879\n- Hey. It's Jimmy from Victory, and this is\n...",
        "language": "en-US"
    },
    "job_id": "bb94a94d-32b2-46d0-a541-7021d648f884"
}
{
    "message": "Unauthorized"
}
{
    "id": "cbbc5305-3c1c-46f0-bdde-468e5ecd763f",
    "success": false,
    "data": {
        "error_code": "5000",
        "error_message": "JOB_NOT_FOUND"
    }
}

Overview

This endpoint retrieves the current status and results of a transcription job using its unique job ID. While processing is in progress, it returns the current job status. Once the job completes, it returns the full transcript data including word-level timing, speaker identification, and subtitle formats (SRT, VTT).
A valid API key is required to use this endpoint. Obtain your API key from the API Access page in your Pictory dashboard.

API Endpoint

GET https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}

Request Parameters

Path Parameters

jobid
uuid
required
The unique identifier (UUID) of the transcription job. This value is the jobId returned by the Video Transcription endpoint.Example: "cbbc5305-3c1c-46f0-bdde-468e5ecd763f"

Headers

Authorization
string
required
API key for authentication (starts with pictai_)
Authorization: YOUR_API_KEY

Response

In-Progress Response

Returned while the transcription is still being processed:
job_id
string
The unique identifier of the transcription job
success
boolean
true while the job is processing
data
object
status
string
"in-progress": transcription is still being processed

Completed Response

Returned when the transcription has finished successfully. The response contains the full transcript data:
success
boolean
true when the job has completed successfully
job_id
string
The unique identifier of the transcription job
data
object
Contains the complete transcription results.

Response Examples

{
    "job_id": "cbbc5305-3c1c-46f0-bdde-468e5ecd763f",
    "success": true,
    "data": {
        "status": "in-progress"
    }
}
{
    "success": true,
    "data": {
        "transcript": [
            {
                "uid": "1c01b891-9cfe-452d-8eb9-d1c82f58b44f",
                "speakerId": 1,
                "words": [
                    {
                        "uid": "21247197-328d-4fa7-9e97-b8f661093438",
                        "word": "",
                        "start_time": 0,
                        "end_time": 0.64,
                        "sentence_index": 0,
                        "is_pause": true,
                        "pause_size": "small",
                        "state": "active",
                        "speakerId": 1
                    },
                    {
                        "uid": "031b6091-08c5-436d-ad92-7da64ebbb9c5",
                        "word": "Click",
                        "start_time": 0.64,
                        "end_time": 0.96,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "6fdf6f9e-8b50-4e32-b09b-9d59a8e4d18c",
                        "word": "the",
                        "start_time": 0.96,
                        "end_time": 1.12,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "bfad854f-9a5e-4dd3-b6cf-afba0f8a0c9e",
                        "word": "play",
                        "start_time": 1.12,
                        "end_time": 1.36,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "1e56a014-74f0-4753-bfd5-1a6c6f91d40b",
                        "word": "button",
                        "start_time": 1.36,
                        "end_time": 1.68,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "c8ec17f0-d3cc-4445-9b5d-83de96cc3d28",
                        "word": "to",
                        "start_time": 1.68,
                        "end_time": 1.92,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "b6d56fc4-32e1-4121-9254-09db58f4861b",
                        "word": "watch",
                        "start_time": 1.92,
                        "end_time": 2.159,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "4f55e95c-e337-422c-9df0-753dbda7071e",
                        "word": "the",
                        "start_time": 2.159,
                        "end_time": 2.399,
                        "speakerId": 1,
                        "sentence_index": 0
                    },
                    {
                        "uid": "804a4882-ac3f-4972-814b-69c29b0eaab6",
                        "word": "tutorial.",
                        "start_time": 2.399,
                        "end_time": 2.899,
                        "speakerId": 1,
                        "sentence_index": 0
                    }
                ]
            },
            {
                "uid": "bdd8ec04-abeb-4c23-8187-b8a16239b4e3",
                "speakerId": 1,
                "words": [
                    {
                        "uid": "eaf3f3f9-a90d-42e2-9e47-c75719b58480",
                        "word": "It's",
                        "start_time": 5.04,
                        "end_time": 5.359,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "3f859d6e-39d2-4dfc-94d6-0dc99711e988",
                        "word": "Jimmy",
                        "start_time": 5.359,
                        "end_time": 5.68,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "7eae2d17-f3ff-4f09-aa7f-71969c6f0bc4",
                        "word": "from",
                        "start_time": 5.68,
                        "end_time": 5.92,
                        "speakerId": 1,
                        "sentence_index": 2
                    },
                    {
                        "uid": "b0dbd4b8-2aaa-4a87-9cc9-11385f2199f6",
                        "word": "Victory,",
                        "start_time": 5.92,
                        "end_time": 6.399,
                        "speakerId": 1,
                        "sentence_index": 2
                    }
                ]
            }
        ],
        "url": "https://pictory-api-prod.s3.us-east-2.amazonaws.com/2sc7gb6gnnobemlp4jf6u3fdh8/e778154d-56c5-4e00-a2ec-0c06fced116a.mp4",
        "mediaInfo": {
            "duration": 451.16,
            "width": 1920,
            "aspect_ratio": "sixteen-nine",
            "aspect_ratio_value": 1.7777777777777777,
            "height": 1080
        },
        "txt": "Click the play button to watch the tutorial. Hey. It's Jimmy from Victory, and this is a demo of the AI video editor tool...",
        "srt": "1\n00:00:00,640 --> 00:00:02,899\nClick the play button to watch the tutorial.\n\n2\n00:00:04,639 --> 00:00:06,879\nHey. It's Jimmy from Victory, and this is\n\n3\n00:00:06,879 --> 00:00:09,939\na demo of the AI video editor tool.\n...",
        "vtt": "WEBVTT\n\n1\n00:00:00.640 --> 00:00:02.899\n- Click the play button to watch the tutorial.\n\n2\n00:00:04.639 --> 00:00:06.879\n- Hey. It's Jimmy from Victory, and this is\n...",
        "language": "en-US"
    },
    "job_id": "bb94a94d-32b2-46d0-a541-7021d648f884"
}
{
    "message": "Unauthorized"
}
{
    "id": "cbbc5305-3c1c-46f0-bdde-468e5ecd763f",
    "success": false,
    "data": {
        "error_code": "5000",
        "error_message": "JOB_NOT_FOUND"
    }
}

Code Examples

Replace YOUR_API_KEY with your actual API key and use the jobId returned from the Video Transcription endpoint.
curl --request GET \
  --url 'https://api.pictory.ai/pictoryapis/v1/jobs/cbbc5305-3c1c-46f0-bdde-468e5ecd763f' \
  --header 'Authorization: YOUR_API_KEY' \
  --header 'accept: application/json' | python -m json.tool
import requests
import time

def poll_transcription_job(api_key, job_id, max_wait=600, poll_interval=15):
    """
    Poll for transcription job completion.

    Args:
        api_key: Your Pictory API key
        job_id: The transcription job ID
        max_wait: Maximum wait time in seconds (default 10 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"):
            print("Job failed")
            return data

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

        if status == "in-progress":
            print(f"Transcription in progress... (elapsed: {int(time.time() - start_time)}s)")
            time.sleep(poll_interval)
            continue

        # Job completed - transcript data is available
        transcript_data = data.get("data", {})
        print(f"Transcription complete!")
        print(f"Language: {transcript_data.get('language')}")
        print(f"Duration: {transcript_data.get('mediaInfo', {}).get('duration')}s")
        print(f"Segments: {len(transcript_data.get('transcript', []))}")
        return data

    print("Timeout waiting for transcription")
    return None

# Usage
result = poll_transcription_job("YOUR_API_KEY", "cbbc5305-3c1c-46f0-bdde-468e5ecd763f")

if result and result.get("success"):
    data = result["data"]
    # Access the plain text transcript
    print(f"\nTranscript:\n{data.get('txt', '')[:500]}...")

    # Access SRT subtitles
    srt = data.get("srt", "")
    print(f"\nSRT preview:\n{srt[:300]}...")
const jobId = 'cbbc5305-3c1c-46f0-bdde-468e5ecd763f';

async function pollTranscriptionJob(apiKey, jobId, maxWait = 600000, 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');
      return data;
    }

    const status = data.data?.status;

    if (status === 'in-progress') {
      console.log(`Transcription in progress... (${Math.round((Date.now() - startTime) / 1000)}s)`);
      await new Promise(resolve => setTimeout(resolve, pollInterval));
      continue;
    }

    // Job completed
    console.log('Transcription complete!');
    console.log(`Language: ${data.data.language}`);
    console.log(`Duration: ${data.data.mediaInfo?.duration}s`);
    console.log(`Segments: ${data.data.transcript?.length}`);
    return data;
  }

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

// Usage
const result = await pollTranscriptionJob('YOUR_API_KEY', jobId);

if (result?.success) {
  console.log(`\nTranscript: ${result.data.txt?.substring(0, 500)}...`);
}
<?php
function pollTranscriptionJob($apiKey, $jobId, $maxWait = 600, $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\n";
            return $data;
        }

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

        if ($status === 'in-progress') {
            $elapsed = time() - $startTime;
            echo "Transcription in progress... ({$elapsed}s)\n";
            sleep($pollInterval);
            continue;
        }

        // Job completed
        echo "Transcription complete!\n";
        echo "Language: " . ($data['data']['language'] ?? 'unknown') . "\n";
        echo "Duration: " . ($data['data']['mediaInfo']['duration'] ?? 0) . "s\n";
        echo "Segments: " . count($data['data']['transcript'] ?? []) . "\n";
        return $data;
    }

    echo "Timeout waiting for transcription\n";
    return null;
}

// Usage
$result = pollTranscriptionJob('YOUR_API_KEY', 'cbbc5305-3c1c-46f0-bdde-468e5ecd763f');

if ($result && $result['success']) {
    echo "\nTranscript: " . substr($result['data']['txt'] ?? '', 0, 500) . "...\n";
}
?>
package main

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

func pollTranscriptionJob(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" {
            elapsed := int(time.Since(startTime).Seconds())
            fmt.Printf("Transcription in progress... (%ds)\n", elapsed)
            time.Sleep(pollInterval)
            continue
        }

        // Job completed
        fmt.Println("Transcription complete!")
        return data, nil
    }

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

func main() {
    result, err := pollTranscriptionJob(
        "YOUR_API_KEY",
        "cbbc5305-3c1c-46f0-bdde-468e5ecd763f",
        10*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 txt, ok := data["txt"].(string); ok {
            if len(txt) > 500 {
                txt = txt[:500] + "..."
            }
            fmt.Printf("\nTranscript: %s\n", txt)
        }
    }
}

Understanding the Transcript Response

The completed transcription response includes several output formats:
FieldDescription
transcriptStructured array of segments with word-level timing, speaker IDs, and pause markers. Suitable for building custom subtitle renderers or transcript editors.
txtFull transcript as plain text. Suitable for search indexing, summarization, or display.
srtTranscript in SRT subtitle format. Can be saved directly as a .srt file for video players.
vttTranscript in WebVTT format. Can be saved as a .vtt file for web-based video players.
mediaInfoSource media metadata including duration, dimensions, and aspect ratio.

Pause Markers

The transcript array includes pause markers alongside spoken words. These entries are identified by the following characteristics:
  • is_pause is set to true
  • The word field contains an empty string
  • pause_size indicates the duration category (e.g., "small")
Pause markers are useful for understanding speech pacing and can be leveraged when building transcript-based editing workflows.

Polling Best Practices

Use a polling interval of 10–30 seconds when checking job status. Polling too frequently may result in rate limiting.
  1. Use webhooks when possible. Configure a webhook URL in the transcription request to receive automatic notification when the job completes, rather than polling.
  2. Implement timeouts. Set a maximum wait time based on the expected file duration. Longer files require more processing time.
  3. Handle all states. Verify both the in-progress status and the presence of transcript data in the response to determine completion.
  4. Cache results. Once a transcription job completes, store the results locally. Completed job data may be cleaned after a retention period.