curl --request POST \
--url https://api.superx.so/v1/posts/viral-score \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Most founders think they have a traffic problem. They have a positioning problem.",
"has_image": false
}
'import requests
url = "https://api.superx.so/v1/posts/viral-score"
payload = {
"text": "Most founders think they have a traffic problem. They have a positioning problem.",
"has_image": False
}
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({
text: 'Most founders think they have a traffic problem. They have a positioning problem.',
has_image: false
})
};
fetch('https://api.superx.so/v1/posts/viral-score', 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.superx.so/v1/posts/viral-score",
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([
'text' => 'Most founders think they have a traffic problem. They have a positioning problem.',
'has_image' => false
]),
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://api.superx.so/v1/posts/viral-score"
payload := strings.NewReader("{\n \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\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://api.superx.so/v1/posts/viral-score")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.superx.so/v1/posts/viral-score")
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 \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\n}"
response = http.request(request)
puts response.read_body{
"data": {
"score": 71,
"beats_own_normal": 0.7134,
"baseline": {
"kind": "account",
"posts_used": 34,
"account_id": "1178367350552305665"
},
"counters": {
"likes": {
"multiple": 1.38,
"p75": 2.69,
"p90": 6.38,
"breakout_share": 0.173,
"probability": 0.7134,
"confidence": "normal",
"own_median": 42,
"expected": 58
},
"replies": {
"multiple": 1.02,
"p75": 1.83,
"p90": 4.1,
"breakout_share": 0.095,
"probability": 0.58,
"confidence": "normal",
"own_median": 6,
"expected": 6
},
"reposts_and_quotes": {
"multiple": 0.98,
"p75": 1.7,
"p90": 3.49,
"breakout_share": 0.075,
"probability": 0.51,
"confidence": "low",
"own_median": 2,
"expected": 2
},
"views": {
"multiple": 1.02,
"p75": 1.83,
"p90": 4.1,
"breakout_share": 0.095,
"probability": 0.56,
"confidence": "low",
"own_median": 5100,
"expected": 5202
}
},
"helped": [
{
"key": "k_credential_proof",
"label": "A result of your own backs the point",
"detail": "Backs the point with a result more than usual",
"effect": 0.1842
}
],
"hurt": [
{
"key": "cov_is_quote",
"label": "It quotes another post",
"detail": "Quotes another post, unlike your usual post",
"effect": -0.0914
}
],
"warnings": [],
"accuracy": {
"pair_accuracy": 0.6516,
"posts": 9481,
"authors": 214,
"pairs": 4225,
"creators": 207,
"line": "Picks the better of two posts by the same account 65% of the time, cross-validated by creator on 4,225 pairs from 207 creators; no sealed test set yet."
},
"engine": {
"generated": "2026-09-17T19:07:36.538Z",
"question_set": "v1.1"
}
},
"meta": {
"credits_charged": 1,
"account_id": "1178367350552305665"
}
}Score a draft against this account's own posts
Scores ONE draft from 0 to 100 against the account’s OWN recent posts, and says what helped and what hurt in plain English. The counters block gives the multiple to expect on likes, replies, reposts+quotes and views versus that account’s own median post, taken from measured calibration bands rather than modelled.
It compares a draft with the account’s normal post. It is not a
reach prediction, and it knows nothing about follower count. Present
it that way: accuracy.line carries the measured held-out figure to
quote, and it is right about two times in three.
reposts_and_quotes and views come back with confidence: "low":
text says much less about those than about likes and replies.
warnings name the things the score never rewards, whatever else
the draft does: asking for replies as the point of the post,
inviting people to connect, a structure borrowed from other
accounts, and sending readers off the platform. A warning means
rewrite, not work around.
The baseline is the account’s last originals from the past 90 days, leaving out anything posted in the last 3 days because those numbers are still settling.
Fewer than 10 usable posts and baseline.kind comes back population,
which scores the draft against the average training post and returns
expected: null on every counter. Pass baseline: "population" to
ask for that on purpose.
Nothing is posted or scheduled.
Cheap on purpose so drafts can be iterated: most calls charge no
credits, one in ten charges 1, and the first call for an account
charges 1 more while its baseline is built. Each plan has a daily cap
on how many scores it can run. Spends no live-data allowance. Needs a
key with the write scope.
curl --request POST \
--url https://api.superx.so/v1/posts/viral-score \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Most founders think they have a traffic problem. They have a positioning problem.",
"has_image": false
}
'import requests
url = "https://api.superx.so/v1/posts/viral-score"
payload = {
"text": "Most founders think they have a traffic problem. They have a positioning problem.",
"has_image": False
}
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({
text: 'Most founders think they have a traffic problem. They have a positioning problem.',
has_image: false
})
};
fetch('https://api.superx.so/v1/posts/viral-score', 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.superx.so/v1/posts/viral-score",
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([
'text' => 'Most founders think they have a traffic problem. They have a positioning problem.',
'has_image' => false
]),
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://api.superx.so/v1/posts/viral-score"
payload := strings.NewReader("{\n \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\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://api.superx.so/v1/posts/viral-score")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.superx.so/v1/posts/viral-score")
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 \"text\": \"Most founders think they have a traffic problem. They have a positioning problem.\",\n \"has_image\": false\n}"
response = http.request(request)
puts response.read_body{
"data": {
"score": 71,
"beats_own_normal": 0.7134,
"baseline": {
"kind": "account",
"posts_used": 34,
"account_id": "1178367350552305665"
},
"counters": {
"likes": {
"multiple": 1.38,
"p75": 2.69,
"p90": 6.38,
"breakout_share": 0.173,
"probability": 0.7134,
"confidence": "normal",
"own_median": 42,
"expected": 58
},
"replies": {
"multiple": 1.02,
"p75": 1.83,
"p90": 4.1,
"breakout_share": 0.095,
"probability": 0.58,
"confidence": "normal",
"own_median": 6,
"expected": 6
},
"reposts_and_quotes": {
"multiple": 0.98,
"p75": 1.7,
"p90": 3.49,
"breakout_share": 0.075,
"probability": 0.51,
"confidence": "low",
"own_median": 2,
"expected": 2
},
"views": {
"multiple": 1.02,
"p75": 1.83,
"p90": 4.1,
"breakout_share": 0.095,
"probability": 0.56,
"confidence": "low",
"own_median": 5100,
"expected": 5202
}
},
"helped": [
{
"key": "k_credential_proof",
"label": "A result of your own backs the point",
"detail": "Backs the point with a result more than usual",
"effect": 0.1842
}
],
"hurt": [
{
"key": "cov_is_quote",
"label": "It quotes another post",
"detail": "Quotes another post, unlike your usual post",
"effect": -0.0914
}
],
"warnings": [],
"accuracy": {
"pair_accuracy": 0.6516,
"posts": 9481,
"authors": 214,
"pairs": 4225,
"creators": 207,
"line": "Picks the better of two posts by the same account 65% of the time, cross-validated by creator on 4,225 pairs from 207 creators; no sealed test set yet."
},
"engine": {
"generated": "2026-09-17T19:07:36.538Z",
"question_set": "v1.1"
}
},
"meta": {
"credits_charged": 1,
"account_id": "1178367350552305665"
}
}Authorizations
A SuperX API key ("sxk_..."), created in the SuperX app under Account > API / MCP / CLI. Keys are server-side secrets.
Body
The draft to score.
1 - 4000True when an image would be attached.
True when a video would be attached.
True when the post quotes another post.
When it would go out (ISO-8601 with an explicit Z or offset). Defaults to now.
account (the default) scores against the account's own recent
posts; population scores against the average training post. An
account with too little history falls back to population.
account, population