# LTX-2.5 Pro — Scenepond API

Model ID: `lightricks/ltx-2.5/text-to-video/pro`

Model developer: Lightricks

Purpose: Text to video

Source page: https://open.scenepond.ai/en/models/lightricks%2Fltx-2.5%2Ftext-to-video%2Fpro#api

Reviewed: 2026-10-01

Base URL: `https://scenepond-api-production.up.railway.app/v1`

Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.

## Native task API

`POST /v1/tasks/fal`

### Minimum request

#### cURL

```bash
curl --fail-with-body -X POST "https://scenepond-api-production.up.railway.app/v1/tasks/fal" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "prompt": "A quiet lakeside at sunrise"
}
JSON
```

#### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

payload = json.loads("{\n  \"model\": \"lightricks/ltx-2.5/text-to-video/pro\",\n  \"prompt\": \"A quiet lakeside at sunrise\"\n}")

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/tasks/fal",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    data=json.dumps(payload).encode("utf-8"),
    method="POST",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

#### JavaScript

```javascript
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/tasks/fal", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "prompt": "A quiet lakeside at sunrise"
})
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request parameters

- `model` — **Required**; `string`. Use this exact public model ID.
  - Constraints: `const = "lightricks/ltx-2.5/text-to-video/pro"`

- `camera_motion` — **Optional**; `string`. Requested camera movement preset.
  - Constraints: `enum = ["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"]`

- `duration` — **Optional**; `integer`. Requested video duration in seconds.
  - Default: `8`
  - Constraints: `enum = [6,8,10]`

- `aspect_ratio` — **Optional**; `string`. Requested output width-to-height ratio.
  - Default: `"16:9"`
  - Constraints: `enum = ["16:9","9:16"]`

- `prompt` — **Required**; `string`. Describe the subject, scene, and desired generation.
  - Constraints: `maxLength = 5000`; `minLength = 1`

- `generate_audio` — **Optional**; `boolean`. Whether audio generation is requested.
  - Default: `true`

- `resolution` — **Optional**; `string`. Output resolution. Values are case-sensitive and specific to this model.
  - Default: `"1080p"`
  - Constraints: `enum = ["720p","1080p"]`

- `fps` — **Optional**; `integer`. Requested frames per second.
  - Default: `25`
  - Constraints: `enum = [24,25,50]`

- `seconds` — **Optional**; `integer`. Video duration in seconds. This is an alias for duration.
  - Default: `8`
  - Constraints: `enum = [6,8,10]`

- `size` — **Optional**; `string`. Alias for image_size or resolution. Prefer the exact native value in this table; pixel-size aliases may not match case-sensitive resolution values.

- `parameters` — **Optional**; `object`. Alternative container for the native parameters in this table. Do not repeat a setting with a different value.

- `metadata` — **Optional**; `object`. Alternative container: place native parameters inside metadata.parameters.

### Illustrative responses

Response examples show the structure only. IDs, URLs, and values are placeholders.

#### Submission response

```json
{
  "id": "task_EXAMPLE",
  "task_id": "task_EXAMPLE",
  "status": "queued",
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "created_at": 1700000000
}
```

#### Completed task status

```json
{
  "task_id": "task_EXAMPLE",
  "platform": "fal",
  "status": "SUCCESS",
  "progress": "100%",
  "fail_reason": "",
  "created_at": 1700000000,
  "finished_at": 1700000060
}
```

#### Artifact listing

```json
{
  "task_id": "task_EXAMPLE",
  "artifacts": [
    {
      "key": "video",
      "type": "video",
      "content_url": "https://scenepond-api-production.up.railway.app/v1/tasks/task_EXAMPLE/artifacts/video/content"
    }
  ]
}
```

### Follow-up requests

#### 2. Check task status

Set SCENEPOND_TASK_ID to task_id. Poll every few seconds until SUCCESS or FAILURE. Status includes progress and fail_reason, but no media.

##### cURL

```bash
curl --fail-with-body -X GET "https://scenepond-api-production.up.railway.app/v1/tasks/$SCENEPOND_TASK_ID" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/tasks/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/tasks/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

#### 3. Get the results

After SUCCESS, list artifacts. Use each returned content_url to download the media with authorization; treat signed URLs as private.

##### cURL

```bash
curl --fail-with-body -X GET "https://scenepond-api-production.up.railway.app/v1/tasks/$SCENEPOND_TASK_ID/artifacts" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/tasks/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "/artifacts",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/tasks/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "/artifacts", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request notes

- Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.
- Parameter values are case-sensitive. Missing or null settings use documented defaults when available; valid zero and false values are retained.
- The parameter table uses native names at the JSON top level. The same settings can be placed in parameters or metadata.parameters; unknown nested settings and conflicting duplicate values are rejected.
- Task submission returns a queued task, not the generated media. Poll status, then list artifacts after SUCCESS.
- Do not automatically resubmit a timed-out POST. Preserve the returned task ID and inspect task status before creating another billable task.
- Defaults and limits follow this gateway and the linked provider schema. Settings may change after a provider or gateway update.

## Video API

`POST /v1/videos`

### Minimum request

#### cURL

```bash
curl --fail-with-body -X POST "https://scenepond-api-production.up.railway.app/v1/videos" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "prompt": "A quiet lakeside at sunrise"
}
JSON
```

#### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

payload = json.loads("{\n  \"model\": \"lightricks/ltx-2.5/text-to-video/pro\",\n  \"prompt\": \"A quiet lakeside at sunrise\"\n}")

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/videos",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    data=json.dumps(payload).encode("utf-8"),
    method="POST",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

#### JavaScript

```javascript
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/videos", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "prompt": "A quiet lakeside at sunrise"
})
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request parameters

