Developers
Public publishing API
Upload media, create posts, and publish to Facebook, Instagram, 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).
TikTok is draft-first over the API.A TikTok post is always created as a draft in Markaestro. Explicit publish uses TikTok's inbox handoff, never public Direct Post, and the creator finalizes inside TikTok. Facebook, Instagram, LinkedIn, Threads, and Pinterest publish programmatically.
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.
/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 products with their connected accounts nested — a product-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. snake_case body: media, social_accounts, scheduled_at, is_draft; scheduling fields are accepted for compatibility and ignored.
/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 same account can appear under multiple products), 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 product, so it only sees and posts to that product. TikTok posts are created as drafts and finalized from the Markaestro app; Facebook, Instagram, 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 products plus the channels currently available for each one.
/api/public/v1/products/:id/destinationsLists the publish destinations for that product, 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 for the selected product destination.
/api/public/v1/posts/:idReturns current post status and publish results.
/api/public/v1/posts/:id/publishQueues an async publish run. Facebook, Instagram, LinkedIn, Threads, and Pinterest publish directly; TikTok uses the inbox handoff and still requires creator completion in TikTok.
/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"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"
}'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"
}'curl -X POST "$MARKAESTRO_URL/api/public/v1/posts/pst_123/publish" \
-H "Authorization: Bearer $MARKAESTRO_API_KEY" \
-H "Idempotency-Key: publish-001"{
"id": "evt_123",
"type": "post.action_required",
"createdAt": "2026-04-08T18:06:10.000Z",
"workspaceId": "ws_123",
"data": {
"postId": "pst_123",
"channel": "tiktok",
"status": "platform_action_required",
"externalId": "p_inbox_url~v2.7631796255831721997",
"nextAction": "open_tiktok_inbox_and_complete_posting"
}
}Text-only, image, or video posts. Up to 10 images or 1 video per post. Direct publish.
At least one image or video, up to 10 items. Single video publishes as a Reel. Carousels support mixed image/video.
TikTok
At least one image or video. Up to 10 images or 1 video. API posts are always created as drafts; explicit publish sends the draft to the creator's TikTok inbox, not 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.