Posttar API

Video Clips

Read a job that cut a long video into short clips, approve the ones you want, and fine-tune each clip.

Video Clips takes one long video (a talk, a podcast, a live) and proposes the moments that work on their own as short vertical clips. Each approved clip becomes a post of format video_clip, with its own hook, captions and caption text, that you schedule and publish like any other post.

The job itself is started from the app or in a conversation with the assistant, where the video is sent. The API reads a job and approves it: GET /clip-jobs/{id} and POST /clip-jobs/{id}/approve. These are a job's proposed clips, not the reel's library clips of GET /posts/{id}/clips. Video Clips is enabled per workspace; a workspace without it answers 403 with forbidden, and nothing is charged.

Two phases, and where the credits go

  • Analysis: the job reads the video and proposes the moments. It takes a few minutes and costs no credits. A video that cannot be used (too short, too long, no speech, not enough good moments) ends the job as failed with refusal, before anything is charged.
  • Approval: you choose which proposals become clips. Each one costs 1 credit, charged all at once when you approve, so approving 3 clips uses 3 credits. Without enough credits for all of them, nothing is charged and the job stays ready.
LimitValue
The long videofrom 2 to 60 minutes, up to 2 GB
Each clipfrom 20 to 60 seconds
Clips approved per jobfrom 1 to 8
Hookup to 60 visible characters, no links and no @handles
Trimming a clipup to 5 seconds either way at each end, from the proposed moment
Keeping the long videothe original video is kept for 71 day after it is failed, and then deleted. The approved clips are never deleted.

Read a job and approve two clips

Poll the job until it is ready, then approve by index.

  1. 1

    Read the job. While status is analyzing, poll again in a minute.

    curl -H "Authorization: Bearer $POSTTAR_KEY" "https://api.posttar.com/v1/clip-jobs/5f0c7a2e-..."
    {
      "id": "5f0c7a2e-...",
      "status": "ready",
      "durationSec": 1520.4,
      "refusal": null,
      "proposals": [
        { "index": 0, "start": 95.2, "end": 138.6, "hook": "Why most freelancers **undercharge**", "title": "Pricing", "approved": false },
        { "index": 2, "start": 811.5, "end": 858.3, "hook": "The **one** question I ask every client", "title": "Discovery call", "approved": false }
      ],
      "clips": []
    }
  2. 2

    Approve two proposals, changing the hook of one. This charges 2 credits.

    curl -X POST -H "Authorization: Bearer $POSTTAR_KEY" -H "Content-Type: application/json" \
      -d '{"clips":[0,2],"hooks":{"2":"The one question I ask before any quote"}}' \
      "https://api.posttar.com/v1/clip-jobs/5f0c7a2e-.../approve"
    {
      "jobId": "5f0c7a2e-...",
      "postIds": ["0e4d9b1a-...", "7a3b5c9d-..."],
      "credits": 2
    }
  3. 3

    Read the job again until every clip has renderState done. Each clip is also a post you read with GET /posts/{id}.

    curl -H "Authorization: Bearer $POSTTAR_KEY" "https://api.posttar.com/v1/clip-jobs/5f0c7a2e-..."

A job approves once. A second approval answers 409 with invalid_state and charges nothing, so retrying after a network error is safe: read the job first, and if clips is already filled, the first call went through.

Fine-tuning a clip

GET /posts/{id} on a clip returns content.clip: the hook, the stretch in use (startSec, endSec) and the proposed one (proposalStartSec, proposalEndSec). PATCH /posts/{id}/video-clip changes the hook and moves each end. It is free: the post is marked as having an outdated video, and the MP4 is rebuilt before it is downloaded, scheduled or published. The caption is edited with PATCH /posts/{id}, as in every format.

Start the clip 1.3 seconds earlier and change its hook.

curl -X PATCH -H "Authorization: Bearer $POSTTAR_KEY" -H "Content-Type: application/json" \
  -d '{"hook":"The **one** question I ask every client","startSec":810.2}' \
  "https://api.posttar.com/v1/posts/7a3b5c9d-.../video-clip"

A clip that failed is made again with POST /posts/{id}/regenerate, the same call as every other format, and a failed clip is made again without spending a credit.