Cut.ProDocs

Conventions

Base URL, field format, pagination, async jobs and expiring links: the rules that apply to every route.

The same rules apply to all routes. Read them once and the reference becomes predictable.

Base URL

https://api.cut.pro/api/v1

HTTPS only. The version is part of the path.

Request

Send the body as JSON with Content-Type: application/json. The routes also accept application/x-www-form-urlencoded and multipart/form-data with the same fields, which helps in no-code tools.

Fields

RuleExample
Every field is snake_casecredits_cost, output_resolution
The resource's own id is always id{ "id": "7412908371004912" }
A reference to another resource carries its namevideo_id, edit_id, connection_id
IDs are stringsstore them as strings, never convert to a number
Date and time in ISO 8601, UTC"2026-10-29T18:04:51.000Z"
Duration and position in the video in seconds"start_time": 42.5
A field with no value comes as null, it does not disappear"completed_at": null

The only exception is metadata in POST /posts: the keys there are each network's own (privacyLevel, categoryId, privacyStatus) and go to the platform exactly as you wrote them.

State and error

status describes where a job is and comes in lowercase: queued, processing, completed, failed.

code describes what went wrong and comes in uppercase: INSUFFICIENT_CREDITS, SUBMISSION_EXPIRED. Every error has the same body, with no text message:

{ "code": "INSUFFICIENT_CREDITS", "extra": { "credits_needed": 121, "current_balance": 40 } }

Use a switch on code and translate it for your interface. See Errors.

Lists and pagination

Every list responds with the resource name and a pagination block:

{
  "clips": [{ "id": "7412908412887301" }],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_count": 52,
    "has_next_page": true,
    "has_previous_page": false,
    "limit": 20
  }
}

Paginate with page (starts at 1) and limit (maximum 100). The default limit changes per route and is in each route's reference.

curl "https://api.cut.pro/api/v1/renders?page=2&limit=100" \
  -H "X-Api-Key: $CUTPRO_API_KEY"

Keep going while has_next_page is true.

Async jobs

Clipping, render, post, transcription, generation and persona do not finish in the response. Creation returns an id and you poll until the end:

  1. Create the job and keep the id.
  2. Poll the job's read route every 5 to 10 seconds.
  3. Stop when the status reaches a final state.
JobRead routeFinal states
ClippingGET /clips/{videoId}/submissions/{submissionId}completed, failed
RenderGET /renders/{renderId}completed, failed, cancelled, expired
PostGET /posts/{id}completed, partial, failed, cancelled
TranscriptionGET /transcriptions/{transcriptionId}ready, no_speech, failed
GenerationGET /generations/{id}ready, failed

This pace fits comfortably within the rate limit. The API does not send webhooks: the end of a job is always found by polling.

WhatValidity
download_url, play_url and thumbnail_url of a clipshort: ask again when you are going to use it
GET /renders/{renderId}/download link1 hour
A render's MP4 fileset by the plan, in render_expiry_hours of GET /renders/limits
Edit (edit_id)does not expire

Do not store a signed link in your database. Store the id and ask for the link on the spot. If the MP4 was already deleted, POST /renders with the edit_id generates a new one.

OpenAPI specification

The complete specification is at https://api.cut.pro/api/v1/openapi.json. Use it to generate a typed client, import into Postman or Insomnia, or give context to a coding agent.

On this page