Getting started

Make your first ShortFast API request, read the response envelope, and handle errors by their stable code.

The ShortFast API creates short-form videos from a brief, edits everything the pipeline produced, renders them to mp4, publishes them to your connected social accounts, runs them on a schedule with automations, and pushes real-time events to your webhooks.

Base URL

https://app.shortfast.com/api/v1

Create an API key

Create and revoke keys under Settings > API & Webhooks in the ShortFast app. A key's full value is shown only once, at creation, so store it securely. Each key is scoped to the workspace it was created in, and every query the API runs is scoped to that workspace.

Your first request

GET / returns API metadata plus the workspace your key resolved to, so it is the cheapest way to check that a key works:

curl https://app.shortfast.com/api/v1/ \
  -H "Authorization: Bearer sf_live_xxxxxxxxxxxxxxxxxxxxxxxx"
{
  "data": {
    "name": "ShortFast API",
    "version": "v1",
    "docs": "https://developer.shortfast.com",
    "workspace": {
      "id": "k9WmT3xR2pQ7nV4bd",
      "name": "Acme Studio",
      "plan": "pro",
      "credits": { "credits": 42500, "tokens": 42500000 },
      "limits": {
        "maxRendersPerMonth": null,
        "maxAutomations": 3,
        "maxProfiles": 3,
        "maxVideoDurationSeconds": 7200,
        "maxRenderSeconds": 720,
        "storageBytes": 50000000000,
        "watermark": false
      },
      "usage": { "storageBytes": 3187441664, "profiles": 2 }
    }
  }
}

The response envelope

Every response is a JSON object with a data key. List endpoints add a paging object and accept limit (1 to 100, default 50) and offset query parameters:

{
  "data": [],
  "paging": { "limit": 50, "offset": 0, "total": 128 }
}

Single-resource endpoints return the same envelope without paging. Two lists are deliberately unpaginated because they are small and static: /profiles and everything under /reference.

Errors

Errors use standard HTTP status codes with a JSON body:

{
  "error": {
    "status": 409,
    "code": "warning-publish-not-configured",
    "message": "No profile selected"
  }
}

code is the stable, machine-readable identifier to branch on. The message wording may change over time; the code will not. details is present only when an error carries structured context, and code is absent on plain validation errors.

StatusMeaning
400An invalid request, a field the endpoint cannot write, or a business refusal carrying a warning-* code
401The API key is missing or invalid
404No such resource in this workspace
409A conflict: the wrong pipeline for the operation, a hard limit, or an idempotency conflict
422An action that does not apply to this video (converting a video that is already editable, promoting a clip)
500Server error
502An AI writer returned nothing usable. Retry in a moment
503A helper is temporarily unavailable. The message names the fallback to use meanwhile

The codes you will branch on most:

CodeStatusMeaning
unauthorized401The key is missing, malformed or revoked
unknown_endpoint404No route matches the path
internal_error500Something broke on our side
idempotency_in_progress409A request with the same Idempotency-Key is still running
idempotency_failed409The first call with this key errored after it may have taken effect. Retry with a fresh key
wrong-video-type409This operation only exists on another pipeline (AI scenes on a faceless video, presentation scenes on a non-presentation)
limit-reached409A hard cap: 50 scenes on a video, 25 webhook endpoints on a workspace
not-available503A capability is temporarily down
warning-no-credits400The workspace has no credits left
warning-invalid-input400A value the shared service refused
warning-source-not-ready400 / 409The video has no render, no transcript or no duration yet

Plan ceilings and job failures share one vocabulary (warning-plan-renders, warning-publish-auth, and the rest). The same code appears on a synchronous 400 and on a failed job's process.error.code / render.error.code / publish.error.code, and the whole list is readable at GET /reference/failure-codes. See Credits and limits.

Retrying safely

Every POST that queues real work or charges credits accepts an optional header:

Idempotency-Key: 4f1c9e2a-6b81-4f0d-9a3e-2c5d7e8b1a44

The first request with a given key runs the action and stores its response. A retry with the same key replays that stored response byte for byte instead of generating, rendering, publishing or charging a second time, so a client timeout is safe to retry. Keys are scoped per workspace and per target, so the same key can never cross two videos or two endpoints. With no header the action simply runs.

Send an Idempotency-Key on POST /videos/{id}/publish in particular: a timed-out retry would otherwise post the same video twice.

Reference

On this page