Vibescaling Docs

Posts

Managing posts via the Vibescaling API

List Posts

GET /api/v1/posts?status=draft&page=1&per_page=20

Query Parameters

ParameterTypeDescription
statusstringFilter by status: draft, scheduled, posted, archived
post_typestringFilter by type: slides or video
tiktok_account_idstringFilter by TikTok account UUID
pagenumberPage number (default: 1, max: 1000)
per_pagenumberItems per page (default: 20, max: 100)

Response

{
  "data": [...],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 42,
    "total_pages": 3
  }
}

Create a Post

POST /api/v1/posts

Request body

{
  "title": "My Post Title",
  "post_type": "slides",
  "caption": "Check out these slides!",
  "hashtags": "#tiktok #content",
  "tiktok_account_id": "uuid"
}
FieldTypeRequiredDescription
titlestringYesPost title (1–500 chars)
post_typestringNo"slides" (default) or "video"
captionstringNoPost caption (max 2200 chars)
hashtagsstringNoHashtags (max 500 chars)
tiktok_account_iduuidNoTikTok account for publishing

Posts are created with status draft.

Get a Post

GET /api/v1/posts/:id

Update a Post

PATCH /api/v1/posts/:id

Request body

Any combination of:

{
  "title": "Updated title",
  "caption": "New caption",
  "hashtags": "#updated",
  "status": "scheduled",
  "scheduled_at": "2026-03-15T14:00:00Z",
  "tiktok_account_id": "uuid"
}

Scheduling via PATCH

Set status to scheduled along with scheduled_at and tiktok_account_id to schedule a post.

Delete a Post

DELETE /api/v1/posts/:id

Permanently deletes a post, its assets (R2 objects), and dispatch logs. Only posts with draft or archived status can be deleted. Returns 204 No Content on success.

Batch Archive

Archive multiple posts at once:

PATCH /api/v1/posts/batch

Request body

{
  "ids": ["uuid-1", "uuid-2", "uuid-3"],
  "action": "archive"
}
FieldTypeDescription
idsuuid[]Post IDs to archive (1–50)
actionstring"archive"

Response

{
  "data": { "archived": 3 }
}

Only posts belonging to your organization are affected. IDs that don't exist or belong to another org are silently skipped.

Upload Assets

POST /api/v1/posts/:id/assets

Upload slide images or video files for a post.

Request body (slide)

{
  "filename": "slide1.png",
  "content_type": "image/png"
}

Request body (video)

{
  "filename": "video.mp4",
  "content_type": "video/mp4",
  "content_length": 52428800,
  "replace": false
}
FieldTypeDescription
filenamestringFile name
content_typestringMIME type (image/png, image/jpeg, video/mp4, video/webm, video/quicktime)
content_lengthnumber?File size in bytes (required for validation on large videos)
replaceboolean?Replace existing video (default: false)

Response

{
  "upload_url": "https://...",
  "r2_key": "orgs/{org}/posts/{post}/slides/slide1.png"
}

Upload the file directly to upload_url via PUT request with the correct Content-Type header.

Video-specific behavior

  • Each video post can have only one video. Uploading a second video returns 409 unless replace: true is set.
  • Video content types must start with video/ (e.g. video/mp4, video/webm, video/quicktime).
  • Maximum video file size is 4GB. Exceeding this returns 413.
  • Video presigned URLs expire after 2 hours (slides expire after 1 hour).

Replace a video

To replace an existing video, set replace: true:

{
  "filename": "updated-video.mp4",
  "content_type": "video/mp4",
  "replace": true
}

This atomically replaces the previous video file.

List Assets

GET /api/v1/posts/:id/assets

Returns the list of assets for a post with presigned download URLs.

Response

{
  "data": [
    {
      "r2_key": "orgs/{org}/posts/{post}/slides/slide1.png",
      "url": "https://...",
      "content_type": "image/png"
    }
  ]
}

Post Object

FieldTypeDescription
iduuidPost ID
org_iduuidOrganization ID
post_typestringslides or video
titlestring?Post title
captionstring?Post caption
hashtagsstring?Hashtags
statusstringdraft, scheduled, publishing, posted, archived
scheduled_attimestamp?When the post is scheduled to publish
posted_attimestamp?When the post was published
tiktok_account_iduuid?TikTok account for publishing
publish_modestringdirect or inbox
publish_retriesnumberNumber of publish retry attempts
last_publish_errorstring?Last publish failure message
privacy_levelstring?TikTok privacy level
disable_commentbooleanComments disabled
disable_duetbooleanDuets disabled
disable_stitchbooleanStitching disabled
brand_content_togglebooleanBranded content disclosure
brand_organic_togglebooleanOwn brand promotion disclosure
created_attimestampCreation time
updated_attimestampLast update time

On this page