Get started
Recipes
Complete scripts for common automations.
Schedule a post with an image
Node.js 18+. Imports an image from a URL, then schedules a post with it.
// Schedule a post with an image from your CMS, e.g. from a cron job or webhook.
const BASE = "https://smanager.mrfirdavs.uz/api/v1";
async function call(path, body) {
const res = await fetch(BASE + path, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ONETHREADS_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
const json = await res.json();
if (!res.ok) throw new Error(`${json.error.code}: ${json.error.message}`);
return json;
}
const image = await call("/media", { url: "https://example.com/cover.png" });
const post = await call("/posts", {
account: "yourname",
text: "New on the blog: how we cut our build time in half",
media: [{ id: image.id, alt: "Build time chart" }],
scheduledAt: "2026-11-02T09:00:00Z",
});
console.log("Scheduled", post.id, "for", post.scheduledAt);Schedule a thread
Node.js 18+. Chains posts with options.replyTo, so each one publishes as a reply to the one before it.
// Schedule a thread: each post replies to the one before it.
const BASE = "https://smanager.mrfirdavs.uz/api/v1";
const parts = [
"We rebuilt our scheduler from scratch. Here's what we learned 🧵",
"1/ Queues are state machines. Every step has to survive a crash.",
"2/ Never publish twice: claim work with a conditional update.",
];
let previous;
let at = Date.parse("2026-11-02T09:00:00Z");
for (const text of parts) {
const res = await fetch(BASE + "/posts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ONETHREADS_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text,
options: previous ? { replyTo: previous } : {},
scheduledAt: new Date(at).toISOString(),
}),
});
const post = await res.json();
if (!res.ok) throw new Error(post.error.message);
previous = post.id;
at += 60_000; // a minute apart; replies never go out before their parent anyway
}Retry failed posts
Python with requests. Run it on a schedule to republish anything that failed.
# Retry every failed post, e.g. once an hour.
import os, requests
BASE = "https://smanager.mrfirdavs.uz/api/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['ONETHREADS_KEY']}"
failed = session.get(f"{BASE}/posts", params={"status": "failed"}).json()["data"]
for post in failed:
r = session.post(f"{BASE}/posts/{post['id']}/publish")
if r.status_code in (200, 202):
print("Published", post["id"], r.json()["permalink"])
else:
print("Still failing", post["id"], r.json()["error"]["message"])No-code tools
n8n, Make and Zapier work too: add an HTTP request step, set the Authorization: Bearer … header and send a JSON body like the examples on each endpoint page.