Manage Scheduled Posts
Schedule your uploads in advance and keep full control over them with our job management endpoints. This page covers how to list and cancel scheduled jobs created via the scheduled_date parameter.
List Scheduled Posts
| Endpoint | GET /api/uploadposts/schedule |
| Authentication | Required. Either an Apikey (Authorization: Apikey <token>) or a white-label profile JWT (Authorization: Bearer <profile_jwt>). |
| Query Params | All optional — see below. |
Query Parameters
| Param | Type | Description |
|---|---|---|
profile_username | string | Return only the jobs of this profile. |
from | string | ISO-8601 lower bound on scheduled_date, inclusive. |
to | string | ISO-8601 upper bound on scheduled_date, exclusive. |
limit | integer | Page size. Omit to return every matching job. |
offset | integer | Number of jobs to skip, ordered by scheduled_date ascending. Defaults to 0. |
Malformed from / to / limit / offset values are ignored rather than rejected.
When you authenticate with a profile JWT, results are restricted to that profile and the profile_username parameter is ignored. You cannot widen the scope past the profile the token was issued for.
curl "https://api.upload-post.com/api/uploadposts/schedule?profile_username=my_profile&from=2024-12-01T00:00:00Z&to=2025-01-01T00:00:00Z&limit=20" \
-H "Authorization: Apikey YOUR_API_KEY"
Success Response 200 OK
Returns an object containing the page of jobs plus its pagination metadata:
{
"scheduled_posts": [
{
"job_id": "a1b2c3d4e5f67890a1b2c3d4e5f67890",
"scheduled_date": "2024-12-25T10:30:00Z",
"post_type": "video",
"profile_username": "my_upload_post_profile",
"title": "Merry Christmas!",
"external_id": "clip-4821",
"source_filename": "christmas_cut_v3.mp4",
"platforms": ["tiktok", "instagram"],
"platform_content": {
"tiktok": { "title": "Merry Christmas!", "caption": "" },
"instagram": { "title": "Merry Christmas!", "caption": "Happy holidays" }
},
"has_preview": true,
"preview_url": null
}
],
"total": 42,
"limit": 20,
"offset": 0
}
| Field | Type | Description |
|---|---|---|
scheduled_posts | array | The requested page of scheduled-job objects. |
total | integer | Total number of jobs matching your filters, ignoring limit/offset. Use it to build a pager. |
limit | integer | null | The limit that was applied; null when you didn't send one. |
offset | integer | The offset that was applied. |
Each element of scheduled_posts contains:
| Field | Type | Description |
|---|---|---|
job_id | string | Unique identifier of the scheduled job. Required to edit or cancel it. |
scheduled_date | string | ISO-8601 date/time when the post will go live. Time is in UTC. |
post_type | string | One of video, photo, text, or unknown. |
profile_username | string | Upload-Post profile that will publish the content. |
title | string | Text shown in a calendar. For single-platform jobs this is the text that platform will actually publish. |
external_id | string | null | Your own identifier for this post, echoed back exactly as you sent it. See Correlating posts with your own system. |
source_filename | string | null | Original file name of the uploaded media, when the job was created from a file or a URL. null for text posts. |
caption / description | string | Generic caption and description stored with the job. |
platforms | array | Platforms the job will publish to. |
platform_content | object | Per-platform title / caption, falling back to the generic values. |
fields | object | The editable per-platform and global fields, as accepted by the PATCH endpoint. |
has_cover | boolean | Whether a cover image is stored for the job. |
cover_preview_url | string | null | Pre-stored cover URL, when one exists. |
has_preview | boolean | Whether a previewable video/photo asset exists for the job. |
preview_url | null | Always null — media URLs are signed on demand, see below. |
thumbnail_url | string | null | Stored thumbnail, when one exists. |
original_timezone | string | null | Timezone the job was originally scheduled in. |
original_scheduled_str | string | null | The original scheduled datetime string as submitted. |
Correlating posts with your own system
If you schedule from your own catalogue, you likely need to map a scheduled job back to the row it came from — to detect what you have already queued, or to show status next to your own records.
Do not match on title. It is editable, both through the PATCH endpoint and
in the dashboard calendar, so a post that gets retitled stops matching and looks
like it was never scheduled.
Send your own identifier as external_id when you create the post, and read it
back here:
curl -X POST https://api.upload-post.com/api/upload \
-H "Authorization: ApiKey YOUR_API_KEY" \
-F "user=my_profile" \
-F "platform[]=tiktok" \
-F "title=Merry Christmas!" \
-F "scheduled_date=2024-12-25T10:30:00Z" \
-F "external_id=clip-4821" \
-F "video=@christmas_cut_v3.mp4"
external_id accepts any string up to 255 characters. It can also be sent as an
X-External-Id header, which is handy when you cannot easily add form fields.
It is available on /api/upload, /api/upload_photos and /api/upload_text,
for both immediate and scheduled posts, and it is returned by
Upload Status and Upload History as
well as this endpoint.
external_id is a label, not a duplicate guardUpload-Post stores and returns external_id but never enforces anything with it.
Reusing one does not block a publish — that is deliberate, so a genuine
repost of the same asset still goes out.
If you want a request to be suppressed when it is accidentally sent twice, that
is a separate field: send an Idempotency-Key header, which collapses repeat
requests for 24 hours. The two are independent and can be used together.
Signing one URL per job made this endpoint time out for large schedules, so preview_url is no longer populated here. When has_preview is true, fetch the signed URL for that single job with GET /api/uploadposts/schedule/<job_id>/preview.
Error Responses
| Status | Reason |
|---|---|
401 Unauthorized | Missing or invalid token. |
Cancel a Scheduled Post
| Endpoint | DELETE /api/uploadposts/schedule/<job_id> |
| Authentication | Required. Either an Apikey (Authorization: Apikey <token>) or a white-label profile JWT (Authorization: Bearer <profile_jwt>). When authenticated with a profile JWT, the job must belong to that profile and the profile must have readonly_calendar: false. |
| URL Param | job_id — ID obtained from the list endpoint. |
Success Response 200 OK
{
"success": true,
"message": "Job <job_id> cancelled and assets deleted."
}
Error Responses
| Status | Body | Condition |
|---|---|---|
401 Unauthorized | Invalid or missing token. | |
404 Not Found | { "success": false, "error": "Job not found" } | The supplied job_id does not exist or doesn't belong to the authenticated user. |
500 Internal Server Error | Unexpected failure while cancelling the job or deleting its assets. |
Edit a Scheduled Post
| Endpoint | PATCH /api/uploadposts/schedule/<job_id> |
| Authentication | Required. Either an Apikey (Authorization: Apikey <token>) or a white-label profile JWT (Authorization: Bearer <profile_jwt>). When authenticated with a profile JWT, the job must belong to that profile and the profile must have readonly_calendar: false. |
| URL Param | job_id — ID obtained from the list endpoint. |
| Body | JSON object with one or more of the fields below. |
| Field | Type | Required | Description |
|---|---|---|---|
scheduled_date | string | No | ISO-8601 date/time, e.g., "2025-10-05T10:30:00Z". Must be in the future and within 1 year. Interpreted as UTC unless timezone is provided. |
timezone | string | No | IANA timezone identifier (e.g., "Europe/Madrid", "America/New_York"). If provided, scheduled_date is interpreted in this timezone. Defaults to UTC if omitted. See IANA Time Zone Database. |
title | string | No | New post title/caption. |
caption | string | No | New caption/description. |
Success Response 200 OK
{
"success": true,
"job_id": "a1b2c3d4e5f67890a1b2c3d4e5f67890",
"scheduled_date": "2025-10-05T10:30:00Z",
"title": "Updated title",
"caption": "Updated caption"
}
Error Responses
| Status | Body | Condition |
|---|---|---|
400 Bad Request | { "success": false, "error": "<reason>" } | Invalid body; invalid/past date; job not editable; daily limit reached. |
401 Unauthorized | Invalid or missing token. | |
403 Forbidden | { "success": false, "error": "Forbidden" } | The job does not belong to the authenticated user, or the profile JWT does not match the job's profile. |
403 Forbidden | { "success": false, "message": "This calendar is read-only…", "error_code": "READONLY_CALENDAR" } | Authenticated with a profile JWT for a profile that has readonly_calendar: true. |
404 Not Found | { "success": false, "error": "Job not found" } | The supplied job_id does not exist. |
500 Internal Server Error | Unexpected failure while editing the job. |
Example Request
curl -X PATCH "https://api.upload-post.com/api/uploadposts/schedule/JOB_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Apikey <token>" \
-d '{
"scheduled_date": "2025-10-05T10:30:00",
"timezone": "Europe/Madrid",
"title": "Updated title",
"caption": "Updated caption"
}'
See Also
- Using
scheduled_datewhen uploading content – parameter description. - Upload Video, Upload Photos, Upload Text – endpoints that support scheduling.
- Upload Status – Check the execution status of scheduled posts using the
job_id.