Schedule Posts with the Viraly API

Updated November 7, 2026

Schedule, reschedule and publish posts from your own code with the Viraly API. This guide takes you from an API key to a scheduled Instagram Reel in four requests, with the exact fields the API reference documents. If you would rather talk than code, the same tools are available to Claude, ChatGPT and Cursor through the MCP server.

What you need

  • A Viraly account with at least one connected channel (any plan; the API is included on every plan).
  • An API key with the posts:write and channels:read permissions. Create one in the Viraly app under Settings, then API keys. Keys start with vly_ and are shown once, so store the key where your code reads secrets.
  • The base URL https://api.viraly.io/api/v1. Every request sends the key as a Bearer token in the Authorization header and gets JSON back, with the result under data and a requestId under meta for support.

Step 1: find the channel to post to

Posts belong to a channel (a connected profile or page). List your channels once and keep the id of the one you want.

curl https://api.viraly.io/api/v1/channels \
  -H "Authorization: Bearer vly_your_key"

The response lists each channel with its id, name, platform and social set. Filter by a social set with ?social_set_id= when an account has several brands.

Step 2: create the post, scheduled

The shortest valid request is a channel, a caption and a time. Viraly builds the platform settings for the channel from the caption; postType picks the placement (Feed by default, Reel or Story on Facebook and Instagram, Short on YouTube). The time is ISO 8601; the timezone field names the IANA zone the time should be read in, so the post lands at 14:00 in New York rather than 14:00 UTC.

curl -X POST https://api.viraly.io/api/v1/posts \
  -H "Authorization: Bearer vly_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6d1c2f3a-reel-2026-04-15" \
  -d '{
    "channelId": "pQ2rS5tU",
    "caption": "Behind the scenes from today'"'"'s shoot",
    "postType": "Reel",
    "scheduledAt": "2026-04-15T14:00:00",
    "timezone": "America/New_York"
  }'

You get the post back with status: "Scheduled" and its id. Keep the id: the next two steps use it.

The Idempotency-Key header is optional and worth sending from any job that might retry: a repeat with the same key returns the first result instead of creating a second post, and media named by url is imported once. Media goes in a media array of urls (Viraly fetches them) or of media ids from the media endpoints; a Reel, Story or Short needs a video, and the API answers 400 with a plain error message when a platform and placement do not go together or a file breaks the network’s rules.

When you need the full composer settings

Send a config object instead of a top-level caption when you need what the composer offers: a first comment, a location, a Pinterest board, a LinkedIn document, platform-specific captions. The shape is the same the web app saves, documented per platform in the API reference, and a PUT /posts/{id} with a caption only patches the caption and leaves the rest of the config as it was.

Step 3: move it

Reschedule with a single call. The same timezone rule applies.

curl -X PUT https://api.viraly.io/api/v1/posts/x7Lp9Qr2/schedule \
  -H "Authorization: Bearer vly_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "scheduledAt": "2026-04-20T09:00:00", "timezone": "America/New_York" }'

Step 4: publish now, or delete

Publishing immediately is a separate call, so a scheduled post never goes out early by accident. The response says Publishing; read the post again a few seconds later for Published or Failed with the network’s reason.

curl -X POST https://api.viraly.io/api/v1/posts/x7Lp9Qr2/publish \
  -H "Authorization: Bearer vly_your_key"

DELETE /posts/{id} removes a draft or a scheduled post from Viraly. A published post cannot be deleted through the API, because deleting it in Viraly would not remove it from the network.

Reading what is scheduled

GET /posts lists posts with filters for socialSetId, channelId, status (Draft, PendingApproval, Scheduled, Published or Failed), a date range and a sort, 25 per page by default and up to 100. It is the call a dashboard or a nightly check uses to confirm that tomorrow is covered.

Limits and good manners

  • Plan limits apply exactly as in the web app: monthly posts, connected channels and AI quotas. A request past a limit answers 403 with a message that says which limit.
  • Rate limits apply per API key; back off on 429 and retry with the same Idempotency-Key.
  • Keys are scoped by permission, so a key that only needs to read should not carry posts:write. Revoke a key from the same settings page the moment it leaks.
  • Every change made through the API shows in the Viraly app like any other post, so your team sees what the integration did.

Frequently asked questions

Can I schedule posts with the Viraly API?

Yes. Create a post with a channel id, a caption and a scheduled time and it lands on the calendar as Scheduled, with the platform settings built for the channel. Reschedule it with one PUT, publish it immediately with one POST, or read it back at any time with GET /posts/{id}.

Which plans include the API?

Every plan includes the API, including Free, with the same limits your plan has in the web app: monthly posts, connected channels and AI quotas. You create a key under Settings, then API keys, choose its permissions and revoke it whenever you like; nothing else is needed.

Can I attach images or video through the API?

Yes. Put urls in the media array and Viraly fetches them, or upload first through the media endpoints and pass the media ids. Reels, Stories and Shorts need a video that meets the network’s rules, and the API answers 400 with a plain message when a file does not.

What happens if my job retries a request?

Send an Idempotency-Key header on create and update calls. A repeat with the same key returns the first result instead of creating a second post, and any media named by url is imported once. Without the header a retry creates a second post, so add it to any scheduled job.

Is there a way to do this without writing code?

Yes. The MCP server gives Claude, ChatGPT, Cursor and other MCP clients the same tools, so you can say “schedule this for Thursday at 11:00” in plain words. Zapier, Make and n8n integrations cover the common automations, and the WordPress plugin posts new blog articles for you.