Social

Social API

Post or schedule a video on Instagram, Facebook, TikTok and YouTube with one call. Pedra Pro only, no credits charged.

Post a video to Instagram, Facebook, TikTok and YouTube with one call, now or at a set time. Send a public MP4 URL and one entry per network with its caption and settings. Pedra stores the video, publishes it on each network and gives you a status for every post.

What you get from one call:

  • One video, four networks: Instagram (as a Reel), a Facebook Page, TikTok and YouTube, each with its own caption and settings.
  • Post now or schedule: leave out scheduledAt and the video goes out within about a minute, or pick any time up to 180 days ahead.
  • A status per post: list your posts to see what went out, the network's own post id and why anything failed. Cancel a scheduled post before it goes out.
  • Works from chat: the same endpoints are tools on the remote Pedra MCP server, so ChatGPT and Claude can schedule posts from a conversation.

Before you start

  • Pedra Pro only. Every call checks that the account is on the Pro plan. Other accounts get 403 pro_required. A scheduled post is only published if the account is still on Pro when it's due; if not, the post fails with an error.
  • Connect the accounts in the app. Social accounts are connected in Pedra under Settings › Socials, where you log in to each network. The API can't connect them. One account per network per Pedra user.
  • Supported networks: Instagram (a professional account, posted as a Reel), a Facebook Page, TikTok and YouTube. Video only for now.
  • No credits. Posting is free. The limit is 25 posts per network in any rolling 24 hours (429 daily_limit).

How it works

Three calls cover most integrations:

  1. Check: POST /api/social/accounts tells you which networks are connected.
  2. Post: POST /api/social/posts with a video URL and one entry per network. You get one post per network back, with status: "pending".
  3. Follow up: POST /api/social/posts/list shows each post's status. Once it's "posted", platformPostId holds the network's id.

The example schedules a vertical video for Instagram, TikTok and YouTube Shorts, tomorrow at 10:00 Madrid time.

# 1. Check which networks are connected
curl -X POST https://app.pedra.ai/api/social/accounts \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY" }'

# 2. Schedule the video for tomorrow at 10:00 Madrid time
curl -X POST https://app.pedra.ai/api/social/posts \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "videoUrl": "https://example.com/videos/calle-mayor-12.mp4",
    "scheduledAt": "2026-10-14T10:00:00+02:00",
    "timezone": "Europe/Madrid",
    "coverOffsetMs": 1000,
    "posts": [
      { "network": "instagram", "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio." },
      { "network": "tiktok", "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio.", "privacyLevel": "PUBLIC_TO_EVERYONE" },
      { "network": "youtube", "title": "Calle Mayor 12: 3-bed flat with terrace", "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio." }
    ]
  }'

# 3. Later: check how it went
curl -X POST https://app.pedra.ai/api/social/posts/list \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "limit": 10 }'

The Python and Node SDKs don't have social methods yet, so the samples use plain HTTP.

List connected accounts

POST/api/social/accounts

Returns every supported network and whether it's connected. account is the Instagram or TikTok username, or the Facebook Page name. YouTube doesn't share the channel name, so it's always null there.

apiKeystringrequired
Your API key.
curl -X POST https://app.pedra.ai/api/social/accounts \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY" }'

Response

JSON
{
  "accounts": [
    { "network": "instagram", "connected": true, "account": "pedra_ai" },
    { "network": "facebook", "connected": true, "account": "Pedra AI" },
    { "network": "tiktok", "connected": false, "account": null },
    { "network": "youtube", "connected": true, "account": null }
  ]
}

Post or schedule a video

POST/api/social/posts

Posts one video to one or more networks, now or at scheduledAt. Pedra first copies the video to its own storage (max 1 GB), so your URL only has to work during this call. A Pedra video URL (img.pedra.ai) is used as is. Each network can appear once in posts and has to be connected, or you get 400 not_connected.

apiKeystringrequired
Your API key.
videoUrlstringrequired
Public https URL of an MP4. Pedra copies it to its own storage (max 1 GB). A Pedra video URL (img.pedra.ai) is used as is.
scheduledAtstring
When to post, as an ISO 8601 date-time. Leave it out to post now (goes out within about a minute). Can't be in the past or more than 180 days ahead.
timezonestring
IANA timezone, e.g. Europe/Madrid. Stored for display only; the time itself comes from scheduledAt.
coverOffsetMsinteger
The cover frame on Instagram and TikTok, in milliseconds from the start of the video (0 to 600000). Ignored on Facebook and YouTube.
postsarrayrequired
One entry per network, at least one. Each network at most once.

