Account, keys and billing
Sign up, read usage and limits, manage API keys and the plan.
Every limit an account has is readable: GET /api/usage gives each one with what is used and what is left. A limit of null means unlimited.
POST /api/signup: Create an account (the API key is emailed as a confirmation link, not returned here)GET /api/me: Account info, usage and connectionsGET /api/account: Alias of GET /api/me: account info, usage and connectionsGET /api/usage: This month's posts, today's AI drafts and brands, against the plan's limitsGET /api/plan: The account's plan, what it includes, current usage and the next plan with a checkout linkGET /api/plans: List plans and limitsGET /api/billing: Plan, subscription state and where to manage billingPOST /api/billing/checkout: Start a Stripe checkout for a paid planPOST /api/billing/portal: A Stripe customer-portal link to change plan, update the card or cancelGET /api/keys: List your API keys (prefixes only — the secret is never returned)POST /api/keys: Create a new API key, optionally with an expiryDELETE /api/keys/{id}: Revoke an API key immediately
Create an account (the API key is emailed as a confirmation link, not returned here)
/api/signupSignup never returns credentials. We create the account and email a one-time confirmation link; opening it proves you control the mailbox and issues your API key. This prevents anyone from registering an address they do not own and receiving a working key.
No API key needed.
Body (JSON)
| Field | Type | Description |
|---|---|---|
email required | string (email) |
Responses
| Status | Means |
|---|---|
200 | Account created; pending_verification=true, emailed=true|false |
curl -X POST "https://postwire.io/api/signup" \
-H "Content-Type: application/json" \
-d '{
"email": "you@example.com"
}'const res = await fetch("https://postwire.io/api/signup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"email": "you@example.com"
}),
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/signup",
json={
"email": "you@example.com",
},
)
print(r.status_code, r.json())Account info, usage and connections
/api/melimits carries posts_this_month, brands, ai_drafts_today, networks_per_post { limit } and scheduled_queue { used, limit, held, left } (null = no limit). A free account created before the 2-Oct-2026 limits also gets grandfathered { until, note } (it keeps the earlier limits until 2026-11-01). Free accounts get insights_teaser: how many What works patterns are ready and how strong each is, without the answer.
Needs an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | OK |
401 | Missing/invalid API key |
curl "https://postwire.io/api/me" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/me", {
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/me",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())Alias of GET /api/me: account info, usage and connections
/api/accountNeeds an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | Same body as /api/me |
401 | Missing/invalid API key |
curl "https://postwire.io/api/account" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/account", {
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/account",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())This month's posts, today's AI drafts and brands, against the plan's limits
/api/usage{ plan, plan_name, period, posts: { used, limit, left, resets_on }, ai_drafts_today: { used, limit, left, resets_at }, brands: { used, limit }, networks_per_post: { limit }, scheduled_queue: { used, limit, held, left }, grandfathered_until?, upgrade? } — a limit of null means unlimited; upgrade appears at 80 % of a limit.
Needs an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | usage |
curl "https://postwire.io/api/usage" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/usage", {
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/usage",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())Example response
{
"plan": "free",
"plan_name": "Free",
"period": "2026-10",
"posts": {
"used": 6,
"limit": 20,
"left": 14,
"resets_on": "2026-11-01"
},
"ai_drafts_today": {
"used": 1,
"limit": 5,
"left": 4
},
"brands": {
"used": 1,
"limit": 1
},
"networks_per_post": {
"limit": 2
},
"scheduled_queue": {
"used": 2,
"limit": 3,
"held": 0,
"left": 1
}
}Abridged. null as a limit means unlimited.
The account's plan, what it includes, current usage and the next plan with a checkout link
/api/planNeeds an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | { plan, name, price_usd_month, includes, limits: { posts_per_month, brands, ai_drafts_per_day, networks_per_post, scheduled_queue }, usage, grandfathered_until?, next? } |
curl "https://postwire.io/api/plan" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/plan", {
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/plan",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())List plans and limits
/api/plansEach plan: { name, price, brands, limit (posts a month, -1 = unlimited), genDay (AI drafts a day), networksPerPost (-1 = every network in each post), maxQueued (scheduled posts at a time, -1 = unlimited) }.
No API key needed.
Responses
| Status | Means |
|---|---|
200 | OK |
curl "https://postwire.io/api/plans"const res = await fetch("https://postwire.io/api/plans", {
method: "GET",
});
console.log(res.status, await res.json());import os, requests
r = requests.get(
"https://postwire.io/api/plans",
)
print(r.status_code, r.json())Plan, subscription state and where to manage billing
/api/billingChanging, cancelling or updating a card is done by a person: POST /api/billing/portal returns the portal link.
Needs an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | { plan, name, price_usd_month, subscription: active|none|unknown|null, manage, upgrade, refund } |
curl "https://postwire.io/api/billing" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/billing", {
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/billing",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())Start a Stripe checkout for a paid plan
/api/billing/checkoutNeeds an API key: Authorization: Bearer pw_live_….
Body (JSON)
| Field | Type | Description |
|---|---|---|
plan required | string | One of: starter, pro, agency, scale. |
Responses
| Status | Means |
|---|---|
200 | { url } |
curl -X POST "https://postwire.io/api/billing/checkout" \
-H "Authorization: Bearer $POSTWIRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"plan": "starter"
}'const res = await fetch("https://postwire.io/api/billing/checkout", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"plan": "starter"
}),
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/billing/checkout",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
json={
"plan": "starter",
},
)
print(r.status_code, r.json())A Stripe customer-portal link to change plan, update the card or cancel
/api/billing/portalNeeds an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | { url } |
503 | billing not configured |
curl -X POST "https://postwire.io/api/billing/portal" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/billing/portal", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/billing/portal",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())List your API keys (prefixes only — the secret is never returned)
/api/keysNeeds an API key: Authorization: Bearer pw_live_….
Responses
| Status | Means |
|---|---|
200 | keys[] |
curl "https://postwire.io/api/keys" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/keys", {
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/keys",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())Create a new API key, optionally with an expiry
/api/keysNeeds an API key: Authorization: Bearer pw_live_….
Body (JSON)
| Field | Type | Description |
|---|---|---|
name | string | |
expires_in_days | integer | 1 to 3650. |
Responses
| Status | Means |
|---|---|
200 | api_key shown once |
curl -X POST "https://postwire.io/api/keys" \
-H "Authorization: Bearer $POSTWIRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "n8n production",
"expires_in_days": 365
}'const res = await fetch("https://postwire.io/api/keys", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"name": "n8n production",
"expires_in_days": 365
}),
});
console.log(res.status, await res.json());import os, requests
r = requests.post(
"https://postwire.io/api/keys",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
json={
"name": "n8n production",
"expires_in_days": 365,
},
)
print(r.status_code, r.json())Revoke an API key immediately
/api/keys/{id}Needs an API key: Authorization: Bearer pw_live_….
Parameters
| Field | Type | Description |
|---|---|---|
id required | path, string |
Responses
| Status | Means |
|---|---|
200 | revoked |
404 | not found or already revoked |
curl -X DELETE "https://postwire.io/api/keys/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f" \
-H "Authorization: Bearer $POSTWIRE_API_KEY"const res = await fetch("https://postwire.io/api/keys/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());import os, requests
r = requests.delete(
"https://postwire.io/api/keys/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f",
headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())