curl --request POST \
--url https://api.ttapi.io/grok/generations \
--header 'Content-Type: application/json' \
--header 'TT-API-KEY: <api-key>' \
--data '
{
"prompt": "<string>",
"model": "grok-imagine-video-1.5-fast",
"aspect_ratio": "16:9",
"video_length": "10",
"resolution_name": "720p",
"first_frame": "https://example.com/first_frame.jpg",
"keyframes": [
{
"image": {
"url": "https://example.com/keyframe1.jpg"
},
"timestamp_s": 3
},
{
"image": {
"url": "https://example.com/keyframe2.jpg"
},
"timestamp_s": 6
}
],
"last_frame": "https://example.com/last_frame.jpg",
"hook_url": "https://example.com/callback"
}
'import requests
url = "https://api.ttapi.io/grok/generations"
payload = {
"prompt": "<string>",
"model": "grok-imagine-video-1.5-fast",
"aspect_ratio": "16:9",
"video_length": "10",
"resolution_name": "720p",
"first_frame": "https://example.com/first_frame.jpg",
"keyframes": [
{
"image": { "url": "https://example.com/keyframe1.jpg" },
"timestamp_s": 3
},
{
"image": { "url": "https://example.com/keyframe2.jpg" },
"timestamp_s": 6
}
],
"last_frame": "https://example.com/last_frame.jpg",
"hook_url": "https://example.com/callback"
}
headers = {
"TT-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'TT-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: '<string>',
model: 'grok-imagine-video-1.5-fast',
aspect_ratio: '16:9',
video_length: '10',
resolution_name: '720p',
first_frame: 'https://example.com/first_frame.jpg',
keyframes: [
{image: {url: 'https://example.com/keyframe1.jpg'}, timestamp_s: 3},
{image: {url: 'https://example.com/keyframe2.jpg'}, timestamp_s: 6}
],
last_frame: 'https://example.com/last_frame.jpg',
hook_url: 'https://example.com/callback'
})
};
fetch('https://api.ttapi.io/grok/generations', 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.ttapi.io/grok/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'model' => 'grok-imagine-video-1.5-fast',
'aspect_ratio' => '16:9',
'video_length' => '10',
'resolution_name' => '720p',
'first_frame' => 'https://example.com/first_frame.jpg',
'keyframes' => [
[
'image' => [
'url' => 'https://example.com/keyframe1.jpg'
],
'timestamp_s' => 3
],
[
'image' => [
'url' => 'https://example.com/keyframe2.jpg'
],
'timestamp_s' => 6
]
],
'last_frame' => 'https://example.com/last_frame.jpg',
'hook_url' => 'https://example.com/callback'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"TT-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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ttapi.io/grok/generations"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("TT-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ttapi.io/grok/generations")
.header("TT-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ttapi.io/grok/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["TT-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}"
response = http.request(request)
puts response.read_body{
"status": "SUCCESS",
"message": "success",
"data": {
"jobId": "jobId"
}
}{
"status": "FAILED",
"message": "\"prompt\" cannot be empty.",
"data": {}
}{
"status": "FAILED",
"message": "Wrong TT-API-KEY or email is not activated."
}Keyframe to Video
Keyframe to video - Pin keyframe images at chosen moments inside the video, combinable with first and last frame
curl --request POST \
--url https://api.ttapi.io/grok/generations \
--header 'Content-Type: application/json' \
--header 'TT-API-KEY: <api-key>' \
--data '
{
"prompt": "<string>",
"model": "grok-imagine-video-1.5-fast",
"aspect_ratio": "16:9",
"video_length": "10",
"resolution_name": "720p",
"first_frame": "https://example.com/first_frame.jpg",
"keyframes": [
{
"image": {
"url": "https://example.com/keyframe1.jpg"
},
"timestamp_s": 3
},
{
"image": {
"url": "https://example.com/keyframe2.jpg"
},
"timestamp_s": 6
}
],
"last_frame": "https://example.com/last_frame.jpg",
"hook_url": "https://example.com/callback"
}
'import requests
url = "https://api.ttapi.io/grok/generations"
payload = {
"prompt": "<string>",
"model": "grok-imagine-video-1.5-fast",
"aspect_ratio": "16:9",
"video_length": "10",
"resolution_name": "720p",
"first_frame": "https://example.com/first_frame.jpg",
"keyframes": [
{
"image": { "url": "https://example.com/keyframe1.jpg" },
"timestamp_s": 3
},
{
"image": { "url": "https://example.com/keyframe2.jpg" },
"timestamp_s": 6
}
],
"last_frame": "https://example.com/last_frame.jpg",
"hook_url": "https://example.com/callback"
}
headers = {
"TT-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'TT-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: '<string>',
model: 'grok-imagine-video-1.5-fast',
aspect_ratio: '16:9',
video_length: '10',
resolution_name: '720p',
first_frame: 'https://example.com/first_frame.jpg',
keyframes: [
{image: {url: 'https://example.com/keyframe1.jpg'}, timestamp_s: 3},
{image: {url: 'https://example.com/keyframe2.jpg'}, timestamp_s: 6}
],
last_frame: 'https://example.com/last_frame.jpg',
hook_url: 'https://example.com/callback'
})
};
fetch('https://api.ttapi.io/grok/generations', 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.ttapi.io/grok/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'model' => 'grok-imagine-video-1.5-fast',
'aspect_ratio' => '16:9',
'video_length' => '10',
'resolution_name' => '720p',
'first_frame' => 'https://example.com/first_frame.jpg',
'keyframes' => [
[
'image' => [
'url' => 'https://example.com/keyframe1.jpg'
],
'timestamp_s' => 3
],
[
'image' => [
'url' => 'https://example.com/keyframe2.jpg'
],
'timestamp_s' => 6
]
],
'last_frame' => 'https://example.com/last_frame.jpg',
'hook_url' => 'https://example.com/callback'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"TT-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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ttapi.io/grok/generations"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("TT-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ttapi.io/grok/generations")
.header("TT-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ttapi.io/grok/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["TT-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"model\": \"grok-imagine-video-1.5-fast\",\n \"aspect_ratio\": \"16:9\",\n \"video_length\": \"10\",\n \"resolution_name\": \"720p\",\n \"first_frame\": \"https://example.com/first_frame.jpg\",\n \"keyframes\": [\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe1.jpg\"\n },\n \"timestamp_s\": 3\n },\n {\n \"image\": {\n \"url\": \"https://example.com/keyframe2.jpg\"\n },\n \"timestamp_s\": 6\n }\n ],\n \"last_frame\": \"https://example.com/last_frame.jpg\",\n \"hook_url\": \"https://example.com/callback\"\n}"
response = http.request(request)
puts response.read_body{
"status": "SUCCESS",
"message": "success",
"data": {
"jobId": "jobId"
}
}{
"status": "FAILED",
"message": "\"prompt\" cannot be empty.",
"data": {}
}{
"status": "FAILED",
"message": "Wrong TT-API-KEY or email is not activated."
}keyframes. The model generates transitions between your keyframe anchors. It can be combined with first_frame and last_frame:
- First frame + keyframes: Specify the opening and interior keyframes
- Keyframes + last frame: Specify interior keyframes and the closing frame
- First frame + keyframes + last frame: Full control over the opening, interior keyframes, and closing frame
grok-imagine-video-1.5-fast and grok-imagine-video-1.5.
timestamp_s must be greater than 0 and less than the video duration; keyframes must be at least 1/3 second apart.Authorizations
You can obtain your API key from the TTAPI Dashboard.
Body
Keyframe to video request parameters
Prompt to guide motion and camera work between keyframes. Optional.
Array of keyframes. Each element contains an image URL and a corresponding timestamp in seconds. Maximum 4 keyframes. timestamp_s must be greater than 0 and less than the video duration; keyframes must be at least 1/3 second apart.
4Show child attributes
Show child attributes
Model name.
grok-imagine-video-1.5-fast, grok-imagine-video-1.5 "grok-imagine-video-1.5-fast"
Video aspect ratio
2:3, 3:2, 1:1, 9:16, 16:9 Video duration in seconds. grok-imagine-video-1.5-fast range: 6 to 30 (6s and 10s are standard durations; 7s and 11s are not supported); grok-imagine-video-1.5 range: 1 to 15.
Output resolution. Available options: 480p, 720p.
480p, 720p, 1080p First frame image URL. Used to strictly specify the first frame of the video. Can be combined with keyframes and last_frame.
Last frame image URL. Used to strictly specify the last frame of the video. Can be combined with keyframes and first_frame. When first_frame and last_frame use the same image, it creates a loop effect.
Callback URL address. When the task completes or fails, notifications will be sent to this address. The notification data structure is consistent with the fetch structure [blocked]. If not set, you need to call the fetch endpoint [blocked] to query the result
"https://example.com/callback"