Post entry

One object per network in posts. network and caption work the same everywhere; the other fields depend on the network and are listed below.

networkstringrequired
The network this entry is for.
Values: instagram facebook tiktok youtube
captionstring
Post text. On YouTube it's the description. Max 2,200 characters on Instagram and TikTok, 5,000 on YouTube.

Instagram

Posted as a Reel on the connected professional account. Only caption, max 2,200 characters.

Facebook

Posted to the connected Facebook Page.

videoTypestring
Post it as a Reel or as a regular feed video.
Values: REEL FEED
Default: REEL
firstCommentstring
Posted as the Page's first comment, for example a link. Max 8,000 characters.

TikTok

privacyLevel is required and has to be one the creator's account allows. caption max 2,200 characters.

privacyLevelstringrequired
Who can see the video. Has to be one the creator's account allows.
Values: PUBLIC_TO_EVERYONE MUTUAL_FOLLOW_FRIENDS FOLLOWER_OF_CREATOR SELF_ONLY
disableCommentboolean
Turn off comments.
disableDuetboolean
Turn off Duet.
disableStitchboolean
Turn off Stitch.
brandOrganicToggleboolean
The video promotes your own brand.
brandContentToggleboolean
Paid partnership. Not allowed with SELF_ONLY.
aiGeneratedboolean
TikTok's AI-generated content label. Set it to false only for real footage.
Default: true

YouTube

title is required. caption becomes the video description, max 5,000 characters. YouTube shows short vertical videos as Shorts.

titlestringrequired
Video title, max 100 characters. Title and caption can't contain < or >.
privacyStatusstring
Video visibility.
Values: public unlisted private
Default: public
categoryIdstring
YouTube category number, as a string (e.g. "22").
curl -X POST https://app.pedra.ai/api/social/posts \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "videoUrl": "https://example.com/videos/calle-mayor-12.mp4",
    "scheduledAt": "2026-10-14T10:00:00+02:00",
    "timezone": "Europe/Madrid",
    "coverOffsetMs": 1000,
    "posts": [
      {
        "network": "instagram",
        "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio."
      },
      {
        "network": "tiktok",
        "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio.",
        "privacyLevel": "PUBLIC_TO_EVERYONE",
        "brandOrganicToggle": true
      },
      {
        "network": "youtube",
        "title": "Calle Mayor 12: 3-bed flat with terrace",
        "caption": "3-bed flat with a sunny terrace on Calle Mayor 12. Book a visit, link in bio.",
        "privacyStatus": "public",
        "categoryId": "22"
      }
    ]
  }'

Response

JSON
{
  "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
  "videoUrl": "https://img.pedra.ai/social-videos/cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60.mp4",
  "posts": [
    {
      "postId": "KBkxMfAPARdEG4gix",
      "network": "instagram",
      "status": "pending",
      "scheduledAt": "2026-10-14T08:00:00.000Z",
      "postedAt": null,
      "platformPostId": null,
      "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
      "error": null
    },
    {
      "postId": "q3TzR8wYbN5cLm2Hd",
      "network": "tiktok",
      "status": "pending",
      "scheduledAt": "2026-10-14T08:00:00.000Z",
      "postedAt": null,
      "platformPostId": null,
      "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
      "error": null
    },
    {
      "postId": "Xe7pGv2sJk9WfA4Ru",
      "network": "youtube",
      "status": "pending",
      "scheduledAt": "2026-10-14T08:00:00.000Z",
      "postedAt": null,
      "platformPostId": null,
      "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
      "error": null
    }
  ]
}

List posts

POST/api/social/posts/list

Returns your posts, sorted by scheduledAt with the newest first. Filter by status, network and date to check what went out and why something failed.

apiKeystringrequired
Your API key.
statusstring
Only posts with this status.
Values: pending processing posted failed cancelled
networkstring
Only posts on this network.
Values: instagram facebook tiktok youtube
fromstring
Only posts with scheduledAt at or after this time (ISO 8601).
tostring
Only posts with scheduledAt at or before this time (ISO 8601).
limitinteger
How many posts to return, 1 to 100.
Default: 50

