> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.twelvelabs.io/v1.3/docs/guides/analyze-videos-and-images/images/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.twelvelabs.io/_mcp/server. # Analyze images > Analyze images to generate text based on their content. This guide shows how to analyze one or more images with a prompt. Upload your images as assets and reference their identifiers, or pass them inline by URL or base64-encoded data. You can analyze up to twenty images in a single request. On the Free plan, each image you analyze counts as 5 minutes toward a shared limit that also covers indexing. For example, 120 images use the entire 10-hour allowance. For details on how your usage is measured and billed, see the [Pricing](https://www.twelvelabs.io/pricing) page. # Key concepts This section explains the key concepts and terminology used in this guide: * **Asset**: Your uploaded content. Once created, you can reference the same asset across multiple operations without uploading the file again. * **Analysis task**: An asynchronous operation for processing your content and generating text. Contains a status and the resulting text when complete. # Prerequisites * To use the platform, you need an API key: If you don't have an account, [sign up](https://playground.twelvelabs.io/) for a free account. Go to the [API Keys](https://playground.twelvelabs.io/dashboard/api-keys) page. If you need to create a new key, select the **Create API Key** button. Enter a name and set the expiration period. The default is 12 months. Select the **Copy** icon next to your key to copy it to your clipboard. * Depending on the programming language you are using, install the TwelveLabs SDK by entering one of the following commands: **`Python`** ```shell Python pip install --upgrade twelvelabs ``` **`Node.js`** ```shell Node.js yarn add twelvelabs-js@latest # or npm install twelvelabs-js@latest ``` * Your images must meet the following requirements: * **Number of images**: one to twenty per request * **Formats**: JPEG, PNG, WebP, GIF, and BMP * **File size**: ≤ 20 MB per image * **Pixel count**: ≤ 16,777,216 pixels per image (width × height) # Complete example Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values. The example analyzes two images - the first uploaded as an asset, the second passed inline by URL - and references both in the prompt. **`Python`** ```Python Python maxlines=12 import time from twelvelabs import TwelveLabs from twelvelabs.types import AnalyzeImageInput # 1. Initialize the client client = TwelveLabs(api_key="") # 2. Upload an image asset = client.assets.create( method="url", url="" # Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported # Or use method="direct" and file=open("", "rb") to upload a local file ) print(f"Created asset: id={asset.id}") # 3. Check the status of the asset print("Waiting for asset to be ready...") while True: asset = client.assets.retrieve(asset.id) if asset.status == "ready": print("Asset is ready") break if asset.status == "failed": raise RuntimeError(f"Asset processing failed: id={asset.id}") time.sleep(5) # 4. Analyze your images images = [ AnalyzeImageInput(name="product_a", asset_id=asset.id), AnalyzeImageInput(name="product_b", url=""), # Or upload it as an asset like the first image ] task = client.analyze_async.tasks.create( model_name="pegasus1.6", image=images, prompt="Compare <@product_a> with <@product_b> and describe what changed.", # temperature=0.2, # max_tokens=1024, # You can also use `response_format` to request structured JSON responses ) print(f"Task ID: {task.task_id}") # 5. Monitor the status while True: task = client.analyze_async.tasks.retrieve(task.task_id) if task.status == "ready": print("Task completed") break elif task.status == "failed": print("Task failed") break else: print("Task still processing...") time.sleep(5) # 6. Process the results print(f"{task.result.data}") ``` **`Node.js`** ```JavaScript Node.js maxlines=12 import { TwelveLabs } from "twelvelabs-js"; // Uncomment the next line if uploading a local file // import fs from 'fs'; // 1. Initialize the client const client = new TwelveLabs({ apiKey: "" }); // 2. Upload an image const asset = await client.assets.create({ method: "url", url: "", // Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported // Or use method: "direct" and file: fs.createReadStream("") to upload a local file }); console.log(`Created asset: id=${asset.id}`); // 3. Check the status of the asset console.log("Waiting for asset to be ready..."); let readyAsset = await client.assets.retrieve(asset.id); while (readyAsset.status !== "ready" && readyAsset.status !== "failed") { await new Promise((resolve) => setTimeout(resolve, 5000)); readyAsset = await client.assets.retrieve(asset.id); } if (readyAsset.status === "failed") { throw new Error(`Asset processing failed: id=${asset.id}`); } console.log("Asset is ready"); // 4. Analyze your images const { taskId } = await client.analyzeAsync.tasks.create({ modelName: "pegasus1.6", image: [ { name: "product_a", assetId: asset.id }, { name: "product_b", url: "" }, // Or upload it as an asset like the first image ], prompt: "Compare <@product_a> with <@product_b> and describe what changed.", // temperature: 0.2, // maxTokens: 1024, // You can also use `responseFormat` to request structured JSON responses }); console.log(`Task ID: ${taskId}`); // 5. Monitor the status let task = await client.analyzeAsync.tasks.retrieve(taskId); while (task.status !== "ready" && task.status !== "failed") { console.log("Task still processing..."); await new Promise((resolve) => setTimeout(resolve, 5000)); task = await client.analyzeAsync.tasks.retrieve(taskId); } if (task.status === "ready") { console.log("Task completed"); } else { console.log("Task failed"); } // 6. Process the results console.log(`${task.result.data}`); ``` # Code explanation #### Python #### Import the SDK and initialize the client Create a client instance to interact with the TwelveLabs Video Understanding Platform.\ **Function call**: You call the [constructor](/v1.3/sdk-reference/python/the-twelve-labs-class#the-initializer) of the `TwelveLabs` class.\ **Parameters**: * `api_key`: The API key to authenticate your requests to the platform.\ **Return value**: An object of type `TwelveLabs` configured for making API calls. #### Upload an image Upload the first image to create an asset. Image analysis requires the asset to be in the `ready` state before you use it.\ **Function call**: You call the [`assets.create`](/v1.3/sdk-reference/python/upload-files/direct-uploads#create-an-asset) method.\ **Parameters**: * `method`: How to provide the image. Use `url` with a publicly accessible image URL, or `direct` with a local file. #### Check the status of the asset Asset processing is asynchronous. Poll the status of the asset until it is `ready` before you use it. #### Analyze your images Create an analysis task to start processing your images. This operation is asynchronous.\ **Function call**: You call the [`analyze_async.tasks.create`](/v1.3/sdk-reference/python/analyze-videos/async-analysis#create-an-async-analysis-task) method.\ **Parameters**: * `image`: A list of `AnalyzeImageInput` objects, one per image. You can analyze up to twenty images per request. For each image, set: * `name`: The name you use to reference the image in the prompt. Can contain only letters, digits, and underscores. * Exactly one source: `asset_id`, `url`, or `base_64_string`. This example uses the asset identifier from the previous step for the first image and passes the second image inline by URL. * `prompt`: The instructions for the analysis. To refer to a specific image in your prompt, use its name as the `<@name>` placeholder. Reference every image or none of them. If the prompt references none of them, the platform analyzes every image you provided. If it references only some of them, the platform returns a `400` error. * *(Optional)* `temperature`: Controls the randomness of the text output. A higher value generates more creative text, while a lower value produces more deterministic output. * *(Optional)* `max_tokens`: The maximum response length, in tokens. * *(Optional)* `response_format`: Use this parameter to request structured JSON responses. For instructions, examples, and best practices, see the [Structured responses](/v1.3/docs/guides/analyze-videos-and-images/structured-responses) page.\ **Return value**: An object of type `CreateAnalyzeTaskResponse` containing a field named `task_id`, which represents the unique identifier of your analysis task. You can use this identifier to track the status of your task. #### Monitor the status The platform requires some time to process images. Poll the status of the analysis task until processing completes. This example uses a loop to check the status every 5 seconds.\ **Function call**: You repeatedly call the [`analyze_async.tasks.retrieve`](/v1.3/sdk-reference/python/analyze-videos/async-analysis#retrieve-task-status-and-results) method until the task completes.\ **Parameters**: * `task_id`: The unique identifier of your analysis task.\ **Return value**: An object of type `AnalyzeTaskResponse` containing, among other information, the following fields: * `status`: The current status of the task. The possible values are: * `queued`: The task is waiting to be processed. * `pending`: The task is queued and waiting to start. * `processing`: The platform is analyzing your images. * `ready`: Processing is complete. Results are available in the `result` field. * `failed`: The task failed. * `result`: When the status is `ready`, this field contains the generated text and usage information. #### Process the results This example prints the generated text to the standard output. #### Node.js #### Import the SDK and initialize the client Create a client instance to interact with the TwelveLabs Video Understanding Platform.\ **Function call**: You call the [constructor](/v1.3/sdk-reference/node-js/the-twelve-labs-class#the-constructor) of the `TwelveLabs` class.\ **Parameters**: You pass all parameters as properties of a single object. * `apiKey`: The API key to authenticate your requests to the platform.\ **Return value**: An object of type `TwelveLabs` configured for making API calls. #### Upload an image Upload the first image to create an asset. Image analysis requires the asset to be in the `ready` state before you use it.\ **Function call**: You call the [`assets.create`](/v1.3/sdk-reference/node-js/upload-files/direct-uploads#create-an-asset) method.\ **Parameters**: You pass all parameters as properties of a single object. * `method`: How to provide the image. Use `url` with a publicly accessible image URL, or `direct` with a local file. #### Check the status of the asset Asset processing is asynchronous. Poll the status of the asset until it is `ready` before you use it. #### Analyze your images Create an analysis task to start processing your images. This operation is asynchronous.\ **Function call**: You call the [`analyzeAsync.tasks.create`](/v1.3/sdk-reference/node-js/analyze-videos/async-analysis#create-an-async-analysis-task) method.\ **Parameters**: You pass all parameters as properties of a single object. * `image`: A list of objects, one per image. You can analyze up to twenty images per request. For each image, set: * `name`: The name you use to reference the image in the prompt. Can contain only letters, digits, and underscores. * Exactly one source: `assetId`, `url`, or `base64String`. This example uses the asset identifier from the previous step for the first image and passes the second image inline by URL. * `prompt`: The instructions for the analysis. To refer to a specific image in your prompt, use its name as the `<@name>` placeholder. Reference every image or none of them. If the prompt references none of them, the platform analyzes every image you provided. If it references only some of them, the platform returns a `400` error. * *(Optional)* `temperature`: Controls the randomness of the text output. A higher value generates more creative text, while a lower value produces more deterministic output. * *(Optional)* `maxTokens`: The maximum response length, in tokens. * *(Optional)* `responseFormat`: Use this parameter to request structured JSON responses. For instructions, examples, and best practices, see the [Structured responses](/v1.3/docs/guides/analyze-videos-and-images/structured-responses) page.\ **Return value**: An `HttpResponsePromise` that resolves to an object of type `CreateAnalyzeTaskResponse`. This example destructures `taskId` from the response — the unique identifier of your analysis task. You can use this identifier to track the status of your task. #### Monitor the status The platform requires some time to process images. Poll the status of the analysis task until processing completes. This example uses a loop to check the status every 5 seconds.\ **Function call**: You repeatedly call the [`analyzeAsync.tasks.retrieve`](/v1.3/sdk-reference/node-js/analyze-videos/async-analysis#retrieve-task-status-and-results) method until the task completes.\ **Parameters**: * `taskId`: The unique identifier of your analysis task.\ **Return value**: An `HttpResponsePromise` that resolves to an object of type `AnalyzeTaskResponse` containing, among other information, the following fields: * `status`: The current status of the task. The possible values are: * `queued`: The task is waiting to be processed. * `pending`: The task is queued and waiting to start. * `processing`: The platform is analyzing your images. * `ready`: Processing is complete. Results are available in the `result` field. * `failed`: The task failed. * `result`: When the status is `ready`, this field contains the generated text and usage information. #### Process the results This example prints the generated text to the standard output. # Synchronous analysis For immediate results, use the synchronous method instead of creating an analysis task. It supports the same image requirements and returns (or streams) the generated text directly in the response. **Response methods** #### Streaming responses Streaming responses deliver text fragments in real time as they are generated, enabling immediate processing and feedback. This method is the default behavior of the platform and is ideal for applications requiring incremental updates.\ * **Response format**: A stream of JSON objects in NDJSON format, with three event types: * `stream_start`: Marks the beginning of the stream. * `text_generation`: Delivers a fragment of the generated text. * `stream_end`: Signals the end of the stream.\ * **Response handling**: * Iterate over the stream to process text fragments as they arrive.\ * **Advantages**: * Real-time processing of partial results. * Reduced perceived latency. * **Use case**: Live captioning, real-time analysis, or applications needing instant updates. #### Non-streaming responses Non-streaming responses deliver the complete generated text in a single response, simplifying processing when the full result is needed. * **Response format**: A single string containing the full generated text. * **Response handling**: * Access the complete text directly from the response. * **Advantages**: * Simplicity in handling the full result. * Immediate access to the entire text. * **Use case**: Generating reports, descriptions, or any scenario where the whole text is required at once. Copy and paste the code below, replacing the placeholders surrounded by `<>` with your values. #### Streaming responses **`Python`** ```Python Python maxlines=12 from twelvelabs import TwelveLabs from twelvelabs.types import AnalyzeImageInput # 1. Initialize the client client = TwelveLabs(api_key="") # 2. Analyze your images images = [ AnalyzeImageInput(name="product_a", url=""), AnalyzeImageInput(name="product_b", url=""), ] text_stream = client.analyze_stream( model_name="pegasus1.6", image=images, prompt="Compare <@product_a> with <@product_b> and describe what changed.", # temperature=0.2, # max_tokens=1024, # You can also use `response_format` to request structured JSON responses ) # 3. Process the results for text in text_stream: if text.event_type == "text_generation": print(text.text) ``` **`Node.js`** ```JavaScript Node.js maxlines=12 import { TwelveLabs } from "twelvelabs-js"; // 1. Initialize the client const client = new TwelveLabs({ apiKey: "" }); // 2. Analyze your images const textStream = await client.analyzeStream({ modelName: "pegasus1.6", image: [ { name: "product_a", url: "" }, { name: "product_b", url: "" }, ], prompt: "Compare <@product_a> with <@product_b> and describe what changed.", // temperature: 0.2, // maxTokens: 1024, // You can also use `responseFormat` to request structured JSON responses }); // 3. Process the results for await (const text of textStream) { if ("text" in text) { console.log(text.text); } } ``` #### Non-streaming responses **`Python`** ```Python Python maxlines=12 from twelvelabs import TwelveLabs from twelvelabs.types import AnalyzeImageInput # 1. Initialize the client client = TwelveLabs(api_key="") # 2. Analyze your images images = [ AnalyzeImageInput(name="product_a", url=""), AnalyzeImageInput(name="product_b", url=""), ] text = client.analyze( model_name="pegasus1.6", image=images, prompt="Compare <@product_a> with <@product_b> and describe what changed.", # temperature=0.2, # max_tokens=1024, # You can also use `response_format` to request structured JSON responses ) # 3. Process the results print(f"{text.data}") ``` **`Node.js`** ```JavaScript Node.js maxlines=12 import { TwelveLabs } from "twelvelabs-js"; // 1. Initialize the client const client = new TwelveLabs({ apiKey: "" }); // 2. Analyze your images const text = await client.analyze({ modelName: "pegasus1.6", image: [ { name: "product_a", url: "" }, { name: "product_b", url: "" }, ], prompt: "Compare <@product_a> with <@product_b> and describe what changed.", // temperature: 0.2, // maxTokens: 1024, // You can also use `responseFormat` to request structured JSON responses }); // 3. Process the results console.log(`${text.data}`); ``` The `image` parameter and all optional parameters (`model_name`, `temperature`, `max_tokens`, `response_format`, etc.) function the same as in the asynchronous approach above. > Analyze images to generate text based on their content.