List Compose Formats
curl --request GET \
--url https://app.uselamina.ai/v1/compose/formats \
--header 'x-api-key: <api-key>'import requests
url = "https://app.uselamina.ai/v1/compose/formats"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://app.uselamina.ai/v1/compose/formats', 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://app.uselamina.ai/v1/compose/formats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://app.uselamina.ai/v1/compose/formats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.uselamina.ai/v1/compose/formats")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.uselamina.ai/v1/compose/formats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"formats": [
{
"id": "cinematic_broll",
"label": "Cinematic b-roll",
"description": "Generated image→video hero clips, continuity-chained, narration + captions.",
"available": true,
"costTier": "high",
"estimatedCredits": 296,
"trending": false,
"tags": [
"brand",
"product",
"cinematic"
],
"inputs": [],
"previewUrl": "https://cdn.uselamina.ai/compose/previews/cinematic_broll.mp4",
"thumbnailUrl": "https://cdn.uselamina.ai/compose/previews/cinematic_broll.jpg"
},
{
"id": "animated_slideshow",
"label": "Animated slideshow",
"description": "Generated stills with Ken-Burns motion + fade transitions, narration over the top.",
"available": true,
"costTier": "low",
"estimatedCredits": 35,
"trending": false,
"tags": [
"blog",
"explainer",
"fast"
],
"inputs": [],
"previewUrl": null,
"thumbnailUrl": null
}
],
"capabilities": {
"maxScriptDurationSec": 90,
"aspectRatios": [
"16:9",
"9:16",
"1:1",
"4:5",
"4:3"
],
"defaultAspectRatio": "16:9",
"clipSeconds": {
"min": 3,
"max": 10,
"default": 5
}
}
}
}{
"error": "Invalid API key"
}"Too many requests from this IP, please try again in a minute"Compose
List Compose Formats
List the video formats POST /v1/compose/video can render — animated
slideshow, cinematic b-roll, motion-graphics explainer, and more. Each
format renders differently and internally uses different models; callers
pick a format (never a model) and see its cost.
The response also returns fixed capabilities (max script length,
supported aspect ratios, clip window) so an agent can construct any valid
compose call from a single discovery request. Formats with available: false are on the roadmap and cannot be dispatched yet. Formats may
declare required inputs (e.g. a presenter image) that must be supplied.
GET
/
v1
/
compose
/
formats
List Compose Formats
curl --request GET \
--url https://app.uselamina.ai/v1/compose/formats \
--header 'x-api-key: <api-key>'import requests
url = "https://app.uselamina.ai/v1/compose/formats"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://app.uselamina.ai/v1/compose/formats', 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://app.uselamina.ai/v1/compose/formats",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://app.uselamina.ai/v1/compose/formats"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.uselamina.ai/v1/compose/formats")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.uselamina.ai/v1/compose/formats")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"formats": [
{
"id": "cinematic_broll",
"label": "Cinematic b-roll",
"description": "Generated image→video hero clips, continuity-chained, narration + captions.",
"available": true,
"costTier": "high",
"estimatedCredits": 296,
"trending": false,
"tags": [
"brand",
"product",
"cinematic"
],
"inputs": [],
"previewUrl": "https://cdn.uselamina.ai/compose/previews/cinematic_broll.mp4",
"thumbnailUrl": "https://cdn.uselamina.ai/compose/previews/cinematic_broll.jpg"
},
{
"id": "animated_slideshow",
"label": "Animated slideshow",
"description": "Generated stills with Ken-Burns motion + fade transitions, narration over the top.",
"available": true,
"costTier": "low",
"estimatedCredits": 35,
"trending": false,
"tags": [
"blog",
"explainer",
"fast"
],
"inputs": [],
"previewUrl": null,
"thumbnailUrl": null
}
],
"capabilities": {
"maxScriptDurationSec": 90,
"aspectRatios": [
"16:9",
"9:16",
"1:1",
"4:5",
"4:3"
],
"defaultAspectRatio": "16:9",
"clipSeconds": {
"min": 3,
"max": 10,
"default": 5
}
}
}
}{
"error": "Invalid API key"
}"Too many requests from this IP, please try again in a minute"The menu
POST /v1/compose/video renders from. Each format is a named look — animated slideshow, cinematic b-roll, motion-graphics explainer, and more — that internally uses different models. You pick a format, never a model, and see its cost.
The response also returns fixed capabilities (max script length, aspect ratios, clip window) so you can build any valid compose call from this one request. Formats with available: false are on the roadmap. A format may declare required inputs (e.g. a presenter image) you must supply when you dispatch it.
Each format may include a previewUrl (a short sample render of the template) and thumbnailUrl (a poster) so you can show the user what each format looks like — not just its cost — before they pick one. Both are null until a preview has been generated.