API Reference
REST API for the AI SNS · Social Studio publishing platform. All responses are JSON unless noted. This page is generated from the server source and reflects the deployed build.
Auth & conventions
How authentication, roles, plan limits and credits work across every route.
Registering creates a user and a workspace — you become the owner — and returns a token together with the workspace id. Logging in returns the same pair. The token is a self-signed HS256 JWT valid for 30 days. There is no refresh endpoint, so sign in again once it expires.
POST /api/auth/register {email, password, workspace?} → {token, workspace_id}
POST /api/auth/login {email, password, workspace_id?} → {token, workspace_id}
JWT payload {uid, ws, email}
curl -H "Authorization: Bearer <token>" \
https://<host>/api/posts
Every route below /api passes through requireAuth, which resolves your workspace, user id and role. Authentication is resolved in this order:
- a legacy API_TOKEN environment match, treated as the owner of workspace 1;
- a valid JWT, with workspace membership checked;
- open development or demo mode.
AUTH routes accept any valid session. WRITE routes additionally require write permission, which only the owner and editor roles hold — a viewer or client is refused with 403 and a read-only role error. ADMIN routes need the x-admin-secret header and CRON routes need x-cron-secret. PUBLIC routes need no bearer token at all, because the token or id in the path is itself the credential.
Some writes check the workspace plan limit for posts, AI units and connected accounts. When a limit is exceeded the route responds:
402 { "error":"limit_reached", "kind":"posts|ai_units|accounts", "limit":30, "upgrade":true }
Monthly allowances per plan:
free posts 30 ai_units 50 accounts 1 starter posts 200 ai_units 500 accounts 3 pro posts 1000 ai_units 1500 accounts 5 business posts ∞ ai_units 3000 accounts 15
Credits are a separate ledger. AI actions spend them according to a cost map: a draft or a set of hashtags costs one credit, an image or an image reference costs five. Credits are soft by default — usage is tracked but never blocked — unless credit enforcement is switched on. Only the influencer analysis route hard-checks credits and can refuse the request.
lib/billing.js · lib/plans.js ENFORCE_CREDITS=1 → credits become blocking POST /api/influencers/analyze → 402 out_of_credits