- `model` — **Required**; `string`. Use this exact public model ID.
  - Constraints: `const = "lightricks/ltx-2.5/text-to-video/pro"`

- `prompt` — **Required**; `string`. Describe the subject, scene, and desired generation.
  - Constraints: `maxLength = 5000`; `minLength = 1`

- `seconds` — **Optional**; `integer`. Video duration in seconds. This is an alias for duration.
  - Default: `8`
  - Constraints: `enum = [6,8,10]`

- `metadata` — **Optional**; `object`. Optional container for model generation settings.

### Fields in metadata

These fields apply when metadata is supplied. A required child does not make its optional parent required.

- `metadata.parameters` — **Optional**; `object`. Only the model settings listed below are accepted.

### Fields in metadata.parameters

These fields apply when metadata.parameters is supplied. A required child does not make its optional parent required.

- `metadata.parameters.camera_motion` — **Optional**; `string`. Requested camera movement preset.
  - Constraints: `enum = ["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"]`

- `metadata.parameters.duration` — **Optional**; `integer`. Requested video duration in seconds.
  - Default: `8`
  - Constraints: `enum = [6,8,10]`

- `metadata.parameters.aspect_ratio` — **Optional**; `string`. Requested output width-to-height ratio.
  - Default: `"16:9"`
  - Constraints: `enum = ["16:9","9:16"]`

- `metadata.parameters.generate_audio` — **Optional**; `boolean`. Whether audio generation is requested.
  - Default: `true`

- `metadata.parameters.resolution` — **Optional**; `string`. Output resolution. Values are case-sensitive and specific to this model.
  - Default: `"1080p"`
  - Constraints: `enum = ["720p","1080p"]`

- `metadata.parameters.fps` — **Optional**; `integer`. Requested frames per second.
  - Default: `25`
  - Constraints: `enum = [24,25,50]`



- `parameters` — **Optional**; `object`. Alternative container for the native parameters in this table. Do not repeat a setting with a different value.

### Illustrative responses

Response examples show the structure only. IDs, URLs, and values are placeholders.

#### Video response

```json
{
  "id": "task_EXAMPLE",
  "object": "video",
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "status": "queued",
  "progress": 0,
  "created_at": 1700000000
}
```

### Follow-up requests

#### Check video status

Set SCENEPOND_TASK_ID to the returned video id. Poll until status is completed or failed.

##### cURL

```bash
curl --fail-with-body -X GET "https://scenepond-api-production.up.railway.app/v1/videos/$SCENEPOND_TASK_ID" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/videos/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/videos/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

#### Download video

After completed, download the media bytes to output.bin. The Content-Type header identifies the media format.

##### cURL

```bash
curl --fail-with-body --output output.bin -X GET "https://scenepond-api-production.up.railway.app/v1/videos/$SCENEPOND_TASK_ID/content" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/videos/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "/content",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    with open("output.bin", "wb") as output:
        output.write(response.read())
print("Saved output.bin")
```

##### JavaScript

```javascript
import { writeFile } from "node:fs/promises";
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/videos/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "/content", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
await writeFile("output.bin", Buffer.from(await response.arrayBuffer()));
console.log("Saved output.bin");
```

### Request notes

- Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.
- Parameter values are case-sensitive. Missing or null settings use documented defaults when available; valid zero and false values are retained.
- Video creation accepts JSON or multipart/form-data. JSON examples are shown here. For multipart, provide one value per field and only one input_reference file.
- For multipart, encode parameters or metadata as JSON strings so booleans and numeric model settings keep their types.
- Use seconds or metadata.parameters.duration. Conflicting durations are rejected. Prefer the exact model resolution value over size aliases.
- Poll the video ID until completed or failed. Download /videos/{id}/content only after completion; it returns media bytes.

## Responses API · background

`POST /v1/responses`

### Minimum request

#### cURL

```bash
curl --fail-with-body -X POST "https://scenepond-api-production.up.railway.app/v1/responses" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "background": true,
  "input": "A quiet lakeside at sunrise"
}
JSON
```

#### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

payload = json.loads("{\n  \"model\": \"lightricks/ltx-2.5/text-to-video/pro\",\n  \"background\": true,\n  \"input\": \"A quiet lakeside at sunrise\"\n}")

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/responses",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    data=json.dumps(payload).encode("utf-8"),
    method="POST",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

#### JavaScript

```javascript
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/responses", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "background": true,
  "input": "A quiet lakeside at sunrise"
})
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request parameters

