REST drafts, publishing, and scheduling
These endpoints extend the five read endpoints with 14 operations, for 19 website API-key operations in total. They use ordinary HTTP, not MCP tool calls. API-key MCP still offers only its calendar-reading tool; these REST additions do not expand it.
Availability: the website and NestJS backend must both contain the matching REST changes. The latest composer-style draft revision has not yet completed compilation or authenticated end-to-end verification. Confirm it in your environment before relying on it in production.
Authentication and request setup
Call the YouScaleIt website origin, followed by the full path in this reference. Do not call the backend host or add /v1.
- Production website origin:
https://youscale.it, after deployment. - Local example:
https://local.exiiit.com:5173, with your local server running and a trusted certificate. - Header:
x-youscaleit-api-key: YOUR_API_KEY. - JSON request bodies:
Content-Type: application/json.
The examples use full website URLs and $YOUSCALEIT_API_KEY, set to your key in your terminal or secret storage. For local development, replace https://youscale.it with your local website origin. Never share real keys in commands, logs, or support messages.
Each example is a direct cURL command. No helper function or ID setup commands are needed. Replace example IDs, usernames, and dates before running; scheduling dates must be in the future.
Run examples individually. Publishing, reposting, and scheduling perform real actions. Replace all example identifiers and destination usernames with actual values from your workspace. Do not execute every example as a single script.
Endpoint overview
| Operation | Method | Website path |
|---|---|---|
| Create draft | POST | /api/profile/drafts |
| Edit draft | PATCH | /api/profile/drafts/:postId |
| List saved social destinations | GET | /api/profile/social-connections |
| Create saved auto-comment | POST | /api/profile/auto-comments/add |
| Publish post now | POST | /api/profile/posts/publish |
| Read publishing status | GET | /api/profile/publishing-status/:jobId |
| Schedule post | POST | /api/profile/scheduled-posts |
| Reschedule post | PATCH | /api/profile/scheduled-posts/:scheduleId |
| Cancel scheduled post | POST | /api/profile/scheduled-posts/:scheduleId/cancel |
| Repost publication now | POST | /api/profile/reposts/publish |
| Schedule repost | POST | /api/profile/scheduled-reposts |
| List repost schedules for a post | GET | /api/profile/posts/:postId/repost-schedules |
| Reschedule repost | PATCH | /api/profile/scheduled-reposts/:scheduleId |
| Cancel scheduled repost | POST | /api/profile/scheduled-reposts/:scheduleId/cancel |
The 13 shared action routes (all rows except saved auto-comment creation) reject query parameters and unknown JSON fields, bound request bodies to 2 MiB, and return private responses with Cache-Control: no-store. The existing auto-comment creation route has its own behavior described below.
All support the existing session-or-key selection: a browser session takes priority if both are present. Shared action writes authenticated by a browser session require an Origin matching the website origin. For API-key checks, use a client without browser cookies. These operations are scoped to the authenticated workspace; do not supply an owner or workspace ID.
Create and edit drafts
REST drafts follow the Create page’s content model. They are ordinary posts in draft status, not the separate older simple-draft records.
Request fields
| Field | Meaning |
|---|---|
title | Required for creation and editing. Trimmed, 1–300 characters. |
isPostUnified | Required boolean. true stores shared content; false uses platform-specific objects. |
status | Optional; only DRAFT is accepted. This is not a publishing control. |
content | Optional parent text, at most 50,000 characters; null is accepted. In unified mode this is the shared text. |
imageUrl, videoUrl | Optional existing HTTPS media references, at most 2,048 characters each. Null or an empty string can clear a value. |
carouselImagesUrl | Optional array of up to 20 existing HTTPS URLs; null or an empty array can clear it. URLs must not contain commas. |
linkedinPost, xPost, blueskyPost, instagramPost, facebookPost, threadsPost, tiktokPost, youtubePost | Optional named platform objects for per-platform content. |
Platform objects accept content, the three media fields, and noMedia. The legacy media field accepts only null for clearing. X and Bluesky also accept threads: up to 100 strings, at most 50,000 characters in total. Use nonblank thread segments and respect the provider’s publishing limits; draft-storage limits are not publication limits.
URLs must not contain embedded usernames/passwords, fragments, whitespace, or backslashes. These endpoints accept references only: they do not upload local files. Publishing additionally requires media to be within the configured trusted HTTPS storage location; an arbitrary URL accepted for draft storage can still fail publication.
Do not send the earlier agent-style isUnified, platforms, or socials request fields. The REST mode field is isPostUnified. Responses use the stored name isUnified.
Create shared content
curl -X POST "https://youscale.it/api/profile/drafts" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"title": "Shared draft",
"isPostUnified": true,
"content": "The same content for all platforms."
}' No platform list is required. Unified describes shared content, not automatic publishing to all connected accounts. You choose a platform and destination later when publishing or scheduling.
A successful response is HTTP 200 with {"success":true,"data":{...}}. data is the filtered post representation described in post fields, including the post ID and named platform objects. Creation and editing use the same response shape. Use the returned data.id in later requests.
Replace 24 with your actual returned ID. Creating a draft does not publish or schedule anything.
Edit or switch to per-platform content
curl -X PATCH "https://youscale.it/api/profile/drafts/24" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"title": "Updated draft",
"isPostUnified": false,
"linkedinPost": {
"content": "A longer professional update for LinkedIn."
},
"xPost": {
"content": "A shorter update for X."
}
}' Use the same body with POST /api/profile/drafts to create a separate new per-platform draft instead.
The draft ID stays unchanged during editing. Unlike MCP draft editing, REST permits mode changes and does not enforce a fixed platform set. Ownership is still checked. Posts with published/non-draft variants, publication history, pending publication schedules, or active publishing jobs are not eligible for these draft edits.
X thread
curl -X PATCH "https://youscale.it/api/profile/drafts/24" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"title": "My X thread",
"isPostUnified": false,
"xPost": {
"threads": [
"1/ Here is what we learned while building our product.",
"2/ Start small and listen to feedback.",
"3/ Improve what people use before adding more features."
]
}
}' Each string is one segment, in order. Send threads instead of single-post X content. Use blueskyPost.threads for Bluesky threads. A nonempty thread array takes precedence over the submitted platform text. Supplying platform content without threads clears existing threads; use null or an empty array to clear threads explicitly.
Switch back to unified mode
curl -X PATCH "https://youscale.it/api/profile/drafts/24" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"title": "Unified draft again",
"isPostUnified": true,
"content": "One shared version for all platforms."
}' Editing and media semantics
- Switching from unified to per-platform seeds empty platform text from the previously saved shared text and copies shared media. Submitted platform fields override those defaults. Unspecified platforms are not a destination-selection mechanism.
- When already per-platform, omitted fields on existing variants are preserved, apart from the legacy media reset. New platform records are initialized from parent defaults before applying submitted fields.
- Parent fields omitted from the request are preserved. Explicit null/empty supported values clear them. Parent content/media can remain stored while the draft is per-platform, as in the composer.
- Switching to unified resets platform-specific text, media overrides, and X/Bluesky threads. Omitted parent values remain stored; provide the shared content/media you actually intend to use. This REST request does not display the UI’s confirmation dialog or automatically choose between differing platform attachments.
noMedia: trueon a per-platform object clears that variant’s media and prevents parent-media fallback. To attach media again, supply the appropriate media fields andnoMedia: false; clear obsolete media fields when changing media type.- Parent and platform changes are saved in one database transaction. This is not an idempotency guarantee for repeated requests and does not remove the need to check publication state before retrying.
Discover saved social destinations
curl "https://youscale.it/api/profile/social-connections" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" Returns an array in data. Each entry contains type, platform, id, username, name, imageUrl, source, parentAccount, parentAccountPresent, and verification. Some identity fields can be null. verification is not_live_verified: saved accounts may still need reconnection before publication.
No credentials are returned. Use an account entry’s actual username, not its display name. Company/page entries identify their connected parent account separately.
Destination formats
Personal account:
{ "type": "account", "accountUsername": "YOUR_CONNECTED_USERNAME" } LinkedIn company:
{ "type": "company", "id": "urn:li:organization:123456", "accountUsername": "YOUR_CONNECTED_USERNAME" } Facebook page:
{ "type": "page", "id": "fb:page:123456", "accountUsername": "YOUR_CONNECTED_USERNAME" } Replace sample IDs with values returned by discovery. For a company/page, use the parent account’s username. Facebook requires a page destination; LinkedIn supports accounts or companies; other platforms use accounts. Selecting a destination does not grant access to a resource outside the workspace.
Create a saved auto-comment
curl -X POST "https://youscale.it/api/profile/auto-comments/add" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"title": "More information",
"content": "Read the full article on our website.",
"social": "LINKEDIN"
}' Title and content are strings of at least two characters. social is optional/nullable and uses uppercase platform values, unlike the lowercase platform in publication requests. This saves an auto-comment; it does not post a comment on a social network.
Success returns HTTP 200 and success: true, with the saved ID, title, content, and social in data; a type field may also be present. List saved comments through the auto-comment read endpoint. Creation does not grant API-key access to the existing update/delete handlers.
This existing route is not handled by the shared action-body parser. Do not assume the shared 2 MiB or strict unknown-field behavior applies here. Only the selected title, content, and social fields are forwarded; the owner comes from authentication.
Publish a post now
This performs a real publication. Use an existing post ID and replace the destination username before running:
curl -X POST "https://youscale.it/api/profile/posts/publish" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"postId": 24,
"platform": "linkedin",
"destination": {
"type": "account",
"accountUsername": "YOUR_CONNECTED_USERNAME"
}
}' | Field | Meaning |
|---|---|
postId | Required positive integer YouScaleIt post ID, not a provider ID. |
platform | Required: linkedin, x, bluesky, instagram, facebook, threads, tiktok, or youtube. |
destination | Required saved destination object from the formats above. |
autoReplyIds | Optional array of up to 10 unique owned auto-comment IDs. The field retains its internal spelling for compatibility. |
tiktokSettings | Optional TikTok-only settings object. |
Auto-comment attachments must match the platform where applicable and are not supported for Threads or TikTok. TikTok settings support title (up to 150 characters), privacyStatus, and boolean allowComment, allowDuet, allowStitch, commercialDisclosure, yourBrand, and brandedContent. Privacy values are PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, or SELF_ONLY; actual provider/account restrictions still apply.
To publish a saved X thread, select platform: "x" and a connected X account. The post must contain the intended thread and meet X’s publication limits.
Success returns HTTP 200 from the website, wrapping the queued job identifier:
{ "success": true, "data": { "jobId": "11111111-1111-4111-8111-111111111111" } } This is an illustrative UUID, not a working job. Replace it in the status request below with the returned data.jobId. A job ID is not proof of publication.
Read publishing status
curl "https://youscale.it/api/profile/publishing-status/11111111-1111-4111-8111-111111111111" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" The owned job result contains jobId, postId, platform, status, and progress. Status is pending, processing, completed, or failed. A completed result can include publication metadata: external post ID, publisher, published time, platform, and post URL. Failures expose a sanitized error, not provider exceptions. Jobs may expire; do not use this endpoint as permanent publication storage.
Schedule a post
The request contains the same publication fields, plus a required future scheduledDateTime in ISO 8601 with UTC or an explicit timezone offset. Threads scheduling is not supported.
The example uses 2027-01-15T10:00:00Z. Replace it with your intended future date and time.
curl -X POST "https://youscale.it/api/profile/scheduled-posts" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"postId": 24,
"platform": "linkedin",
"destination": {
"type": "account",
"accountUsername": "YOUR_CONNECTED_USERNAME"
},
"scheduledDateTime": "2027-01-15T10:00:00Z"
}' The schedule is returned in data with id, postId, platform, posterId, scheduledDateTime, and status. Stored platform values can be uppercase even though the input uses lowercase. Use the returned schedule ID in later requests, not the post ID. Replace 456 below with your actual schedule ID.
Do not both publish immediately and schedule unless you intend separate publications.
Reschedule
curl -X PATCH "https://youscale.it/api/profile/scheduled-posts/456" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{"scheduledDateTime":"2027-01-16T10:00:00Z"}' Only the time changes; this is not a content or destination update. The schedule must be eligible, future, and pending.
Cancel
curl -X POST "https://youscale.it/api/profile/scheduled-posts/456/cancel" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{}' Cancellation stops an eligible schedule; it does not delete the post or undo publication. An already stopped schedule can be returned unchanged. Reschedule/cancel responses use the schedule shape above. Use the monthly calendar to review schedules.
Repost an existing publication
Supported platforms are x, linkedin, bluesky, and facebook. Use an existing publication belonging to the selected post and platform; this interface does not schedule a repost before its source publication exists.
Read post details, then select the relevant internal publication record ID:
curl "https://youscale.it/api/profile/posts/24" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" The repost examples use post ID 24 and publication ID 789. Replace both with your actual IDs. It is not the external social-network post ID.
Repost now
This performs a real action.
curl -X POST "https://youscale.it/api/profile/reposts/publish" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"postId": 24,
"postPublicationId": 789,
"platform": "linkedin",
"destination": {
"type": "account",
"accountUsername": "YOUR_CONNECTED_USERNAME"
}
}' Success returns postId, postPublicationId, platform, status: "completed", and a nullable externalPostId inside data. Not every provider returns a new external ID.
Schedule a repost
Add a future timestamp to the same request shape:
curl -X POST "https://youscale.it/api/profile/scheduled-reposts" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{
"postId": 24,
"postPublicationId": 789,
"platform": "linkedin",
"destination": {
"type": "account",
"accountUsername": "YOUR_CONNECTED_USERNAME"
},
"scheduledDateTime": "2027-01-15T10:00:00Z"
}' Each request selects one time and one destination. The response is an array in data; take the schedule ID from the appropriate entry for subsequent requests.
Replace 321 with the returned ID. Repost schedules include id, postId, postPublicationId, platform, status, scheduledDateTime, destination, resultExternalId, and publishedAt. Some fields are null; an execution failure may add a sanitized error. The returned destination describes stored account/publisher identifiers and is not the same shape as the input destination selector.
List schedules for a post
curl "https://youscale.it/api/profile/posts/24/repost-schedules" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" Returns an array of owned schedules in data, including execution status. It is not paginated.
Reschedule
curl -X PATCH "https://youscale.it/api/profile/scheduled-reposts/321" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{"scheduledDateTime":"2027-01-16T10:00:00Z"}' Cancel
curl -X POST "https://youscale.it/api/profile/scheduled-reposts/321/cancel" -H "x-youscaleit-api-key: $YOUSCALEIT_API_KEY" -H "Content-Type: application/json" -d '{}' Reschedule and cancel return one schedule object in data. Processing or published repost schedules cannot be edited. Cancellation does not undo a repost already sent to a provider.
Responses, errors, and retries
Successful website operations on this page return HTTP 200 with success: true and a data value. A queued publication still requires job-status checking; successful draft creation is not publication. Do not infer the website status from a backend status such as 201 or 202.
| Situation | Current website behavior |
|---|---|
| Neither browser session nor key supplied | HTTP 401 with success: false and a generic Unauthorized message |
| Query parameters on a shared action route or unsupported request content type | HTTP 400 with {"success":false} |
| Shared action write authenticated through a session without a matching Origin | HTTP 403 with {"success":false} |
| Shared action input/ID validation failure, oversized body, backend rejection, timeout, or unexpected backend response | Generic HTTP 404 with {"success":false} |
| Auto-comment creation failure | Generic HTTP 404 with success: false; a code may be present |
| Unmatched ordinary API path | HTTP 404 with {"success":false} |
Wrong HTTP methods are also subject to SvelteKit’s method handling; use the exact methods listed above. Generic 404 responses do not mean only “missing resource,” and clients should not expect detailed schema, ownership, or provider errors.
Never automatically replay a failed or timed-out write. The operation may have completed before the response failed, including if response validation failed after the backend committed it. Check the saved post, job status, calendar, or repost schedules first. There is no general idempotency-key contract for these endpoints.
The shared action backend request has a 30-second timeout; hosting limits can differ. Errors from upstream services are not necessarily forwarded with their original status or retry headers. Keep retry policies conservative, preserve private media URLs, and do not log credentials or full private responses.
See troubleshooting for safe diagnosis. REST mode-switching behavior in this reference does not change the separate MCP draft contract.
