Posts API

Create, schedule, and manage posts across all 10 supported platforms. The Posts API handles single posts, bulk creation, content validation, and retry logic for failed deliveries.

POST/api/v1/postsCreate or schedule a post
POST/api/v1/posts/bulkCreate multiple posts at once
GET/api/v1/postsList all posts
GET/api/v1/posts/:idGet post details
PATCH/api/v1/posts/:idUpdate a scheduled or draft post
DELETE/api/v1/posts/:idCancel or delete a post
POST/api/v1/posts/:id/retryRetry a failed post
POST/api/v1/posts/validateValidate content against platform limits

Create a post

POST/api/v1/postsCreate or schedule a post

Headers

Authorization
stringRequired

Bearer token. Example: Bearer sk_live_abc123...

Content-Type
stringRequired

Must be application/json

Idempotency-Key
stringOptional

Unique key to prevent duplicate posts. Recommended for all create operations.

Request body

content
stringOptional

Post text content. Character limits vary by platform. Optional for media-only posts.

platforms
arrayRequired

Array of platform targets. Each object must include platform and accountId. Optionally include a content field to override the top-level content for that platform.

mediaItems
arrayOptional

Array of media attachments. Each object has type ("image" or "video") and url (publicly accessible URL).

status
stringOptional

Post status.

Default: scheduled

draftscheduledimmediate
scheduledFor
stringOptional

ISO 8601 date for scheduling. Must be at least 5 minutes in the future and no more than 90 days ahead.

timezone
stringOptional

IANA timezone string (e.g. "America/New_York"). Used to interpret scheduledFor.

platformSettings
objectOptional

Platform-specific settings. Keys are platform names, values are setting objects (e.g. instagram.shareToFeed, twitter.replySettings).

publishNow
booleanOptional

Set to true to publish immediately, bypassing any schedule.

Default: false

queue
booleanOptional

Set to true to auto-schedule this post to the next available queue slot. Use instead of scheduledFor.

Default: false

Per-platform content: Each object in the platforms array can include a content field that overrides the top-level content for that specific platform. This lets you tailor messaging per network while creating a single post.

Queue integration: Instead of setting scheduledFor manually, pass "queue": true to automatically schedule the post into the next available queue slot. See the Queues API for details.

TikTok requires a privacy level. When you target tiktok, you must include platformSettings.tiktok.privacy. Valid values are PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, and SELF_ONLY, and the value must be enabled on the connected account. Posts are rejected at creation rather than published with a guessed privacy level.

# Publish immediately
schedulala post "Excited to announce our new feature!" --platforms twitter,linkedin,instagram --now
# Schedule for later
schedulala post "Excited to announce our new feature!" \
--platforms twitter,linkedin,instagram \
--schedule "2026-03-15T14:00:00Z"
# With media
schedulala post "Check it out" --platforms instagram \
--media "https://example.com/announcement.jpg" --now
# Platform-specific content
schedulala post "Default text" --platforms twitter,linkedin \
--platform-content '{"linkedin":{"content":"LinkedIn version"}}' --now
{
"success": true,
"post": {
"id": "67abc456def789012345cdef",
"status": "scheduled",
"content": "Excited to announce our new feature! Check it out at example.com",
"scheduledFor": "2026-03-15T14:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "pending"
},
{
"platform": "linkedin",
"accountId": "67abc123def4567890120002",
"status": "pending"
},
{
"platform": "instagram",
"accountId": "67abc123def4567890120003",
"status": "pending"
}
],
"createdAt": "2026-03-01T12:00:00.000Z"
}
}

Bulk create posts

POST/api/v1/posts/bulkCreate multiple posts at once

Create up to 25 posts in a single request. Each post in the array follows the same schema as the create post endpoint. The response includes a summary with per-post results so you can identify any failures.

Request body

posts
arrayRequired

Array of post objects (max 25). Each follows the same schema as POST /api/v1/posts.

timezone
stringOptional

Default timezone for all posts. Individual posts can override this.

