curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"request": "Make it shorter and drop the emoji."
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine"
payload = { "request": "Make it shorter and drop the emoji." }
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({request: 'Make it shorter and drop the emoji.'})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine', 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}/refine",
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([
'request' => 'Make it shorter and drop the emoji.'
]),
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}/refine"
payload := strings.NewReader("{\n \"request\": \"Make it shorter and drop the emoji.\"\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}/refine")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"request\": \"Make it shorter and drop the emoji.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine")
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 \"request\": \"Make it shorter and drop the emoji.\"\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>"
}
]
}Refine a post
Rewrites a single post in the content plan according to your request, and returns the whole updated plan.
Take post_id from a post in the plan. Only that post changes; every other post is returned unchanged. To replace a post’s text yourself instead of having it rewritten, use Update post content.
This request costs 1 credit and fails with a 402 when the workspace is out of quota. It calls a language model, so expect it to take a few seconds.
content first, because your edit is the version that survived. A 409 here means something different: repeated write conflicts on the plan that did not settle.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/posts/{post_id}/refine \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"request": "Make it shorter and drop the emoji."
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine"
payload = { "request": "Make it shorter and drop the emoji." }
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({request: 'Make it shorter and drop the emoji.'})
};
fetch('https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine', 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}/refine",
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([
'request' => 'Make it shorter and drop the emoji.'
]),
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}/refine"
payload := strings.NewReader("{\n \"request\": \"Make it shorter and drop the emoji.\"\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}/refine")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"request\": \"Make it shorter and drop the emoji.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/virality/posts/{post_id}/refine")
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 \"request\": \"Make it shorter and drop the emoji.\"\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 post, as returned in the content plan. Must be a UUID.
ID of the app.
Body
What to change about the post, in your own words. Can't be empty.
5000"Make it shorter and drop the emoji."
Response
The content plan, with this post rewritten.
The app's content plan, or null if it has none.
Show child attributes
Show child attributes
Was this page helpful?