GetMulticast API
Publish, schedule, and manage replies across every platform GetMulticast connects to — programmatically. Built for Zapier, n8n, Make, and your own scripts.
https://getmulticast.com/api/v1 — every path below is relative to this.This is the same engine the GetMulticast dashboard itself runs on, not a separate or lighter reimplementation — every endpoint here calls the identical internal logic a click in the dashboard would trigger, so behavior never drifts between the two. A UI redesign never changes what these endpoints do; only a real, documented change to this reference does.
Official SDKs: none published yet — JavaScript, Python and PHP clients are planned, not built. Until then, any HTTP client works fine: every example on this page is plain curl, and translates directly to fetch, requests, axios, Guzzle, or whatever you already use.
Quickstart
Zero to a real published post, in order:
- Get an API key — Dashboard → Settings → Developer. This one step is UI-only; everything after it is a plain HTTP call.
- Find a real account id — every id used below (
"1784..."etc.) comes from this call, not made up:
curl https://getmulticast.com/api/v1/accounts \ -H "Authorization: Bearer gmc_live_..."
- Publish — using a real
mediaUrlyou already have hosted somewhere public, and a real account id from step 2:
curl -X POST https://getmulticast.com/api/v1/posts \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{
"mediaUrl": "https://example.com/clip.mp4",
"mediaType": "video",
"caption": "Hello from the API",
"selections": { "instagram": ["1784..."] }
}'
That returns 202 immediately with a runId — see Rate limits & timeouts for why it's 202 and not 201, and GET /posts/{id} below for how to check the real result once publishing finishes.
Authentication
Every request needs an API key in the Authorization header, as a Bearer token. Create one from Dashboard → Settings → Developer — the raw key is shown exactly once at creation and can't be retrieved again (we only ever store a one-way hash of it, the same way Stripe and GitHub handle API keys).
# every request
curl https://getmulticast.com/api/v1/accounts \
-H "Authorization: Bearer gmc_live_XXXXXXXXXXXXXXXXXXXXXXXX"
Each key carries its own scopes, checked directly against this real list — nothing here is aspirational:
| Scope | Grants |
|---|---|
accounts:read | Read connected social accounts |
posts:read | Read posts, publish results and scheduled posts |
posts:write | Publish, schedule, reschedule, delete and retry posts |
analytics:read | Read real per-post metrics (YouTube, X, Pinterest, Bluesky only — see GET /posts/{id}/analytics) |
comments:read | Read recent comments and the pending-reply review queue |
comments:write | Draft, edit, approve, reject and send comment replies |
credits:read | Read the account's AI credit balance |
webhooks:read | List registered webhooks and their delivery history |
webhooks:write | Register and delete webhooks |
rss:read | List RSS auto-post feeds |
rss:write | Register, update and delete RSS auto-post feeds |
recycling:read | List content recycling rules |
recycling:write | Create, update and delete content recycling rules |
A request to an endpoint outside a key's granted scopes returns 403 insufficient_scope. Create narrowly-scoped keys for anything you hand to a third-party tool.
Rate limits & timeouts
| Limit | Value |
|---|---|
| Requests per minute, per key | 60 |
| Requests per day, per key | 5,000 |
| Request timeout | 30s |
| Max request body | 10MB |
Every response carries rate-limit headers so you can self-throttle before hitting the ceiling:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1757980800 # unix epoch seconds
Exceeding a limit returns 429 with a Retry-After header (seconds to wait). POST /posts and POST /posts/scheduled queue the real publish work in the background and return immediately (202) — the actual per-platform publishing (which can genuinely take minutes, e.g. Instagram/TikTok video processing) happens after the response, same as the dashboard's own "Post Now" button. Poll GET /posts/{id} for the final result, or use a webhook (see below) instead of polling.
202 response itself comes back in well under a second — it only queues the job. The actual publish that follows in the background is the part that varies: seconds for platforms with simple APIs, up to a couple of minutes for platforms that process video server-side before it's live (Instagram and TikTok in particular). That's why this endpoint returns 202 before publishing is done, not 201 after it.Errors
Every error — auth, validation, rate limit, or an unexpected failure — returns the same JSON envelope, so you can always branch on error.code rather than parsing text:
{
"error": {
"code": "insufficient_scope",
"message": "This API key doesn't have the 'posts:write' scope required for this endpoint.",
"requestId": "a1b2c3d4e5f6a1b2"
}
}
| HTTP status | error.code | Meaning |
|---|---|---|
400 | invalid_request | Missing/malformed field — see message for which one. |
401 | missing_api_key / invalid_api_key / revoked_api_key | No, wrong, or revoked Bearer token. |
403 | insufficient_scope / forbidden | Key lacks the scope, or the resource belongs to someone else. |
404 | not_found | No such resource, or wrong method for a real path. |
405 | method_not_allowed | Path exists, wrong HTTP method. |
409 | failed_precondition | Valid request, wrong state (e.g. approving an already-sent reply). |
429 | rate_limit_exceeded / resource_exhausted | Rate limit hit, or (for posts) out of AI credits. |
500 | internal_error | Something broke on our end — logged server-side by requestId; include it if you contact support. |
Two real mistakes worth calling out
An empty selections object on POST /posts is rejected up front, before anything is queued:
{ "error": { "code": "invalid_request", "message": "selections is required", "requestId": "..." } }
A misspelled or unsupported platform key inside selections (e.g. "instagrm", or a real platform you just haven't connected yet) behaves differently, and it's easy to get caught out by this: it is not rejected up front. The request still returns 202 like any other, but that platform's entry in the eventual publishResults (see GET /posts/{id}) comes back as a real, specific per-platform failure instead of a request-level error:
"publishResults": {
"instagrm": [{ "ok": false, "error": "No connected instagrm account found." }]
}
If a platform key never shows up publishing successfully, check it against GET /accounts first — that's the exact, real set of platform keys and account ids you have to work with.
Pagination
List endpoints accept limit (1–100, default 25) and cursor, and return a nextCursor — pass it back as cursor to fetch the next page; null means you're on the last page.
curl "https://getmulticast.com/api/v1/posts?limit=50&cursor=abc123" \ -H "Authorization: Bearer gmc_live_..."
Idempotency
Send an Idempotency-Key header on POST /posts, POST /posts/scheduled, or POST /comments/reply to make a retried request safe — if you send the same key twice (e.g. your client timed out and retried), the second call returns the exact same result as the first instead of publishing/replying twice. Keys are scoped per API key and remembered for 24 hours. Use a UUID you generate per logical action, same convention as Stripe.
curl -X POST https://getmulticast.com/api/v1/posts \
-H "Authorization: Bearer gmc_live_..." \
-H "Idempotency-Key: 8f14e45f-ceea-4f9f-9b0f-3c1e2e6a1a11" \
-H "Content-Type: application/json" \
-d '{ ... }'
Versioning
This is v1 — the path itself (/api/v1/...) is the version. Once you're integrated, this contract won't change under you: no field is removed or repurposed, no endpoint's meaning changes. Real new capability ships as new, additive fields or endpoints within v1 where possible; a genuine breaking change ships as /api/v2/... alongside v1, not in place of it.
Accounts
Every connected social account across every platform.
curl https://getmulticast.com/api/v1/accounts \ -H "Authorization: Bearer gmc_live_..."
{
"accounts": {
"instagram": [{ "id": "1784...", "label": "Main Instagram" }],
"youtube": [{ "id": "UCxx...", "label": "My Channel" }],
"x": [{ "id": "14582...", "label": "@handle" }]
// ...one array per connected platform: facebook, threads, tiktok,
// linkedin, bluesky, pinterest, googlebusiness
},
"requestId": "..."
}
Posts
Publish now to one or more connected accounts across one or more platforms. Returns 202 immediately with a post id — publishing itself happens in the background (see Rate limits above). Upload your media somewhere public first (or use mediaUrl from your own storage) — this endpoint never accepts raw file bytes.
| Field | Type | Required | Notes |
|---|---|---|---|
mediaUrl | string | yes | A public URL to the video or image file. |
mediaType | string | yes | "video" or "image". Text-only posts aren't supported yet. |
selections | object | yes | { "instagram": ["accountId1"], "x": ["accountId2"] } — platform → array of account ids from GET /accounts. |
caption | string | no | Shared caption for every selected account. |
captionOverrides | object | no | { "x": "Shorter caption for X" } — per-platform override. |
hashtags | string[] | no | Appended to the caption. |
firstComment | string | no | Auto-posted as the first comment (Facebook & Instagram only today). |
curl -X POST https://getmulticast.com/api/v1/posts \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{
"mediaUrl": "https://example.com/clip.mp4",
"mediaType": "video",
"caption": "New drop 🚀",
"hashtags": ["launch","newproduct"],
"selections": { "instagram": ["1784..."], "youtube": ["UCxx..."] }
}'
{ "runId": "8fJ2k...", "queued": true, "requestId": "..." }
Lists your posts, newest first. Paginated (see Pagination above).
{
"posts": [
{ "id": "8fJ2k...", "status": "published", "caption": "New drop 🚀",
"publishResults": { "instagram": [{ "accountId": "1784...", "ok": true, "postId": "..." }] },
"createdAt": "2026-09-12T10:03:00Z" }
],
"nextCursor": null,
"requestId": "..."
}
One post's full status and per-account publish results. status is processing, published, or publish_failed.
Real, live metrics for one post on one platform. Only youtube, x, pinterest, and bluesky are wired — every other platform returns a real 400 not_supported naming the exact missing permission (e.g. Instagram needs a permission this app doesn't have granted yet), never a fake zero.
curl "https://getmulticast.com/api/v1/posts/8fJ2k.../analytics?platform=x" \ -H "Authorization: Bearer gmc_live_..."
{
"platform": "x", "postId": "18472...",
"metrics": { "likes": 42, "reposts": 5, "replies": 3, "quotes": 0, "impressions": 1204 },
"requestId": "..."
}
Totals (views, interactions, posts, engagement rate) and your top 3 posts by views, across one channel or every connected channel. Both params optional — omit accountId to summarize everything; days defaults to 30 (max 90).
curl "https://getmulticast.com/api/v1/analytics/summary?days=7" \ -H "Authorization: Bearer gmc_live_..."
One channel's own totals, plus which content formats and hashtags actually perform (medians, not averages, so one viral post doesn't skew it).
This channel's best times/day/format/posting-frequency to post, computed from its own real post history. Returns "basedOn": "general" with generic guidance if there isn't 5+ posts of real history yet — never presented as personalized when it isn't.
Your best-performing posts, ranked by views (default), likes, or comments. All params optional.
Every competitor you're tracking (Analytics → Competitor tracking), with their latest followers, posting frequency, and engagement per post.
Retries only the accounts that failed on a given platform for this post.
curl -X POST https://getmulticast.com/api/v1/posts/8fJ2k.../retry \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{ "platform": "instagram" }'
Same fields as POST /posts, plus:
| Field | Type | Required | Notes |
|---|---|---|---|
date | string | yes | "2026-09-20" |
time | string | no | "09:00", defaults to 09:00. |
timezone | string | no | IANA name, e.g. "America/New_York". Defaults to UTC. |
Returns 201 with the scheduled post's id and resolved UTC time.
Lists posts still waiting to publish, soonest first. Paginated.
Reschedules a still-pending post. Body: { "scheduledAtUtc": "2026-09-21T14:00:00Z" }, or { "date": "...", "time": "..." } in the post's original timezone.
Cancels a still-pending scheduled post.
Comments & Replies
Recent comments (last 7 days) across your monitored accounts on Instagram, Facebook, Threads, YouTube, LinkedIn and Bluesky, including whether each already has a reply. X/Twitter works at the mentions level instead — see /replies/pending, which covers every platform including X.
Replies to one comment surfaced by GET /comments. Send directText to send your own exact text immediately (no AI, no review step), or omit it to have GetMulticast's AI draft a reply into your Review queue (/replies/pending) instead of sending it directly.
| Field | Required | Notes |
|---|---|---|
platform, accountId, commentId | yes | From GET /comments. |
text | yes | The original comment's text (used for the AI draft). |
directText | no | Send exactly this, no AI involved. |
instruction | no | One-off AI instruction, e.g. "mention our discount code". |
postUrn | LinkedIn only | Required for LinkedIn. |
rootUri, rootCid, commentCid | Bluesky only | Required for Bluesky (AT Protocol reply refs). |
Marks a comment as handled without replying (e.g. spam). Body: { "platform", "accountId", "commentId" }.
Your Review Inbox — AI-drafted replies (from review-mode automations, across every platform including X) waiting for approval.
Sends the pending reply — the AI draft as-is, or pass { "editedText": "..." } to send different text instead.
Discards a pending reply without sending it.
Asks the AI to revise the current draft. Body: { "context": "make it shorter and friendlier" } (required).
Overwrites the draft text without sending it. Body: { "text": "..." }.
Credits
Your remaining AI credit balance — spent by POST /videos below (never by the post/comment/webhook/RSS/recycling endpoints above, which only move media you already have).
{ "credits": 847, "requestId": "..." }
AI Video Generation
Generates a real AI video — the same engine the dashboard's own "Generate Video" button calls, not a separate or lighter version. A short text-to-video clip is generated per scene (Agnes), with an optional AI-narrated voiceover track. Generation happens in the background and can take minutes: POST /videos returns 202 immediately with a videoId; poll GET /videos/{id} until status is "ready" (then videoUrl is set — pass it straight into POST /posts or POST /posts/scheduled to publish it) or "failed" (statusMessage explains why; any charged credits are automatically refunded). Honest current limitation: there is no compositing step — with multiple scenes, the first scene that produced a clip becomes videoUrl, every scene's own clip is kept on scenes[i].mediaUrl, and a voiceover track (if requested) is a separate file, not muxed into the video.
Starts generating a video. Charges AI credits immediately (see GET /credits) unless saveAsDraft is true — an insufficient balance returns 429 resource_exhausted before anything is charged or generation starts.
| Field | Type | Required | Notes |
|---|---|---|---|
prompt | string | no | What the video should be about — becomes a single implicit scene when scenes is omitted. Needed unless every scene in scenes supplies its own aiPrompt. |
scenes | array | no | Advanced: multiple scenes instead of one prompt. Each: { "mediaSource": "ai"|"upload", "aiPrompt", "mediaUrl", "voiceoverScript" } — "upload" scenes need mediaUrl, "ai" scenes need aiPrompt or a top-level prompt. |
aspectRatio | string | no | "9:16" (default), "1:1", or "16:9". |
aiVoiceover | boolean | no | Adds an AI-narrated voiceover track (edge-tts), synthesized from each scene's voiceoverScript or the top-level prompt. |
voiceId | string | no | Voiceover voice id. Defaults to the account's default voice. |
saveAsDraft | boolean | no | Saves the video's settings without generating or charging credits — generate later from the dashboard. |
curl -X POST https://getmulticast.com/api/v1/videos \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{
"prompt": "A cinematic drone shot flying over a mountain lake at sunrise",
"aspectRatio": "9:16",
"aiVoiceover": true
}'
{ "videoId": "vX9k2...", "creditsRemaining": 823, "requestId": "..." }
Lists your videos, newest first. Paginated (see Pagination above).
One video's generation status. status is draft, processing, ready, or failed; progressPct and statusMessage update live while processing.
{
"id": "vX9k2...", "status": "ready", "progressPct": 100,
"videoUrl": "https://storage.googleapis.com/.../vX9k2....mp4",
"voiceoverUrl": "https://storage.googleapis.com/.../vX9k2....mp3",
"requestId": "..."
}
Permanently deletes a video.
Webhooks
Register a URL to get a real HTTP POST the moment something happens — no polling. Delivery is durable: every event is queued and a background worker attempts delivery, retrying on a real backoff schedule (1m → 5m → 30m → 2h → 6h → 24h, 7 attempts total) if your endpoint doesn't return a 2xx — after which the delivery is marked failed and stops retrying. Every delivery is signed so you can verify it actually came from GetMulticast, and carries the same X-GetMulticast-Delivery id across every retry attempt so you can safely dedupe on your end.
| Event | Fires when |
|---|---|
post.published | A post finished publishing to at least one account. |
post.failed | A post failed on every selected account. |
comment.received | A new comment/mention was fetched on a monitored account. |
reply.sent | A reply — auto-sent or approved from the Review queue — actually went out. |
// POST to your url, Content-Type: application/json
{
"id": "a5e0...",
"event": "post.published",
"createdAt": "2026-09-12T10:04:12Z",
"data": { "runId": "8fJ2k...", "results": { "...": "..." }, "okCount": 2, "total": 2 }
}
Headers on every delivery:
X-GetMulticast-Event: post.published
X-GetMulticast-Signature: sha256=<hmac hex digest of the raw body, using your webhook secret>
X-GetMulticast-Delivery: a5e0f21c-... # unique per delivery attempt
Verify it (Node example — same HMAC-SHA256-over-raw-body pattern Stripe/GitHub webhooks use):
const crypto = require("crypto");
function verify(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}
Registers a webhook. Body: { "url": "https://...", "events": ["post.published","reply.sent"] }. The response's secret field is shown exactly once — store it to verify future deliveries.
Lists your registered webhooks (never returns the secret again).
Removes a webhook.
Real delivery history for one webhook, newest first — every attempt's status and error, useful for debugging a receiver that isn't seeing events.
{
"deliveries": [
{ "id": "d9c1...", "event": "post.published", "status": "delivered", "attempts": 1, "lastError": null, "createdAt": "..." },
{ "id": "a2e0...", "event": "reply.sent", "status": "pending", "attempts": 2, "lastError": "http_503", "nextAttemptAt": "..." }
],
"requestId": "..."
}
RSS Auto-Post
Point GetMulticast at an RSS or Atom feed and it checks for new items on a schedule (15 minutes minimum), posting each new one to the accounts you choose — the same automation Zapier/IFTTT "RSS → social" recipes provide, built in.
<enclosure>/Atom enclosure link, (2) Media RSS (<media:content>/<media:thumbnail>), (3) the first <img> found in the item's full HTML body. Items with none of these are skipped, not force-posted as text. Only facebook, instagram, threads, pinterest, and bluesky support image posts today, so those are the only valid targets for an RSS feed.| Field | Required | Notes |
|---|---|---|
url | yes | The feed's URL (RSS 2.0 or Atom). |
selections | yes | Same shape as POST /posts — { "instagram": ["accountId"] }. Only image-capable platforms are accepted. |
captionTemplate | no | Defaults to "{title}\n\n{link}" — {title} and {link} are the only placeholders substituted. |
checkIntervalMinutes | no | Defaults to 60, floor of 15. |
curl -X POST https://getmulticast.com/api/v1/rss-feeds \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/feed/",
"selections": { "instagram": ["1784..."], "facebook": ["1029..."] },
"captionTemplate": "New post: {title}\n\nRead more: {link}",
"checkIntervalMinutes": 30
}'
Lists your feeds, including lastCheckedAt, lastError (if the last check failed) and postedCount.
Updates any of active, selections, captionTemplate, checkIntervalMinutes. Set active: false to pause a feed without deleting it.
Queues an immediate check instead of waiting for the next scheduled interval — picked up within about a minute.
Content Recycling
Pick one of your own already-published posts and set up a rule to automatically re-publish it again every N days — optionally with the caption AI-rewritten each time so it doesn't read as a verbatim repeat. Checked every 6 hours.
GET /posts/{id}/analytics above), so an automatic best-post picker would either ignore most platforms or invent numbers. You choose the source post explicitly.| Field | Required | Notes |
|---|---|---|
sourcePostId | yes | A post id from GET /posts that already published successfully. |
selections | no | Defaults to the accounts the source post actually succeeded on. |
intervalDays | no | Defaults to 30, floor of 1. |
rewriteCaption | no | If true, AI rewrites the caption on each recycle instead of reusing it verbatim. |
curl -X POST https://getmulticast.com/api/v1/recycling-rules \
-H "Authorization: Bearer gmc_live_..." \
-H "Content-Type: application/json" \
-d '{ "sourcePostId": "8fJ2k...", "intervalDays": 14, "rewriteCaption": true }'
Lists your rules, including lastRecycledAt, nextRecycleAt, and recycleCount.
Updates any of active, selections, intervalDays, rewriteCaption. Set active: false to pause without deleting.
Queues an immediate recycle instead of waiting for the next scheduled interval.
OpenAPI spec & Postman collection
Every endpoint on this page, machine-readable — generate a client in any language, or import straight into Postman/Insomnia instead of building requests by hand.
Download OpenAPI 3.0 spec (.yaml)
Download Postman collection (.json)
The collection ships with base_url and api_key as collection variables — set api_key once (Postman → collection → Variables) and every request in it authenticates automatically.
MCP server
A Model Context Protocol server that exposes this entire API as tools an MCP-compatible AI client (ChatGPT, Claude, etc.) can call directly — "post this to Instagram and Facebook," "what's in my review queue," "reply to that comment," said in plain language. Two ways to connect, use whichever fits your client — GetMulticast never sees your MCP client's traffic either way, it's just another caller of the same public API documented on this page.
Remote server (no install) — for ChatGPT, Claude Code, and claude.ai
Server URL: https://getmulticast.com/mcp — every request needs your API key as a normal bearer header: Authorization: Bearer gmc_live_...
ChatGPT (Settings → Connectors → Advanced → Developer mode, then Add MCP server):
- Transport: Streamable HTTP
- URL:
https://getmulticast.com/mcp - Headers: name
Authorization, valueBearer gmc_live_...
Claude Code, one command, no download:
claude mcp add getmulticast -t http \ --header "Authorization: Bearer gmc_live_..." \ -- https://getmulticast.com/mcp
claude.ai (web or desktop app) — no API key needed, real sign-in instead:
- Settings → Connectors → Add custom connector
- URL:
https://getmulticast.com/mcp - Authentication: Sign in now
- Click Add — Claude opens a GetMulticast login/approve screen, click Approve, done
Local server (download & run) — Claude Desktop's other option
Download the server (.zip) — current version: v1.3.0 · Released Sept 2026 — unzip, then:
cd getmulticast-mcp-server
npm install
GETMULTICAST_API_KEY=gmc_live_... node index.js # test it starts cleanly
Then point your MCP client at it. For Claude Desktop, add to its config file (Settings → Developer → Edit Config):
{
"mcpServers": {
"getmulticast": {
"command": "node",
"args": ["/full/path/to/getmulticast-mcp-server/index.js"],
"env": { "GETMULTICAST_API_KEY": "gmc_live_..." }
}
}
}
/full/path/to/ with wherever you actually unzipped the file — that literal placeholder will fail. On Mac/Linux it typically looks like /Users/yourname/getmulticast-mcp-server/index.js; on Windows, C:\Users\yourname\getmulticast-mcp-server\index.js.Claude Code can use this local server too, if you'd rather run it yourself than use the remote URL above:
claude mcp add getmulticast \ --env GETMULTICAST_API_KEY=gmc_live_... \ -- node /full/path/to/getmulticast-mcp-server/index.js
Same rule applies — replace /full/path/to/ with your own real unzip location, same as above.
37 tools total, one per API endpoint on this page, verified against the real route table — once connected, ask your MCP client to list its tools, or just describe what you want done ("generate a video about our new product launch and post it to Instagram and TikTok," "what's in my review queue right now").
n8n community node
Two real nodes covering the whole API — published on npm as n8n-nodes-getmulticast — current version: v1.4.0 · Released Sept 2026. Install it directly from n8n: Settings → Community Nodes → Install → enter n8n-nodes-getmulticast. Source on GitHub; submitted to n8n for official Verified-node review.
GetMulticast (action node) covers every resource in this API — Video, Post (including Analytics), Comment, Pending Reply, Webhook, RSS Feed, Recycling Rule, Account, Credits. The Video resource (Create/Get/List/Delete) plays the same role Blotato's "Visual" resource plays in their own n8n node: generate an AI video, poll until it's ready, then feed the result into Post > Create — the same shape as Blotato's own "idea in Telegram → AI video → approve → publish everywhere" workflow templates.
GetMulticast Trigger (trigger node) starts a workflow on a real event (post.published, post.failed, comment.received, reply.sent) with full webhook lifecycle management — activating the workflow registers the webhook automatically (POST /webhooks), deactivating it removes the registration (DELETE /webhooks/{id}), and every delivery is HMAC-signature-verified before reaching your workflow. No manual URL-copying step, though n8n's own generic Webhook node still works too if you'd rather register the URL yourself.
Zapier
A Zapier integration isn't listed on the Zapier App Directory yet — that requires Zapier's own developer review process (their own account, their own submission/review cycle — the same shape as any platform app review). In the meantime, Zapier's built-in Webhooks by Zapier action/trigger works against this API directly with no custom app needed: use a "Custom Request" action for any endpoint on this page (set the Authorization header to your API key), and a "Catch Hook" trigger + this API's POST /webhooks to receive events in real time.
What's not here yet
Built honestly, not oversold — here's what v1 deliberately doesn't include yet:
- Analytics for Instagram, Facebook, Threads, LinkedIn, TikTok, and Google Business — see GET /posts/{id}/analytics above for exactly which permission each is missing (a real, specific gap, not a vague "coming soon"). YouTube, X, Pinterest, and Bluesky are real and live today.
- A published, listed Zapier app — the code path above (Webhooks by Zapier) works today without one.
Changelog
| Version | Date | Changes |
|---|---|---|
v1.1 | Sept 2026 | Added AI Video Generation — POST/GET /videos, GET/DELETE /videos/{id} — same engine as the dashboard's Generate Video button. MCP server bumped to v1.3.0 (37 tools). |
v1.0 | Sept 2026 | Initial public release — every endpoint on this page, all real, all live from day one. |
Questions or found a bug? support@getmulticast.com