curl -X POST https://schedulala.com/api/v1/posts/bulk \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: bulk_$(uuidgen)" \
-d '{
"timezone": "America/New_York",
"posts": [
{
"content": "Monday motivation! Start the week strong.",
"platforms": [{ "platform": "twitter", "accountId": "67abc123def4567890120001" }],
"scheduledFor": "2026-03-16T09:00:00Z"
},
{
"content": "Wednesday tip: consistency beats perfection.",
"platforms": [{ "platform": "twitter", "accountId": "67abc123def4567890120001" }],
"scheduledFor": "2026-03-18T09:00:00Z"
}
]
}'
{
"success": true,
"results": [
{
"index": 0,
"success": true,
"post": {
"id": "67abc456def789012345cd01",
"status": "scheduled",
"content": "Monday motivation! Start the week strong.",
"scheduledFor": "2026-03-16T09:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "pending"
}
],
"createdAt": "2026-03-01T12:00:00.000Z"
}
},
{
"index": 1,
"success": true,
"post": {
"id": "67abc456def789012345cd02",
"status": "scheduled",
"content": "Wednesday tip: consistency beats perfection.",
"scheduledFor": "2026-03-18T09:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "pending"
}
],
"createdAt": "2026-03-01T12:00:00.000Z"
}
}
],
"summary": {
"total": 2,
"succeeded": 2,
"failed": 0
}
}

List posts

GET/api/v1/postsList all posts

Retrieve a paginated list of your posts. Supports filtering by status, platform, profile, and date range. Results are returned in reverse chronological order.

Query parameters

status
stringOptional

Filter by post status.

draftscheduledimmediatepostedpartially_failedfailedcancelled
brandId
stringOptional

Filter by brand ID.

platform
stringOptional

Filter by platform name.

twitterinstagramfacebooklinkedintiktokthreadsblueskyyoutubepinteresttelegram
limit
numberOptional

Number of posts to return.

Default: 20

page
numberOptional

Page number for offset-based pagination.

Default: 1

after
stringOptional

Return posts scheduled after this ISO 8601 date.

before
stringOptional

Return posts scheduled before this ISO 8601 date.

# List all posts
schedulala post:list
# Filter by status
schedulala post:list --status scheduled --limit 10
{
"success": true,
"posts": [
{
"id": "67abc456def789012345cdef",
"status": "scheduled",
"content": "Excited to announce our new feature!",
"scheduledFor": "2026-03-15T14:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "pending"
}
],
"createdAt": "2026-03-01T12:00:00.000Z"
}
],
"pagination": {
"total": 45,
"page": 1,
"limit": 10,
"pages": 5,
"hasMore": true
}
}

Get post details

GET/api/v1/posts/:idGet post details

Retrieve full details for a single post, including per-platform delivery status. After a post is published, each platform entry includes the native postId, postUrl, and postedAt timestamp.

Path parameters

id
stringRequired

The post ID (e.g. 67abc456def789012345cdef).

schedulala post:status 67abc456def789012345cdef
# Watch until published or failed
schedulala post:status 67abc456def789012345cdef --watch
{
"success": true,
"post": {
"id": "67abc456def789012345cdef",
"status": "posted",
"content": "Excited to announce our new feature! Check it out at example.com",
"scheduledFor": "2026-03-15T14:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "posted",
"postId": "1897654321098765432",
"postUrl": "https://x.com/yourhandle/status/1897654321098765432",
"postedAt": "2026-03-15T14:00:05.000Z"
},
{
"platform": "linkedin",
"accountId": "67abc123def4567890120002",
"status": "posted",
"postId": "urn:li:share:7654321098765432100",
"postUrl": "https://www.linkedin.com/feed/update/urn:li:share:7654321098765432100",
"postedAt": "2026-03-15T14:00:08.000Z"
},
{
"platform": "instagram",
"accountId": "67abc123def4567890120003",
"status": "posted",
"postId": "17890012345678901",
"postUrl": "https://www.instagram.com/p/ABC123xyz/",
"postedAt": "2026-03-15T14:00:12.000Z"
}
],
"mediaItems": [
{
"type": "image",
"url": "https://example.com/announcement.jpg"
}
],
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-15T14:00:12.000Z"
}
}

Update a post

PATCH/api/v1/posts/:idUpdate a scheduled or draft post