- `model` — **Required**; `string`. Use this exact public model ID.
  - Constraints: `const = "lightricks/ltx-2.5/text-to-video/pro"`

- `background` — **Required**; `boolean`. Must be true for this video model.
  - Constraints: `const = true`

- `input` — **Required**; `string | array<object>`. A string supplies the generation prompt. Message content arrays may also contain input_text.

### Fields in input

These fields apply when input is supplied. A required child does not make its optional parent required.

- `input[].role` — **Optional**; `string`. Message role for the input content.
  - Constraints: `example = "user"`

- `input[].content` — **Required**; `array<object>`. Generation text and reference image content.

### Fields in input[].content

These fields apply when input[].content is supplied. A required child does not make its optional parent required.

- `input[].content[].type` — **Required**; `string`. Use input_text for text or input_image for a reference image.
  - Constraints: `enum = ["input_text","input_image"]`

- `input[].content[].text` — **Conditional**; `string`. Describe the subject, scene, and desired generation.
  - Required when type is input_text.

- `input[].content[].image_url` — **Conditional**; `string`. Reference image. Supply an accessible HTTP(S) URL or a base64 image data URL.
  - Required when type is input_image.



- `stream` — **Optional**; `boolean`. Streaming is unavailable for this video model.
  - Default: `false`
  - Constraints: `const = false`

- `metadata` — **Optional**; `object`. Optional container for model generation settings.

### Fields in metadata

These fields apply when metadata is supplied. A required child does not make its optional parent required.

- `metadata.parameters` — **Optional**; `object`. Only the model settings listed below are accepted.

### Fields in metadata.parameters

These fields apply when metadata.parameters is supplied. A required child does not make its optional parent required.

- `metadata.parameters.camera_motion` — **Optional**; `string`. Requested camera movement preset.
  - Constraints: `enum = ["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"]`

- `metadata.parameters.duration` — **Optional**; `integer`. Requested video duration in seconds.
  - Default: `8`
  - Constraints: `enum = [6,8,10]`

- `metadata.parameters.aspect_ratio` — **Optional**; `string`. Requested output width-to-height ratio.
  - Default: `"16:9"`
  - Constraints: `enum = ["16:9","9:16"]`

- `metadata.parameters.generate_audio` — **Optional**; `boolean`. Whether audio generation is requested.
  - Default: `true`

- `metadata.parameters.resolution` — **Optional**; `string`. Output resolution. Values are case-sensitive and specific to this model.
  - Default: `"1080p"`
  - Constraints: `enum = ["720p","1080p"]`

- `metadata.parameters.fps` — **Optional**; `integer`. Requested frames per second.
  - Default: `25`
  - Constraints: `enum = [24,25,50]`



### Illustrative responses

Response examples show the structure only. IDs, URLs, and values are placeholders.

#### Background response

```json
{
  "id": "resp_EXAMPLE",
  "object": "response",
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "status": "queued",
  "background": true,
  "output": [],
  "usage": null
}
```

#### Completed response

```json
{
  "id": "resp_EXAMPLE",
  "object": "response",
  "model": "lightricks/ltx-2.5/text-to-video/pro",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "status": "completed",
      "content": [
        {
          "type": "output_text",
          "text": "<video controls src=\"MEDIA_CONTENT_URL\"></video>",
          "annotations": []
        }
      ]
    }
  ]
}
```

### Follow-up requests

#### Retrieve background response

Use the returned response id. Queued responses have no output; completed responses contain the media URL.

##### cURL

```bash
curl --fail-with-body -X GET "https://scenepond-api-production.up.railway.app/v1/responses/$SCENEPOND_RESPONSE_ID" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://scenepond-api-production.up.railway.app/v1/responses/" + quote(os.environ["SCENEPOND_RESPONSE_ID"], safe="") + "",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_RESPONSE_ID) throw new Error("Set SCENEPOND_RESPONSE_ID first");
const response = await fetch("https://scenepond-api-production.up.railway.app/v1/responses/" + encodeURIComponent(process.env.SCENEPOND_RESPONSE_ID) + "", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request notes

- Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.
- This video model supports background Responses only. Omitted or false background and stream:true are rejected; text-model Responses have a different contract.
- Set SCENEPOND_RESPONSE_ID to the returned id and retrieve it until status is completed or failed.
- Completed output contains an output_text block with a video element and a gateway media URL. It is not a native video output object; parse the URL instead of inserting untrusted HTML.
- Responses token usage values for this media adapter are compatibility values. Video generation still uses the configured task price.
- Use metadata.parameters for the generation settings listed here. Text-only options such as tools, reasoning, temperature, and max_output_tokens do not control Fal generation.

## Sources

- [Provider model reference](https://fal.ai/models/fal-ai/ltx-2.5/text-to-video/pro/api)
