Analytics (What works)
Your best posts against your own median, the patterns behind them, and drafts modelled on a winner.
Every post PostWire published in the last 90 days, compared with the median of the same account on the same network. A network that does not share a number is listed with the reason, never as a zero. n is always returned.
GET /api/insights: What works: your best posts against your own median, and the patterns behind themPOST /api/insights/replicate: Draft new posts modelled on one of your best posts (nothing is published)POST /api/insights/settings: Turn click tracking of your own links on or off
What works: your best posts against your own median, and the patterns behind them
/api/insightsEvery post PostWire published for the account in the last 90 days, compared with the median of the same social account on the same network (views where the network reports them, otherwise likes + reposts + replies). n is always returned; posts under 24 hours old are not ranked; a network that does not share a number is listed with the reason instead of a zero. Free plans get the 3 best posts; paid plans get the full ranking and the patterns (format, day, time of day, length, hashtags, first-line type), which need at least 10 ranked posts and 3 posts per group. On a plan without patterns, locked.patterns_preview lists the patterns that are ready with the size of each effect (x_median, n) but not the winning value, locked.best_time does the same for the best time to post, and locked.teaser sums it up (or says how many more measured posts are needed).
Needs an API key: Authorization: Bearer pw_live_….
Parameters
| Field | Type | Description |
|---|---|---|
brand_id | query, string | |
platform | query, string | |
tz | query, string | IANA timezone for the day/time patterns (default UTC) |
Responses
| Status | Means |
|---|---|
200 | { top: [{ id, platform, value, metric, median, n, x_median, headline, why[] }], networks[], patterns | null, locked: { patterns_ready, patterns_status, patterns_preview[], best_time, teaser, more_posts_ranked } | null, insights_teaser?, upgrade? } |
401 | API key required |
404 | brand not found |
curl "https://postwire.io/api/insights?platform=bluesky&tz=America%2FLima" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/insights?platform=bluesky&tz=America%2FLima", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());import os, requests
r = requests.get(
"https://postwire.io/api/insights?platform=bluesky&tz=America%2FLima",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())Draft new posts modelled on one of your best posts (nothing is published)
/api/insights/replicateWrites one draft per network reusing the structure, opening, length, format and tone of a post from /api/insights, on a new topic or angle; its sentences are not reused. Counts toward the daily AI limit. Paid plans.
Needs an API key: Authorization: Bearer pw_live_….
Body (JSON)
| Field | Type | Description |
|---|---|---|
post_id required | string | |
platforms | array of string | |
topic | string | |
brand_voice | string |
Responses
| Status | Means |
|---|---|
200 | { drafts: { <platform>: { text, title?, tags? } }, reference, published: false } |
402 | not included in the current plan (code plan_feature, with the plan that includes it) |
404 | post not found |
429 | daily AI limit |
503 | AI not configured |
curl -X POST "https://postwire.io/api/insights/replicate" \
-H "Authorization: Bearer $POSTWIRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post_id": "at://did:plc:4x2…/app.bsky.feed.post/3l7…",
"platforms": [
"bluesky",
"linkedin"
],
"topic": "our new rye"
}'const res = await fetch("https://postwire.io/api/insights/replicate", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"post_id": "at://did:plc:4x2…/app.bsky.feed.post/3l7…",
"platforms": [
"bluesky",
"linkedin"
],
"topic": "our new rye"
}),
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/insights/replicate",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
json={
"post_id": "at://did:plc:4x2…/app.bsky.feed.post/3l7…",
"platforms": ["bluesky", "linkedin"],
"topic": "our new rye",
},
)
print(r.status_code, r.json())Turn click tracking of your own links on or off
/api/insights/settingsWith track_links on, https links in posts to Bluesky, Mastodon, LinkedIn, Facebook, Telegram, Discord and YouTube go out as postwire.io/r/<code> and redirect to the same page; clicks show up in /api/insights. Paid plans.
Needs an API key: Authorization: Bearer pw_live_….
Body (JSON)
| Field | Type | Description |
|---|---|---|
track_links required | boolean |
Responses
| Status | Means |
|---|---|
200 | { ok, track_links } |
402 | not included in the current plan |
curl -X POST "https://postwire.io/api/insights/settings" \
-H "Authorization: Bearer $POSTWIRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"track_links": true
}'const res = await fetch("https://postwire.io/api/insights/settings", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"track_links": true
}),
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/insights/settings",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
json={
"track_links": True,
},
)
print(r.status_code, r.json())