---
title: "Sync analysis"
method: POST
path: "/analyze"
---

# Sync analysis

`POST /analyze`

This method analyzes your videos and returns the results directly in the response. It supports general analysis (prompt-based text generation).

<Accordion title="Input requirements">
- Minimum duration: 4 seconds
- Maximum duration: 1 hour
- Formats: [FFmpeg supported formats](https://ffmpeg.org/ffmpeg-formats.html)
- Resolution: 360x360 to 5184x2160 pixels
- Aspect ratio: Between 1:1 and 1:2.4, or between 2.4:1 and 1:1.
</Accordion>

**When to use this method**:
- Analyze videos up to 1 hour
- Retrieve immediate results without polling for task completion
- Stream text fragments in real time for immediate processing and feedback

**Do not use this method for**:
- Videos longer than 1 hour. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.
- Video segmentation with custom segment definitions. Use the [`POST`](/v1.3/api-reference/analyze-videos/create-async-analysis-task) method of the `/analyze/tasks` endpoint instead.

On the Free plan, you have a total of 600 minutes (10 hours) shared across indexing, analysis, and segmentation. For details, see the [Video hours and video count limits](/v1.3/docs/concepts/indexes#video-hours-and-video-count-limits) section.

<Note title="Note">
This endpoint is rate-limited. For details, see the [Rate limits](/v1.3/docs/get-started/rate-limits) page.
</Note>

## Headers

- `x-api-key` string, required

## Request body

- object
  - `model_name` 'pegasus1.5' — The video understanding model to use for analysis. - `pegasus1.5`: General analysis (prompt-based text generation) with video clipping, structured prompts with reference images, and video segmentation (async only). See the [Pegasus](/v1.3/docs/concepts/models/pegasus#context-window) page for token limits. **Default:** `pegasus1.5`
  - `video` union — An object specifying the source of the video content. Include exactly one source.
    - object — Provide the video via a URL.
      - `type` 'url', required — Discriminator value: url
      - `url` string, uri, required — The publicly accessible URL of the video file. Use direct links to raw media files. Video hosting platforms and cloud storage sharing links are not supported.
    - object — Provide the video via a unique identifier of an asset.
      - `type` 'asset_id', required — Discriminator value: asset_id
      - `asset_id` string, required — The unique identifier of an asset from a [direct](/v1.3/api-reference/upload-content/direct-uploads) or [multipart](/v1.3/api-reference/upload-content/multipart-uploads) upload. The asset status must be `ready`. Use the [Retrieve an asset](/v1.3/api-reference/upload-content/direct-uploads/retrieve) method to check the status.
    - object — Provide the video via base64-encoded data.
      - `type` 'base64_string', required — Discriminator value: base64_string
      - `base64_string` string, required — The base64-encoded video data. The maximum size is 30MB.
  - `prompt` string — A prompt that guides the model on the desired format or content. Your prompts can be instructive or descriptive, or you can phrase them as questions. This text counts toward the [context window](/v1.3/docs/concepts/models/pegasus#context-window). **Examples**: - Based on this video, I want to generate five keywords for SEO (Search Engine Optimization). - I want to generate a description for my video with the following format: Title of the video, followed by a summary in 2-3 sentences, highlighting the main topic, key events, and concluding remarks.
  - `prompt_v2` AnalyzePromptV2 — A structured prompt with `<@name>` placeholders for referencing images. Not supported when the `analysis_mode` parameter is `time_based_metadata`. Mutually exclusive with the `prompt` parameter.
    - `input_text` string, required — The text of the prompt. Use `<@name>` placeholders to reference images declared in `media_sources` (Example: `"Is there a <@tiger-1> in the video?"`). This text counts toward the [context window](/v1.3/docs/concepts/models/pegasus#context-window).
    - `media_sources` SMEMediaSource[] — Reference images for the `<@name>` placeholders in the prompt. Maximum 4 sources.
      - `name` string, required — A descriptive name for this media source.
      - `media_type` 'image', required — The media type. Only `image` is available.
      - `url` string, uri — A publicly accessible HTTPS URL of the image.
      - `asset_id` string — The unique identifier of an uploaded asset.
      - `base64_string` string — Base64-encoded image data. The maximum size is 30MB.
  - `temperature` number, double — Controls the randomness of the text output. **Default:** 0.2 **Min:** 0 **Max:** 1
  - `stream` boolean — Set this parameter to `true` to enable streaming responses in the <a href="https://github.com/ndjson/ndjson-spec" target="_blank">NDJSON</a> format. **Default:** `true`
  - `response_format` SyncResponseFormat — Specifies the format of the response. When you omit this parameter, the platform returns unstructured text.
    - `type` 'json_schema', required — Set this parameter to "json_schema" to receive structured JSON responses.
    - `json_schema` SyncResponseFormatJsonSchema, required — Contains the JSON schema that defines the response structure. The schema must adhere to the [JSON Schema Draft 2020-12](https://json-schema.org/draft/2020-12) specification. **Supported types** - `array` - `boolean` - `integer` - `null` - `number` - `object` - `string` - `timestamp` **Supported constraints** | Type | Supported keywords | Notes | |------|-------------------|-------| | `integer` | `maximum`, `exclusiveMaximum`, `minimum`, `exclusiveMinimum`. | - `maximum`: Sets the highest allowed value (inclusive).<br/>- `exclusiveMaximum`: Sets the highest allowed value (exclusive).<br/>- `minimum`: Sets the lowest allowed value (inclusive).<br/>- `exclusiveMinimum`: Sets the lowest allowed value (exclusive).<br/>These constraints are supported only for the `integer` type. | | `string` | `pattern`, `format` | - `pattern`: A regular expression that the string must match.<br/>- `format`: Validates predefined formats. It accepts the following values: `uuid`, `date-time`, `date`, and `time`.<br/>See string limitations below. | | `object` | `properties`, `required` | - `properties`: Defines object properties and their schemas.<br/>- `required`: Specifies mandatory properties.<br/>See object limitations below. | | `array` | `items`, `minItems` | `minItems` accepts only `0` or `1`.<br/>See array limitations below. | | `timestamp` | `format` | `format` (required): Sets the output format. Accepted values: `seconds`, `hh:mm:ss`, `hh:mm:ss.fff`.<br/>See the **Timestamp type** section below. | **String limitations** When you use the `string` type: - The platform validates strings using only `pattern` and `format`. Including `minLength` or `maxLength` causes a 422 error: "String length constraints (minLength) are not supported." Remove these keywords from your schema. **Object limitations** When you use the `object` type: - The platform does not support the `additionalProperties` keyword. Including it causes a 422 error. Remove it from your schema. - The platform returns properties in declaration order. - Make the first property required. If the first property is optional, the platform moves the first required property to the beginning. **Array limitations** When you use the `array` type: - The platform does not support `uniqueItems` or `maxItems`. Including either keyword causes a 422 error. Remove them from your schema. **Constant and enumerated values** The `const` and `enum` keywords support the following types: - `boolean` - `null` - `number` - `string` **Schema composition** The platform supports only `anyOf` for [schema composition](https://json-schema.org/understanding-json-schema/reference/combining). **Annotations** The platform accepts but ignores JSON schema annotations like `title`, `$comments`, and `description`. **Subschema references** You can reference subschemas using `$ref` with these requirements: - Define subschemas within `$defs`. - Use valid URIs that point to the internal subschema. For details, see the [JSON Schema documentation on $defs](https://json-schema.org/understanding-json-schema/structuring#defs). **Timestamp type** Declare a property as `{"type": "timestamp", "format": "<format>"}` to control the format of the returned value. The `format` field accepts the following values: | `format` | Example output | Notes | |----------|----------------|-------| | `seconds` | `10.5` | Returns a JSON number in seconds. | | `hh:mm:ss` | `"00:01:23"` | Rounded to the nearest second. Negative values are converted to `"00:00:00"`. | | `hh:mm:ss.fff` | `"00:01:23.500"` | Millisecond precision. | The type of the response depends on the value of the `format` field: `seconds` returns a JSON number, while `hh:mm:ss` and `hh:mm:ss.fff` return a JSON string. *Supported positions* You can declare `timestamp` fields at the top level of your schema or inside objects nested one level within an array: - Top level: `properties.<field_name>` - Inside an array: `properties.<array_field>.items.properties.<field_name>` Declaring `timestamp` outside these positions — deeper nesting, inside `oneOf` / `anyOf` / `allOf`, or inside `$ref` — is not supported and is rejected with HTTP 400. *Validation errors* When `format` is missing or invalid, the platform returns `400 parameter_invalid`: ``` response_format.json_schema.properties.<name>.format: format is required for timestamp type; allowed values: seconds, hh:mm:ss, hh:mm:ss.fff ``` **Reserved property names (`start_time` / `end_time`)** The `start_time` and `end_time` properties in your response schema receive special type handling at any nesting depth (including inside array `items`). These are unrelated to the top-level `start_time` / `end_time` request parameters. The platform returns the value in a format determined by the declared type: *Allowed declarations:* | Declared type | Platform behavior | |---------------|-------------------| | `number` | Passes the value through without conversion. | | `integer` | Rounds the value to the nearest integer. | | `string` (no `format`) | Converts the value to the `hh:mm:ss.fff` format. | | `timestamp` with `format` | See the **Timestamp type** section above for the available formats. | *Rejected declarations (returns `400` error):* - `string` with any `format` keyword (`time`, `date-time`, `email`, `uri`, etc.) - `boolean` - `object` - `array` - `null` All other property names in your schema remain unconstrained by these rules. For other field names, use the `timestamp` type described above. **Response validation** Check the `FinishReason` field to verify your JSON response is complete: - When `FinishReason` is `stop`, the generation completed normally, and the JSON is valid and complete. - When `FinishReason` is `length`, the platform truncates the response at the maximum response length or the context window. This may result in truncated, invalid JSON that fails to parse.
  - `max_tokens` integer — The maximum response length, in tokens.
  - `start_time` number, double — Start of the analysis window, as an absolute timestamp in seconds, based on the internal metadata of the video. Use with `end_time` to analyze only a portion of the video. <Note title="Notes"> - If omitted, defaults to the internal start time of the video. - Most videos start at 0, but some (for example, from cameras or broadcast recordings) may have a non-zero start time. To find the value, run `ffprobe -v error -show_entries format=start_time,duration -of default=noprint_wrappers=1 your_video.mp4`. - Must be less than `end_time` and less than the video duration. The clip (`end_time - start_time`) must be at least `4` seconds. </Note>
  - `end_time` number, double — End of the analysis window, as an absolute timestamp in seconds, based on the internal metadata of the video. Use with `start_time` to analyze only a portion of the video. <Note title="Notes"> - If omitted, defaults to the internal start time of the video plus its duration. - Most videos start at 0, but some (for example, from cameras or broadcast recordings) may have a non-zero start time. To find the value, run `ffprobe -v error -show_entries format=start_time,duration -of default=noprint_wrappers=1 your_video.mp4`. - Must be greater than `start_time` and less than or equal to the video duration. The clip (`end_time - start_time`) must be at least `4` seconds. </Note>

## Response `200`

The specified video has successfully been analyzed.

- union
  - union — When the value of the `stream` parameter is set to `true`, the platform provides a streaming response in the NDJSON format. The stream contains the following types of events: - Stream start - Text generation - Stream end To integrate the response into your application, follow the guidelines below: - Parse each line of the response as a separate JSON object. - Check the `event_type` field to determine how to handle the event. - For `text_generation` events, process the `text` field as it arrives. Depending on your application's requirements, this may involve displaying the text incrementally, storing it for later use, or performing any tasks. - Use the `stream_start` and `stream_end` events to manage the lifecycle of your streaming session.
    - object — Indicates the beginning of the stream.
      - `event_type` 'stream_start', required — This field is always set to `stream_start` for this event.
      - `metadata` StreamStartResponseMetadata — An object containing metadata about the stream.
        - `generation_id` string — A unique identifier for the generation session.
    - object — Contains a fragment of generated text. Note that text fragments may be split at arbitrary points, not necessarily at word or sentence boundaries.
      - `event_type` 'text_generation', required — This field is always set to `text_generation` for this event.
      - `text` string — A fragment of the generated text.
    - object — Indicates the end of the stream.
      - `event_type` 'stream_end', required — This field is always set to `stream_end` for this event.
      - `finish_reason` 'stop' | 'length' — The reason the generation stopped. - `stop`: The generation reached the end of the output text. - `length`: The response reached the maximum response length or the context window. For JSON responses, this may return truncated JSON that fails to parse.
      - `metadata` StreamEndResponseMetadata — An object containing metadata about the stream.
        - `generation_id` string — The same unique identifier provided in the `stream_start` event.
        - `usage` TokenUsage — The number of tokens used in the generation.
          - `output_tokens` integer, required — The number of tokens in the generated text.
          - `input_tokens` integer — The number of tokens the input consumed. Together with `output_tokens`, this value must fit within the [context window](/v1.3/docs/concepts/models/pegasus#context-window).
      - `error` AnalyzeTaskError — A message attached to an analysis response. The platform uses this object in three cases: - **Task failure** — set on `AnalyzeTaskResponse.error` when `status` is `failed`. The `message` field describes the failure. - **Truncation: maximum response length reached** — set on the response `error` when `finish_reason` is `length` because `output_tokens` reached the requested `max_tokens` value. The `message` field advises increasing the `max_tokens` value. - **Truncation: context window reached** — set on the response `error` when `finish_reason` is `length` because the input and response reached the [context window](/v1.3/docs/concepts/models/pegasus#context-window). The `message` field advises reducing the input size or decreasing the `max_tokens` value. For truncation cases, the partial output is in `result.data` (async) or `data` (sync). Check `finish_reason` instead of parsing the message text.
        - `message` string, required — A human-readable message. One of: - **Failure** (async, `status: failed`): describes the failure reason. Example: `"Video duration exceeds maximum allowed duration"`. - **Truncation: maximum response length reached** (`finish_reason: length`, `output_tokens >= max_tokens`): `"output truncated: the generation reached the configured max_tokens. The partial output is returned; raise max_tokens (up to 98304) if you need a longer response."`. - **Truncation: context window reached** (`finish_reason: length`, model stopped before reaching `max_tokens`): `"output truncated: combined input and output tokens reached the model's context limit. The partial output is returned; consider reducing input size (shorter prompt, smaller video clip, fewer media bindings) or lowering max_tokens."`. The exact text is not part of the contract. Do not parse it.
  - NonStreamAnalyzeResponse — When the value of the `stream` parameter is set to `false`, the response is as follows:
    - `id` string — Unique identifier of the response.
    - `data` string — The generated text based on the prompt you provided.
    - `finish_reason` 'stop' | 'length' — The reason the generation stopped. - `stop`: The generation reached the end of the output text. - `length`: The response reached the maximum response length or the context window. For JSON responses, this may return truncated JSON that fails to parse.
    - `usage` TokenUsage — The number of tokens used in the generation.
      - `output_tokens` integer, required — The number of tokens in the generated text.
      - `input_tokens` integer — The number of tokens the input consumed. Together with `output_tokens`, this value must fit within the [context window](/v1.3/docs/concepts/models/pegasus#context-window).
    - `error` AnalyzeTaskError — A message attached to an analysis response. The platform uses this object in three cases: - **Task failure** — set on `AnalyzeTaskResponse.error` when `status` is `failed`. The `message` field describes the failure. - **Truncation: maximum response length reached** — set on the response `error` when `finish_reason` is `length` because `output_tokens` reached the requested `max_tokens` value. The `message` field advises increasing the `max_tokens` value. - **Truncation: context window reached** — set on the response `error` when `finish_reason` is `length` because the input and response reached the [context window](/v1.3/docs/concepts/models/pegasus#context-window). The `message` field advises reducing the input size or decreasing the `max_tokens` value. For truncation cases, the partial output is in `result.data` (async) or `data` (sync). Check `finish_reason` instead of parsing the message text.
      - `message` string, required — A human-readable message. One of: - **Failure** (async, `status: failed`): describes the failure reason. Example: `"Video duration exceeds maximum allowed duration"`. - **Truncation: maximum response length reached** (`finish_reason: length`, `output_tokens >= max_tokens`): `"output truncated: the generation reached the configured max_tokens. The partial output is returned; raise max_tokens (up to 98304) if you need a longer response."`. - **Truncation: context window reached** (`finish_reason: length`, model stopped before reaching `max_tokens`): `"output truncated: combined input and output tokens reached the model's context limit. The partial output is returned; consider reducing input size (shorter prompt, smaller video clip, fewer media bindings) or lowering max_tokens."`. The exact text is not part of the contract. Do not parse it.

## Other responses

- `400` — The request has failed.
- `404` — The specified resource does not exist.
- `429` — If the rate limit is reached, the platform returns an `HTTP 429 - Too many requests` error response. The response body is empty.

---

[API](https://skmtc.net/twelvelabs/apis/twelvelabs-api.md) · [All operations](https://skmtc.net/twelvelabs/apis/twelvelabs-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/twelvelabs/twelvelabs-api/revisions/fd9d80e384a8/schema)
