curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"refinement_instruction": "Make the lighting cooler and remove the coffee cup."
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image"
payload = {
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"refinement_instruction": "Make the lighting cooler and remove the coffee cup."
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
image_prompt: 'A freelancer closing a laptop at a tidy desk, warm morning light',
refinement_instruction: 'Make the lighting cooler and remove the coffee cup.'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image', 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.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image",
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([
'image_prompt' => 'A freelancer closing a laptop at a tidy desk, warm morning light',
'refinement_instruction' => 'Make the lighting cooler and remove the coffee cup.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image"
payload := strings.NewReader("{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}"
response = http.request(request)
puts response.read_body{
"image_url": "https://storage.base44.com/virality/3f2504e0.png",
"plan": {
"id": "8c1f9a2e-3b7d-4c5e-9f01-2a3b4c5d6e7f",
"app_id": "6820f3a4e7b91d003c45a1f2",
"strategy": {
"app_summary": "A CRM for freelancers who want to track leads without a spreadsheet.",
"marketing_approach": "Lead with the spreadsheet pain, then show the app solving it.",
"platforms": [
{
"platform": "instagram",
"mode": "series",
"reasoning": "Instagram rewards a consistent series, so these build on each other.",
"posts": [
{
"id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"platform": "instagram",
"angle": "pain_point",
"angle_label": "Pain point",
"post_number": 1,
"total_posts": 5,
"suggested_day": 1,
"rationale": "Opens on the spreadsheet frustration the audience already has.",
"content": "Still tracking leads in a spreadsheet? I built the thing I wanted instead.",
"image_url": "https://storage.base44.com/virality/3f2504e0.png",
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"hashtags": [
"freelance",
"buildinpublic"
],
"post_title": "I built a CRM because spreadsheets kept losing my leads",
"suggested_subreddits": [
"r/freelance",
"r/SideProject"
],
"launch_comment": "Happy to answer questions about how it works.",
"option_label": "Direct and personal",
"best_for_context": "Best if your audience already knows you"
}
]
}
]
},
"created_at": "2026-08-24T09:15:00+00:00",
"updated_at": "2026-08-24T10:02:00+00:00"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Generate a post image
Generates the image for a single post and saves it on the plan.
The post’s own image_prompt wins over the image_prompt you send, so the request body only decides the prompt for a post that has none. To change an image that already exists, send refinement_instruction.
image_url and you send no refinement_instruction, the existing image is returned as-is. Nothing is generated and no credits are charged.Generating an image costs 1 credit and fails with a 402 when the workspace is out of quota. Image generation is budgeted at up to 60 seconds per attempt, so use a client timeout above that.
This endpoint is limited to 12 requests per minute, separately from the other social content endpoints.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"refinement_instruction": "Make the lighting cooler and remove the coffee cup."
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image"
payload = {
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"refinement_instruction": "Make the lighting cooler and remove the coffee cup."
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
image_prompt: 'A freelancer closing a laptop at a tidy desk, warm morning light',
refinement_instruction: 'Make the lighting cooler and remove the coffee cup.'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image', 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.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image",
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([
'image_prompt' => 'A freelancer closing a laptop at a tidy desk, warm morning light',
'refinement_instruction' => 'Make the lighting cooler and remove the coffee cup.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image"
payload := strings.NewReader("{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/generate-image")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"image_prompt\": \"A freelancer closing a laptop at a tidy desk, warm morning light\",\n \"refinement_instruction\": \"Make the lighting cooler and remove the coffee cup.\"\n}"
response = http.request(request)
puts response.read_body{
"image_url": "https://storage.base44.com/virality/3f2504e0.png",
"plan": {
"id": "8c1f9a2e-3b7d-4c5e-9f01-2a3b4c5d6e7f",
"app_id": "6820f3a4e7b91d003c45a1f2",
"strategy": {
"app_summary": "A CRM for freelancers who want to track leads without a spreadsheet.",
"marketing_approach": "Lead with the spreadsheet pain, then show the app solving it.",
"platforms": [
{
"platform": "instagram",
"mode": "series",
"reasoning": "Instagram rewards a consistent series, so these build on each other.",
"posts": [
{
"id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"platform": "instagram",
"angle": "pain_point",
"angle_label": "Pain point",
"post_number": 1,
"total_posts": 5,
"suggested_day": 1,
"rationale": "Opens on the spreadsheet frustration the audience already has.",
"content": "Still tracking leads in a spreadsheet? I built the thing I wanted instead.",
"image_url": "https://storage.base44.com/virality/3f2504e0.png",
"image_prompt": "A freelancer closing a laptop at a tidy desk, warm morning light",
"hashtags": [
"freelance",
"buildinpublic"
],
"post_title": "I built a CRM because spreadsheets kept losing my leads",
"suggested_subreddits": [
"r/freelance",
"r/SideProject"
],
"launch_comment": "Happy to answer questions about how it works.",
"option_label": "Direct and personal",
"best_for_context": "Best if your audience already knows you"
}
]
}
]
},
"created_at": "2026-08-24T09:15:00+00:00",
"updated_at": "2026-08-24T10:02:00+00:00"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Personal API key.
Path Parameters
ID of the post, as returned in the content plan. Must be a UUID.
ID of the app.
Body
Prompt to generate the image from. Used only when the post carries no image_prompt of its own, which is the prompt the plan generated for it. Send the post's own image_prompt back if you want to be sure of what is used.
2000"A freelancer closing a laptop at a tidy desk, warm morning light"
What to change about the existing image. Sending this regenerates the image even when the post already has one. The first 300 characters are used.
500"Make the lighting cooler and remove the coffee cup."
Was this page helpful?