curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/virality/generate \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"platforms": [
"instagram",
"linkedin"
],
"social_url": "https://x.com/yourhandle"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/generate"
payload = {
"platforms": ["instagram", "linkedin"],
"social_url": "https://x.com/yourhandle"
}
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({platforms: ['instagram', 'linkedin'], social_url: 'https://x.com/yourhandle'})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/generate', 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/generate",
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([
'platforms' => [
'instagram',
'linkedin'
],
'social_url' => 'https://x.com/yourhandle'
]),
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/generate"
payload := strings.NewReader("{\n \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\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/generate")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/generate")
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 \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\n}"
response = http.request(request)
puts response.read_body{
"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 content plan
Generates the full content plan: a set of posts for each platform you approve, written from the app’s accepted strategy.
Submit answers and accept a strategy first. This endpoint fails with a 409 unless the app has a strategy, and while another generation is already running for the app.
This request costs 10 credits and fails with a 402 when the workspace is out of quota. It runs the whole generation inline, one language model call per platform plus the first platform’s images, so it can take several minutes with 3 platforms. Use a long client timeout. The remaining images generate in the background, so poll Get social content state to pick up the image_url values that land after the response.
Generating a plan replaces any plan the app already has, including its generated images.
This endpoint shares a limit of 15 requests per minute with the other social content endpoints.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/virality/generate \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"platforms": [
"instagram",
"linkedin"
],
"social_url": "https://x.com/yourhandle"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/generate"
payload = {
"platforms": ["instagram", "linkedin"],
"social_url": "https://x.com/yourhandle"
}
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({platforms: ['instagram', 'linkedin'], social_url: 'https://x.com/yourhandle'})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/generate', 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/generate",
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([
'platforms' => [
'instagram',
'linkedin'
],
'social_url' => 'https://x.com/yourhandle'
]),
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/generate"
payload := strings.NewReader("{\n \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\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/generate")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/generate")
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 \"platforms\": [\n \"instagram\",\n \"linkedin\"\n ],\n \"social_url\": \"https://x.com/yourhandle\"\n}"
response = http.request(request)
puts response.read_body{
"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 app.
Body
Platforms to generate content for, 1 to 3 of x, instagram, tiktok, linkedin, reddit, facebook. The order is preserved in the response. Unsupported values are ignored, and a request where none are supported fails with a 400.
1 - 3 elements["instagram", "linkedin"]
HTTPS URL of your social profile, used to match the writing voice of the generated content. Omit it to reuse the voice resolved when you submitted answers.
500"https://x.com/yourhandle"
Response
Successful Response
The app's social content plan after the change.
The app's content plan, or null if it has none.
Show child attributes
Show child attributes
Was this page helpful?