Posts
Create, schedule, list, update, and delete posts across your connected social media accounts.
Create Post
Create a new post and either schedule it for later, publish it immediately, or save it as a draft. A single request can target multiple platforms and accounts simultaneously.
/v1/postsCreate and schedule a postRequest Body
| Parameter | Type | Description |
|---|---|---|
type | string | "schedule", "now", or "draft". Determines when the post is published. |
caption | string | Post caption/text. Max 5,000 characters. Platform-specific limits may apply (see Platform Settings). Can be left out if the post has media: Instagram, YouTube, TikTok and Pinterest always need media (YouTube a video), and the other platforms need text or media. A post without what a platform needs is still accepted, but fails on that platform when it publishes; a Pinterest post without a photo or a video is refused before it is saved. |
scheduled_at | string | ISO 8601 UTC datetime for scheduling. Required when type is "schedule". |
media_ids | string[] | Array of media file IDs from the Upload endpoint. See media rules below. |
account_ids | string[] | Array of connected account IDs to post to. Get these from the Accounts endpoint. A workspace can hold several accounts of one platform (two Instagram accounts, say): each has its own ID. |
platform_settings | object | Per-platform settings keyed by platform identifier, for every account of that platform in the post. See Platform Settings section. Every platform also accepts a `caption` here, which replaces the main caption on that platform and is checked against that platform's limit. |
account_settings | object | Settings for single accounts, keyed by account ID: the same fields platform_settings takes for that account's platform, caption included. An account with an entry here publishes with it instead of its platform's platform_settings entry (the two are never merged), so put every setting it needs in it. Each key must be one of the post's account_ids. |
Headers
| Parameter | Type | Description |
|---|---|---|
Idempotency-Key | string | Up to 255 chars. Replaying the same key with the same workspace returns the original post instead of creating a duplicate. |
X-Workspace-Id | string | Required when using an all-scope API key. The workspace this post belongs to. |
Idempotency-Key is scoped per (user, workspace)
Replaying an Idempotency-Key that was already used in another workspace returns 409 VALIDATION_ERROR with "Idempotency-Key already used for a different workspace". This is intentional defense for users with multiple keys (e.g. one workspace-scoped key + one all-scope key). Replays should hit the original workspace, not bleed into a different one. Generate a fresh key per workspace, or scope the key string with a workspace prefix.
Media Rules (enforced across all platforms)
- • Maximum 10 images or 1 video per post (X limited to 4 images, Pinterest to 5)
- • You cannot mix images and videos in the same post
- • Images: JPEG or PNG, max 25 MB per file
- • Videos: MP4 or MOV, max 500 MB per file
- • Each file's format and size are checked against every selected platform before the post is saved (Bluesky photos, for example, are 2 MB at most, and Telegram videos 50 MB), and so is each platform's caption length. Other platform rules, like YouTube needing a video, are checked when the post publishes
- • Instagram + 10-bit (HDR) video is rejected at creation with 400 VALIDATION_ERROR. Re-export as standard 8-bit H.264, or drop the Instagram account; the other platforms accept the video as-is
- • No daily cap on posts, except on X: each X (Twitter) account takes up to 5 posts a day (scheduled, posting and published ones count) because the X API is metered
- • Posts can be scheduled up to 90 days in advance
- • An account that is paused (its owner has more channels than their plan includes) returns 400 CHANNEL_PAUSED. See Paused accounts
See Platform Settings for per-platform media constraints.
Example Request
curl -X POST https://api.quegly.com/v1/posts \
-H "Authorization: qgl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "schedule",
"scheduled_at": "2026-06-01T14:00:00.000Z",
"caption": "Check out this amazing transformation! #design #homedecor",
"media_ids": [
"e639003b-f727-4a1e-87bd-74a2c48ae41e",
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
],
"account_ids": [
"instagram-account-id",
"tiktok-account-id"
],
"platform_settings": {
"tiktok": {
"caption": "TikTok-specific caption with different hashtags #fyp #design",
"privacy_level": "PUBLIC_TO_EVERYONE",
"allow_comment": true,
"allow_duet": true,
"allow_stitch": true
}
}
}'Two accounts of one platform
platform_settings.<platform> applies to every account of that platform in the post. To give one account settings of its own, put them in account_settings under its ID. Here two Pinterest accounts post the same photo, each to a board of its own:
{
"type": "schedule",
"scheduled_at": "2026-06-01T14:00:00.000Z",
"caption": "Ten summer salads for busy weeknights",
"media_ids": ["e639003b-f727-4a1e-87bd-74a2c48ae41e"],
"account_ids": ["pinterest-account-a", "pinterest-account-b"],
"account_settings": {
"pinterest-account-a": { "board_id": "549755885175" },
"pinterest-account-b": { "board_id": "549755885299", "title": "Summer salads" }
}
}Response
{
"id": "post-abc123",
"status": "scheduled",
"scheduled_at": "2026-06-01T14:00:00.000Z",
"caption": "Check out this amazing transformation! #design #homedecor",
"platforms": ["instagram", "tiktok"],
"media": [
{ "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e", "media_type": "image" },
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "media_type": "image" }
],
"created_at": "2026-05-15T12:00:00.000Z"
}List Posts
Retrieve posts within a date range. Returns both scheduled and published posts.
/v1/postsList posts by date rangeQuery Parameters
| Parameter | Type | Description |
|---|---|---|
start_date | string | Range start, ISO 8601 UTC (e.g. 2026-06-01T00:00:00.000Z) |
end_date | string | Range end, ISO 8601 UTC (e.g. 2026-06-30T23:59:59.000Z) |
Example
curl "https://api.quegly.com/v1/posts?start_date=2026-06-01T00:00:00.000Z&end_date=2026-06-30T23:59:59.000Z" \
-H "Authorization: qgl_your_api_key"{
"posts": [
{
"id": "post-abc123",
"caption": "Check out this transformation!",
"status": "posted",
"scheduled_at": "2026-06-01T14:00:00.000Z",
"platforms": [
{
"account_id": "instagram-account-id",
"platform": "instagram",
"status": "posted",
"post_url": "https://www.instagram.com/p/abc123"
}
],
"media": [...]
}
]
}Get Post
Retrieve a single post by ID, including its platform statuses, media, settings (platform_settings, and account_settings for accounts with their own) and any error messages.
/v1/posts/{id}Get a single postPath Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
curl https://api.quegly.com/v1/posts/post-abc123 \
-H "Authorization: qgl_your_api_key"Update Post
Update a scheduled post. Only posts with status scheduled or incomplete can be updated. Published posts cannot be modified.
/v1/posts/{id}Update a scheduled postPath Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Request Body (all fields optional)
| Parameter | Type | Description |
|---|---|---|
caption | string | Updated caption text |
scheduled_at | string | Updated schedule time (ISO 8601 UTC) |
media_ids | string[] | Replace media attachments |
account_ids | string[] | Replace target accounts |
platform_settings | object | Replace the post's per-platform settings, whole: send every setting it should keep (Get Post returns them) |
account_settings | object | Replace the post's per-account settings, whole, keyed by account ID |
platform_settings sent without account_settings also clears the own settings of every account on a platform whose settings it changes, so those accounts post with the new ones; send account_settings in the same call to keep or set an account's own.
While one of the post's accounts is paused, every update returns 400 CHANNEL_PAUSED until account_ids leaves it out.
curl -X PUT https://api.quegly.com/v1/posts/post-abc123 \
-H "Authorization: qgl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"scheduled_at": "2026-06-02T16:00:00.000Z",
"caption": "Updated caption with new hashtags #interior #decor"
}'Delete Post
Delete a scheduled post. Posts whose scheduled time has already passed cannot be deleted via the API (matching the dashboard behavior).
/v1/posts/{id}Delete a postPath Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID to delete |
curl -X DELETE https://api.quegly.com/v1/posts/post-abc123 \
-H "Authorization: qgl_your_api_key"{
"id": "post-abc123",
"deleted": true
}Publish Now
Immediately publish a scheduled post, bypassing its scheduled time. Idempotent: if the post is already posted/partial, the current state is returned.
/v1/posts/{id}/publish-nowPublish a post immediatelyPath Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID to publish |
curl -X POST https://api.quegly.com/v1/posts/post-abc123/publish-now \
-H "Authorization: qgl_your_api_key"{
"id": "post-abc123",
"status": "posting",
"message": "Post is being published to all platforms"
}Publishing is asynchronous. The response confirms the publish was triggered. Poll Get Post for the final per-platform status (posted, partial, or failed).
Post Statuses
| Status | Description |
|---|---|
incomplete | Post is being created. Missing required fields (media, accounts, or schedule time) |
scheduled | Post is complete and queued for publishing at the scheduled time |
posting | Post is currently being published to platforms |
posted | Successfully published to all target platforms |
partial | Published to some platforms but failed on others |
failed | Failed to publish on all platforms |