Update a post that is in draft or scheduled status. Published, failed, and cancelled posts cannot be updated. Only include the fields you want to change — omitted fields are left unchanged.

Path parameters

id
stringRequired

The post ID to update.

Request body

content
stringOptional

Updated post text content.

platforms
arrayOptional

Updated platform targets.

mediaItems
arrayOptional

Updated media attachments.

scheduledFor
stringOptional

Updated schedule time (ISO 8601).

timezone
stringOptional

Updated timezone.

platformSettings
objectOptional

Updated platform-specific settings.

status
stringOptional

Change status (e.g. move a draft to scheduled).

draftscheduled
curl -X PATCH https://schedulala.com/api/v1/posts/67abc456def789012345cdef \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"content": "Updated announcement! Check out our new feature at example.com",
"scheduledFor": "2026-03-16T10:00:00Z"
}'
{
"success": true,
"post": {
"id": "67abc456def789012345cdef",
"status": "scheduled",
"content": "Updated announcement! Check out our new feature at example.com",
"scheduledFor": "2026-03-16T10:00:00.000Z",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "pending"
},
{
"platform": "linkedin",
"accountId": "67abc123def4567890120002",
"status": "pending"
},
{
"platform": "instagram",
"accountId": "67abc123def4567890120003",
"status": "pending"
}
],
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-01T13:30:00.000Z"
}
}

Delete a post

DELETE/api/v1/posts/:idCancel or delete a post

Cancel a scheduled or draft post. The post status is set to cancelled and it will not be published. Already-published posts cannot be deleted through this endpoint.

Path parameters

id
stringRequired

The post ID to cancel.

schedulala post:delete 67abc456def789012345cdef
{
"success": true,
"deleted": true,
"id": "67abc456def789012345cdef",
"method": "cancelled"
}

Retry a failed post

POST/api/v1/posts/:id/retryRetry a failed post

Retry delivery for a post with status failed or partially_failed. You can optionally specify which platforms to retry and add a delay before the retry attempt.

Path parameters

id
stringRequired

The post ID to retry.

Request body

platforms
arrayOptional

Array of platform names to retry. If omitted, all failed platforms are retried.

delay
numberOptional

Seconds to wait before retrying.

Default: 0

schedulala post:retry 67abc456def789012345cdef
{
"success": true,
"post": {
"id": "67abc456def789012345cdef",
"status": "scheduled",
"content": "Excited to announce our new feature! Check it out at example.com",
"platforms": [
{
"platform": "twitter",
"accountId": "67abc123def4567890120001",
"status": "posted",
"postId": "1897654321098765432",
"postUrl": "https://x.com/yourhandle/status/1897654321098765432",
"postedAt": "2026-03-15T14:00:05.000Z"
},
{
"platform": "instagram",
"accountId": "67abc123def4567890120003",
"status": "pending",
"previousError": "Media upload timeout"
}
]
},
"retriedPlatforms": [
"instagram"
]
}

Validate content

POST/api/v1/posts/validateValidate content against platform limits

Check whether your content meets each platform's requirements before creating a post. Returns per-platform validation results including character counts, media compatibility, and any errors.

Request body

content
stringRequired

The text content to validate.

platforms
arrayRequired

Array of platform name strings to validate against (e.g. ["twitter", "instagram", "tiktok"]).

mediaItems
arrayOptional

Array of media items to validate. Each has type and url.

curl -X POST https://schedulala.com/api/v1/posts/validate \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"content": "Check out our latest product update! We have been working hard to bring you the best experience possible.",
"platforms": ["twitter", "tiktok", "instagram"],
"mediaItems": [
{ "type": "image", "url": "https://example.com/product.jpg" }
]
}'
{
"success": true,
"validation": {
"isValid": false,
"platforms": {
"twitter": {
"valid": true,
"contentLength": 42,
"maxLength": 280,
"remainingCharacters": 238,
"mediaValid": true
},
"tiktok": {
"valid": false,
"errors": [
"TikTok requires a video. Image-only posts are not supported."
],
"mediaValid": false
},
"instagram": {
"valid": true,
"contentLength": 42,
"maxLength": 2200,
"remainingCharacters": 2158,
"mediaValid": true
}
}
}
}

Related