Developers
Public publishing API
Upload media, create posts, and publish to Facebook, Instagram, TikTok, LinkedIn, Threads, and Pinterest, all scoped to a product via a workspace API key. The recommended way to integrate is the Connect API — a small, flat/api/connect/v1 surface that most scheduling tools can target as-is.
Need full control — explicit publish, job-run polling, signed webhooks, batch, per-channel settings? The advanced /api/public/v1 API further down exposes all of it. Both share the same auth, products, and publishing pipeline; use only these versioned public routes (internal app routes require Firebase user auth and are not part of the public contract).
Facebook, Instagram, and TikTok are manual-first over the API. Posts for those channels default to manual_reminder delivery: Markaestro never calls the platform's API for them. Publishing moves the post to the workspace's To Post queue, where the owner downloads the media, posts natively, and confirms — so posts appear exactly as if created by hand. Pass deliveryMode: "direct_publish" on create to opt a post into official-API publishing instead (on TikTok that means the inbox handoff, never public Direct Post). LinkedIn, Threads, and Pinterest publish programmatically by default.
Workspaces can have multiple products. Every API key is bound to one product when you create it, so calls target that product automatically and requests for any other product are rejected.
Building an AI agent?
Start with the AI agent guide instead. It has copy-paste tool schemas, a system-prompt brief, the retry and error-handling rules an agent needs, and a four-command quickstart. Your agent can also read /llms.txt directly.
/api/connect/v1 that most scheduling tools can target as-is. It maps the common create-upload-url → PUT → post convention onto the same workspace, auth, products, and publishing pipeline as the full API below. Set the client base URL to /api/connect and authenticate with a product-scoped workspace API key (scopes posts.read, posts.write, media.write)./api/connect/v1/social-accountsLists connected Facebook, Instagram, TikTok, LinkedIn, and Threads destinations as flat accounts, each labeled with its product so clients can group and disambiguate. Each channel is its own dedicated path — no cross-channel fan-out.
/api/connect/v1/productsLists brands (wire name: products) with their connected accounts nested — a brand-first picker.
/api/connect/v1/media/create-upload-urlReturns a short-lived, single-use signed PUT url plus a media id.
<upload_url>Upload the raw image bytes to the signed url. No API key needed — the signature authorizes it.
/api/connect/v1/postsCreates a draft per selected account. Set is_draft=false with scheduled_at to schedule delivery; TikTok uses the creator-inbox handoff.
/api/connect/v1/postsLists workspace posts with flat status, caption, and media urls.
# 1. List connected accounts
curl "$MARKAESTRO_URL/api/connect/v1/social-accounts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"
# 2. Request a signed upload url, then PUT the bytes
curl -X POST "$MARKAESTRO_URL/api/connect/v1/media/create-upload-url" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "mime_type": "image/png", "size_bytes": 184320, "name": "slide-1.png" }'
curl -X PUT "<upload_url>" -H "Content-Type: image/png" --data-binary @slide-1.png
# 3. Create a draft post for one or more accounts
curl -X POST "$MARKAESTRO_URL/api/connect/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"caption": "New drop",
"media": ["ast_111", "ast_222"],
"social_accounts": ["prod_123#instagram:instagram:ig_123"]
}'Each account from /social-accounts is labeled with its product — the wire-format name for a brand (the same account can appear under multiple brands) — and its id encodes productId#destinationId — pass it back verbatim in social_accounts, and the request fans out one post per account. Each key is bound to one brand, so it only sees and posts to that brand. Facebook, Instagram, and TikTok posts are manual-first — created as drafts and published natively by the workspace owner from the Markaestro To Post queue, never via the platform's API. LinkedIn, Threads, and Pinterest publish programmatically after an explicit publish action. Post status is one of draft, processing, posted, or failed. Facebook, Instagram, LinkedIn, TikTok, and Threads are each their own dedicated destination — publishing to one never fans out to another. Track publishing state through GET /api/connect/v1/posts.
Advanced: full Public API
The complete /api/public/v1 surface — explicit publish, async job runs, signed webhooks, batch create, and per-channel settings. Use it when the Connect API is not enough.
/api/public/v1/productsLists the key's brands plus the channels currently available for each one.
/api/public/v1/products/:id/destinationsLists the publish destinations for that brand, including standalone Instagram Login, Facebook Page, Threads, LinkedIn Profile/Page, and connected TikTok destinations.
/api/public/v1/mediaMultipart upload. Returns an asset id and hosted URL.
/api/public/v1/postsCreates a draft in the workspace. Facebook, Instagram, and TikTok default to manual posting (deliveryMode manual_reminder); pass deliveryMode direct_publish to opt a post into API publishing.
/api/public/v1/postsLists posts, newest first. Filter with ?status=scheduled to see what is queued, and ?productId= to scope to one brand. A brand-bound key is always limited to its own brand and may omit productId.
/api/public/v1/posts/:idReturns current post status, delivery mode, and publish results.
/api/public/v1/posts/:id/publishQueues an async publish run. Manual posts land in the workspace's To Post queue for native posting; LinkedIn, Threads, and Pinterest publish directly; opted-in Meta posts publish via the official API, and opted-in TikTok posts use the inbox handoff.
/api/public/v1/posts/:idDeletes the post from Markaestro. Uses the existing posts.write scope. Returns 400 VALIDATION_POST_IS_PUBLISHING while a publish run is in flight. Deleting a published post does not retract the live platform copy.
/api/public/v1/job-runs/:idReturns queued, running, succeeded, or failed.
/api/public/v1/webhook-endpointsRegisters a webhook destination using an API key.
/api/public/v1/webhook-endpointsLists registered webhook destinations for that API key scope.
/api/public/v1/webhook-endpoints/:idDisables a webhook destination.
curl "$MARKAESTRO_URL/api/public/v1/products" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"destinationId when a product has multiple destinations, such as a LinkedIn Profile plus Pages.curl "$MARKAESTRO_URL/api/public/v1/products/prod_123/destinations" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"curl -X POST "$MARKAESTRO_URL/api/public/v1/media" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Idempotency-Key: upload-001" \
-F "file=@launch-1.jpg""deliveryMode": "direct_publish" to opt this post into official-API publishing.curl -X POST "$MARKAESTRO_URL/api/public/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: post-001" \
-d '{
"channel": "instagram",
"caption": "Launch day carousel",
"mediaAssetIds": ["ast_123", "ast_124"],
"productId": "prod_123",
"destinationId": "instagram:instagram:ig_123"
}'deliveryMode: "platform_inbox" (or direct_publish), an explicit publish sends the draft to the creator's TikTok inbox instead.curl -X POST "$MARKAESTRO_URL/api/public/v1/posts" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: post-tt-001" \
-d '{
"channel": "tiktok",
"caption": "Spring drop teaser",
"mediaAssetIds": ["ast_vid_123"],
"productId": "prod_123",
"destinationId": "tiktok:tiktok:tt_open_123"
}'post.action_required; LinkedIn, Threads, Pinterest, and opted-in Meta posts publish directly; opted-in TikTok posts queue the inbox handoff.curl -X POST "$MARKAESTRO_URL/api/public/v1/posts/pst_123/publish" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Idempotency-Key: publish-001"posts.read and posts.write.# What is scheduled for one brand
curl "$MARKAESTRO_URL/api/public/v1/posts?status=scheduled&productId=prod_123&limit=100" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"
# Omit productId to see every brand the key can reach
curl "$MARKAESTRO_URL/api/public/v1/posts?status=scheduled" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"
# Cancel one
curl -X DELETE "$MARKAESTRO_URL/api/public/v1/posts/pst_123" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY"{
"id": "evt_123",
"type": "post.action_required",
"createdAt": "2026-04-08T18:06:10.000Z",
"workspaceId": "ws_123",
"data": {
"postId": "pst_123",
"channel": "instagram",
"status": "platform_action_required",
"nextAction": "post_manually_from_reminder"
}
}Text-only, image, or video posts. Up to 10 images or 1 video per post. Manual posting by default; direct publish on opt-in.
At least one image or video, up to 10 items. Single video publishes as a Reel. Manual posting by default; direct publish on opt-in.
TikTok
At least one image or video. Up to 10 images or 1 video. Manual posting by default; opted-in posts go to the creator's TikTok inbox, never public Direct Post.
Text, single image, single video, or organic multi-image posts up to 20 images. Target either the connected Profile or a managed Page.