ReferenceREST API functionssocialmutatesocial.draftPost

social.draftPost

Save a social post as a DRAFT for chosen connected accounts (zernioAccountId values from social.accounts), optionally with a placement per account, picture or video addresses (https) and a planned time so it sits on the Some calendar: when {day,time} (day is today, tomorrow, a weekday name in English or YYYY-MM-DD; nextWeek for the following week; time HH:MM) is resolved by the server in the workspace timezone, never worked out by you; or an exact plannedAt (ISO with offset). With no time given, propose one from social.week and say so; never guess. It publishes nothing: the person reads it and presses Publish in Selda. Placements per network: instagram feed|carousel|story|reel, facebook feed|story|reel, tiktok none (the media decides); other networks take none. A story, reel or carousel needs media.

RESTPOST /v1/social/draft-post
RPC formPOST /mcp/mutate with "fn": "social.draftPost"
Scopewrite
Sandbox keyallowed
Extra entitlementnone
MCP toolsnone, HTTP only
Internal functionsocial/posts:draftForKey

A free sandbox key may call it.

Arguments

ArgumentTypeRequiredNotes
projectIdid<"projects">required
contentstringrequired
accountIdsstring[]required
placementsobject[]optional
mediaUrlsstring[]optional
plannedAtstringoptional
when{ day: string; time?: string; nextWeek?: boolean }optional
timezonestringoptional

What Selda fills in

You never send these. The HTTP layer overwrites them from the API key, which is what keeps one organisation’s data out of another’s reach.

ArgumentFilled in from
orgIdyour organisation, resolved from the API key
userIdthe user the API key belongs to

Example request

Required arguments only. Values in angle brackets are yours to fill in; the optional ones are in the table above.

curl -X POST https://api.selda.ai/v1/social/draft-post \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "projectId": "<projectId>", "content": "<content>", "accountIds": ["<accountIds>"] }'
{
  "projectId": "<projectId>",
  "content": "<content>",
  "accountIds": ["<accountIds>"]
}

The same call in the RPC form

One dispatcher answers both, so this is the same request at a different URL. Use it when you are already posting to /mcp/*, or for a function that has no path of its own.

curl -X POST https://api.selda.ai/mcp/mutate \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "fn": "social.draftPost", "args": { "projectId": "<projectId>", "content": "<content>", "accountIds": ["<accountIds>"] } }'
{
  "fn": "social.draftPost",
  "args": {
    "projectId": "<projectId>",
    "content": "<content>",
    "accountIds": ["<accountIds>"]
  }
}

Example response

Every endpoint answers in the same envelope, whichever URL you called.

{
  "value": <the function's return value>,
  "request_id": "req_..."
}

The shape of value is not documented here. social/posts:draftForKey declares no returns validator, so there is nothing to derive it from, and a shape written out by hand here is a shape that goes stale without anything noticing. Call it once against a test key and read what comes back.

On failure the body is { "error": { "type", "code", "message", "request_id" }, "request_id" } and request_id is echoed in the X-Request-Id header.


Generated from convex/lib/mcpRegistry.ts. Nothing in this reference sends: launchRun is in no registry and never will be, so a script can prepare a campaign completely and a person still presses send in the app.