Post statuses

  • pending: waiting for its time. Only pending posts can be cancelled.
  • processing: being published right now.
  • posted: live on the network. postedAt and platformPostId are set.
  • failed: not published. error says why.
  • cancelled: cancelled before it went out.

Post object

Every endpoint that returns posts uses this shape.

postIdstring
Pedra's id for the post.
networkstring
The network.
Values: instagram facebook tiktok youtube
statusstring
See Post statuses above.
Values: pending processing posted failed cancelled
scheduledAtstring
When it's due, in UTC.
postedAtstring | null
When it went out, or null.
platformPostIdstring | null
The network's id once posted (e.g. the YouTube video id). For private TikTok posts, the publish id.
videoIdstring
The stored video, shared by all posts from the same call.
errorstring | null
Why it failed, or null.
firstCommentErrorstring
Only present when a Facebook first comment failed. The post itself still went out.
curl -X POST https://app.pedra.ai/api/social/posts/list \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "from": "2026-10-01T00:00:00Z",
    "limit": 20
  }'

Response

JSON
{
  "posts": [
    {
      "postId": "Xe7pGv2sJk9WfA4Ru",
      "network": "youtube",
      "status": "posted",
      "scheduledAt": "2026-10-14T08:00:00.000Z",
      "postedAt": "2026-10-14T08:00:41.000Z",
      "platformPostId": "k7Qm2LrT0aE",
      "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
      "error": null
    },
    {
      "postId": "q3TzR8wYbN5cLm2Hd",
      "network": "tiktok",
      "status": "failed",
      "scheduledAt": "2026-10-14T08:00:00.000Z",
      "postedAt": null,
      "platformPostId": null,
      "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
      "error": "TikTok rejected the post: the account was disconnected. Reconnect it under Settings > Socials."
    },
    {
      "postId": "Lw4nB8cVe2TyH6sPq",
      "network": "facebook",
      "status": "posted",
      "scheduledAt": "2026-10-10T16:30:00.000Z",
      "postedAt": "2026-10-10T16:30:52.000Z",
      "platformPostId": "1029384756102938",
      "videoId": "8b1d4e2f-7a3c-4f90-b5e6-2c9d0a1f3e47",
      "error": null,
      "firstCommentError": "Facebook didn't accept the comment."
    }
  ]
}

Cancel a scheduled post

POST/api/social/posts/cancel

Cancels a post that hasn't gone out yet. Only pending posts can be cancelled; anything else returns 409 not_cancellable. Each network's post is separate, so cancelling one leaves the others from the same call untouched.

apiKeystringrequired
Your API key.
postIdstringrequired
The post's id (from the posts or list call).
curl -X POST https://app.pedra.ai/api/social/posts/cancel \
  -H "Content-Type: application/json" \
  -d '{ "apiKey": "YOUR_API_KEY", "postId": "KBkxMfAPARdEG4gix" }'

Response

JSON
{
  "post": {
    "postId": "KBkxMfAPARdEG4gix",
    "network": "instagram",
    "status": "cancelled",
    "scheduledAt": "2026-10-14T08:00:00.000Z",
    "postedAt": null,
    "platformPostId": null,
    "videoId": "cf568771-4d2a-4e8b-9c3f-1a7e5b2d8f60",
    "error": null
  }
}

Errors

Errors come back as { "error": "...", "code": "..." }. Branch on code; error is a readable message. See Errors & limits for the general model.

  • 400: invalid_video_url (not a public https URL), video_unreachable (Pedra couldn't download it), not_a_video, video_too_large (over 1 GB), invalid_network, not_connected (connect it under Settings › Socials), invalid_post (the message names the network and the field), invalid_scheduled_at (not ISO 8601, in the past, or more than 180 days ahead), invalid_cover (coverOffsetMs isn't whole milliseconds between 0 and 600000).
  • 401 invalid_api_key: the API key is missing or wrong.
  • 403 pro_required: the account isn't on Pedra Pro.
  • 404 post_not_found: no post with that postId on this account.
  • 409 not_cancellable: the post is already posted, failed, processing or cancelled.
  • 429 daily_limit: that network already has 25 posts in the last 24 hours.

Next

Make the video first with the Video API (its URL is used as is), or schedule posts from ChatGPT or Claude with the MCP server.