curl --request POST \
--url https://brew.new/api/v1/content/gif \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"from": "prompt",
"prompt": "<string>",
"fps": 12,
"loop": true
}
'import requests
url = "https://brew.new/api/v1/content/gif"
payload = {
"from": "prompt",
"prompt": "<string>",
"fps": 12,
"loop": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({from: 'prompt', prompt: '<string>', fps: 12, loop: true})
};
fetch('https://brew.new/api/v1/content/gif', 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://brew.new/api/v1/content/gif",
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([
'from' => 'prompt',
'prompt' => '<string>',
'fps' => 12,
'loop' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://brew.new/api/v1/content/gif"
payload := strings.NewReader("{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://brew.new/api/v1/content/gif")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/content/gif")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}"
response = http.request(request)
puts response.read_body{
"gifUrl": "<string>",
"videoUrl": "<string>",
"generatedImageUrl": "<string>",
"altText": "<string>",
"duration": 123,
"fps": 123,
"aspectRatio": "<string>",
"width": 123,
"height": 123,
"loop": true
}Generate a GIF
Produces a looping animated GIF (5-second source clip), routed by the from discriminator: prompt generates an on-brand still then animates it, image animates a source image (both via the AI gif workflow), and video converts a source MP4. For prompt and image sources, aspect ratio is one of 16:9, 9:16, 1:1 (default 16:9), and the GIF has that shape: a source image of another shape is centre-cropped when that keeps at least 75% of it, otherwise padded in its own edge colour, never stretched. imageUrl takes any public PNG, JPEG, WebP, GIF (first frame), AVIF or TIFF up to 50 MB and 268 megapixels, of any size or shape; SVG, HEIC and BMP return 422 CONTENT_OPERATION_FAILED. For video, aspectRatio is not accepted; use width and fps for conversion. Returns CDN-hosted gifUrl (plus videoUrl, width/height and motion metadata for the AI sources). Credit-metered (fixed cost: prompt 20, image 10, video 10).
curl --request POST \
--url https://brew.new/api/v1/content/gif \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"from": "prompt",
"prompt": "<string>",
"fps": 12,
"loop": true
}
'import requests
url = "https://brew.new/api/v1/content/gif"
payload = {
"from": "prompt",
"prompt": "<string>",
"fps": 12,
"loop": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({from: 'prompt', prompt: '<string>', fps: 12, loop: true})
};
fetch('https://brew.new/api/v1/content/gif', 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://brew.new/api/v1/content/gif",
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([
'from' => 'prompt',
'prompt' => '<string>',
'fps' => 12,
'loop' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://brew.new/api/v1/content/gif"
payload := strings.NewReader("{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://brew.new/api/v1/content/gif")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/content/gif")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"from\": \"prompt\",\n \"prompt\": \"<string>\",\n \"fps\": 12,\n \"loop\": true\n}"
response = http.request(request)
puts response.read_body{
"gifUrl": "<string>",
"videoUrl": "<string>",
"generatedImageUrl": "<string>",
"altText": "<string>",
"duration": 123,
"fps": 123,
"aspectRatio": "<string>",
"width": 123,
"height": 123,
"loop": true
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
1 - 100The brand this request acts on. REQUIRED for organization-scoped credentials (otherwise 400 BRAND_ID_REQUIRED — there is no default brand); list ids with GET /v1/brands. Brand-scoped credentials may omit it, and sending a different brand returns 403 BRAND_SCOPE_MISMATCH. A brand outside your organization returns 404 BRAND_NOT_FOUND.
1 - 64Body
A from discriminator: { from:"prompt", prompt, … }, { from:"image", imageUrl, … }, or { from:"video", videoUrl, … }.
Was this page helpful?