REST API
Post from your own code with a project API key. Create one in the project's Settings → Developers (admins only); it is shown once. Send it as a bearer token to https://your-postwase-domain/api/v1.
bash
curl https://your-postwase-domain/api/v1/channels -H "Authorization: Bearer pw_live_YOUR_KEY"Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/me | The project the key belongs to |
GET | /api/v1/channels | Connected channels: id, platform, name, status |
POST | /api/v1/media | Import a file from a URL: { url, filename? } → 202 { id } |
GET | /api/v1/media/:id | Media status: uploaded → processing → ready (or failed) |
GET | /api/v1/posts | Recent posts with per-channel status; ?from=&to= filter by scheduled time |
POST | /api/v1/posts | Create a post (body below) |
GET | /api/v1/posts/:id | One post with media and channel options |
PUT | /api/v1/posts/:id | Replace a post that hasn't started publishing |
POST | /api/v1/posts/:id/cancel | Cancel channels that haven't published |
Create a post
Exactly one of publishNow, scheduledAt (ISO 8601 with offset) or addToQueue; with none of them the post is saved as a draft.
bash
curl https://your-postwase-domain/api/v1/posts \
-H "Authorization: Bearer pw_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{
"content": "New clip is out!",
"mediaIds": ["MEDIA_ID"],
"targets": [
{ "channelId": "TIKTOK_CHANNEL_ID", "options": { "privacyLevel": "PUBLIC_TO_EVERYONE" } },
{ "channelId": "YOUTUBE_CHANNEL_ID", "options": { "title": "New clip" }, "contentOverride": "Full story in the description" }
],
"scheduledAt": "2026-11-02T09:00:00+07:00"
}'Responses: 201 with the post; 422 with issues when a network's rules aren't met (or media_not_ready); 402 when the owner's plan limit is reached; 409 no_free_slot for a full queue.
Import media, then post
Node.js 20+
const api = (path, init = {}) =>
fetch("https://your-postwase-domain/api/v1" + path, {
...init,
headers: { Authorization: `Bearer ${process.env.POSTWASE_KEY}`, "Content-Type": "application/json" },
}).then((r) => r.json());
const { id } = await api("/media", { method: "POST", body: JSON.stringify({ url: "https://example.com/clip.mp4" }) });
let media;
do {
await new Promise((r) => setTimeout(r, 3000));
media = await api(`/media/${id}`);
} while (media.status === "uploaded" || media.status === "processing");
if (media.status !== "ready") throw new Error(media.error);
const [tiktok] = (await api("/channels")).filter((c) => c.platform === "tiktok");
await api("/posts", {
method: "POST",
body: JSON.stringify({
content: "New clip!",
mediaIds: [id],
targets: [{ channelId: tiktok.id, options: { privacyLevel: "PUBLIC_TO_EVERYONE" } }],
addToQueue: true,
}),
});Prefer AI assistants? The same actions are available as MCP tools: see Connect AI apps.