X (Twitter) credits

Post to X as a pay-per-use add-on of the paid plans: what each post uses, what is left, and top-ups.

View as MarkdownOpenAPIBase URL https://postwire.io

X charges for every post, so posting to X uses X credits: 1 X credit = 1 X post; a post with a link uses 10 (X charges about 13 times more for links); each image or video adds 1. Each paid plan includes X credits every month (Starter 30, Pro 150, Agency 600, Scale 2,000; they renew on the 1st and do not roll over) and a daily cap of X posts (5, 20, 60, 150). Top-up credits (80 for $5, 340 for $20, one-time) are used after the plan's credits and do not expire. X is not available on Free or during the trial. Connect X like any OAuth network (POST /api/oauth/x/url) and publish with platforms: ["x"]: the credits are taken before anything is sent to X and come back if X rejects the post. Text is fitted to 280 characters as X counts them (a link counts 23, an emoji 2); up to 4 images or one video.

  • GET /api/x: X (Twitter) credits: what posting to X uses and what this account has left
  • GET /api/x/quote: How many X credits one post would use, before it is published or scheduled
  • POST /api/x/credits/checkout: A Stripe Checkout link to buy X top-up credits (one-time payment)

X (Twitter) credits: what posting to X uses and what this account has left

GET/api/x

X is a pay-per-use add-on of the paid plans (Starter, Pro, Agency, Scale; not Free, not during a trial). 1 X credit = 1 X post; a post with a link uses 10 (X charges about 13 times more for links); each image or video adds 1. Each paid plan includes X credits every month (Starter 30, Pro 150, Agency 600, Scale 2,000; they renew on the 1st and do not roll over) and a daily cap of X posts (5, 20, 60, 150); top-up credits (80 for $5, 340 for $20, one-time) are used after them and do not expire. An X post without enough credits is not sent to X: its result has code x_credits_required and the links to buy more.

Needs an API key: Authorization: Bearer pw_live_….

Responses

StatusMeans
200{ network: "x", available, mode: paid|free|trial|internal, allowed, killed, pricing: { rule, credits, plans, packs, notes }, credits?: { plan_allowance, allowance_used, allowance_left, topup, total_left, resets_on }, daily?: { used, max }, buy?: [{ pack, usd, credits, url, label }], history: [{ at, kind, what, credits, from_plan, from_topup }], upgrade? (Free), house? (internal: { spent_usd, cap_usd }) }
curl
curl "https://postwire.io/api/x" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/x", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/x",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Example response

JSON
{
  "network": "x",
  "available": true,
  "mode": "paid",
  "allowed": true,
  "credits": {
    "plan_allowance": 150,
    "allowance_used": 12,
    "allowance_left": 138,
    "topup": 80,
    "total_left": 218,
    "resets_on": "2026-11-01"
  },
  "daily": {
    "used": 3,
    "max": 20
  },
  "buy": [
    {
      "pack": "5",
      "usd": 5,
      "credits": 80,
      "url": "https://postwire.io/api/x/credits/go?t=…&pack=5"
    },
    {
      "pack": "20",
      "usd": 20,
      "credits": 340,
      "url": "https://postwire.io/api/x/credits/go?t=…&pack=20"
    }
  ]
}

Abridged: it also returns pricing (the rule, every plan's X credits and daily cap, the packs) and history (the last movements).

How many X credits one post would use, before it is published or scheduled

GET/api/x/quote

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
textquery, stringThe X post's text. A link anywhere in it (also a bare domain such as postwire.io/x) makes it a post with a link.
imagesquery, integerImages attached (X takes up to 4).
videoquery, booleanA video attached (one, on its own).

Responses

StatusMeans
200{ credits, has_link, images, video, sentence } — e.g. sentence "This post uses 10 X credits: it contains a link."
curl
curl "https://postwire.io/api/x/quote?text=The+new+docs+are+live%3A+https%3A%2F%2Fpostwire.io%2Fdocs%2F" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/x/quote?text=The+new+docs+are+live%3A+https%3A%2F%2Fpostwire.io%2Fdocs%2F", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/x/quote?text=The+new+docs+are+live%3A+https%3A%2F%2Fpostwire.io%2Fdocs%2F",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Example response

JSON
{
  "credits": 10,
  "has_link": true,
  "images": 0,
  "video": false,
  "sentence": "This post uses 10 X credits: it contains a link."
}

A Stripe Checkout link to buy X top-up credits (one-time payment)

POST/api/x/credits/checkout

Packs: "5" = 80 credits for $5, "20" = 340 credits for $20. Nothing is charged until the person pays on the Stripe page. Paid plans only (403 x_paid_plan_required otherwise, with the plan that has X).

Needs an API key: Authorization: Bearer pw_live_….

Body (JSON)

FieldTypeDescription
pack requiredstringOne of: 5, 20.

Responses

StatusMeans
200{ url } of the Stripe Checkout page
403x_paid_plan_required (Free or a running trial) or internal_account
curl
curl -X POST "https://postwire.io/api/x/credits/checkout" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "pack": "5"
}'
Node
const res = await fetch("https://postwire.io/api/x/credits/checkout", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "pack": "5"
  }),
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.post(
    "https://postwire.io/api/x/credits/checkout",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
    json={
        "pack": "5",
    },
)
print(r.status_code, r.json())

Example response

JSON
{
  "url": "https://checkout.stripe.com/c/pay/cs_live_…"
}