← Home

SpikeReel API

Turn long videos into captioned vertical shorts programmatically. The API mirrors the app: you submit a video, we transcribe it, find the best moments, reframe to vertical, and burn in captions, then you poll for the finished clips.

Base URL

https://spikereel.com/api/v1

Authentication

The API is a paid feature. Generate a key from your account settings (paid plans only) and send it as a bearer token on every request. Your key is shown once at creation, store it securely and never expose it in client-side code.

Authorization: Bearer sk_live_your_key_here

Verify your key with a quick call:

curl https://spikereel.com/api/v1/me \
  -H "Authorization: Bearer sk_live_your_key_here"
{
  "plan": "pro",
  "planLabel": "Pro",
  "usage": {
    "minutesUsed": 12.5,
    "minutesLimit": 300,
    "minutesRemaining": 287.5,
    "periodStart": "2026-07-01T00:00:00.000Z"
  }
}

Create a clipping job

POST/clips

Submit a video by URL (JSON) or by file upload (multipart). Returns immediately with a job id and status queued, processing runs asynchronously.

curl -X POST https://spikereel.com/api/v1/clips \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://youtube.com/watch?v=...",
    "options": {
      "clipCount": 6,
      "minSeconds": 18,
      "maxSeconds": 55,
      "aspect": "9:16",
      "captionStyle": "hormozi",
      "languages": ["en"]
    }
  }'

Or upload a file:

curl -X POST https://spikereel.com/api/v1/clips \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -F "[email protected]" \
  -F "clipCount=6"

Response (202 Accepted):

{
  "id": "job_a1b2c3d4e5f6",
  "status": "queued",
  "progress": 0,
  "title": "episode.mp4",
  "kind": "clip",
  "clipCount": 0,
  "createdAt": "2026-07-03T12:00:00.000Z",
  "error": null
}

Options

  • clipCount — number of clips to produce (1–12, capped by your plan)
  • minSeconds / maxSeconds — clip length bounds (8–180)
  • aspect9:16, 1:1, 4:5, 16:9, original
  • captionStylehormozi, clean, neon, bold, cinematic, documentary, minimal, none
  • reframefill, blur, original
  • priorityvirality, clarity, education, emotion, comedy, sales
  • languages — array of language codes, e.g. ["en", "es"]

Get a job (poll for results)

GET/clips/{id}

Poll until status is completed or failed. When complete, each clip includes a signed downloadUrl that works without authentication and expires after 7 days.

curl https://spikereel.com/api/v1/clips/job_a1b2c3d4e5f6 \
  -H "Authorization: Bearer sk_live_your_key_here"
{
  "id": "job_a1b2c3d4e5f6",
  "status": "completed",
  "progress": 100,
  "title": "episode.mp4",
  "kind": "clip",
  "clipCount": 6,
  "createdAt": "2026-07-03T12:00:00.000Z",
  "error": null,
  "clips": [
    {
      "id": "clip_1",
      "title": "The one hiring mistake that kills startups",
      "score": 92,
      "durationSec": 41.2,
      "hashtags": ["#startups", "#hiring"],
      "description": "…",
      "downloadUrl": "https://spikereel.com/clips/job_a1b2c3d4e5f6/clip_1.mp4?e=…&t=…",
      "thumbnailUrl": "https://spikereel.com/clips/job_a1b2c3d4e5f6/clip_1.jpg?e=…&t=…",
      "rendered": true
    }
  ]
}

Status values: queued, processing, completed, failed, cancelled.

List recent jobs

GET/clips

Returns your 50 most recent clipping jobs (without the clip arrays).

curl https://spikereel.com/api/v1/clips \
  -H "Authorization: Bearer sk_live_your_key_here"

Connected accounts

GET/accounts

List the social platforms connected on your account, these are the valid platform values for publishing.

curl https://spikereel.com/api/v1/accounts \
  -H "Authorization: Bearer sk_live_your_key_here"
{
  "connected": [
    { "platform": "youtube", "account": "My Channel" }
  ]
}

Publish or schedule a clip

POST/clips/{jobId}/publish

Publish a rendered clip to one connected platform immediately, or schedule it by including scheduledAt (ISO 8601). The platform must be connected on your account, check GET /accounts first.

curl -X POST https://spikereel.com/api/v1/clips/job_a1b2c3d4e5f6/publish \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "clipId": "clip_1",
    "platform": "youtube",
    "title": "The one hiring mistake that kills startups",
    "caption": "Full episode linked below. #startups",
    "privacy": "public"
  }'

Publish response:

{ "published": true, "platform": "youtube" }

Schedule for later (add scheduledAt):

{ "clipId": "clip_1", "platform": "tiktok", "scheduledAt": "2026-07-10T14:00:00Z" }
{ "scheduled": true, "platform": "tiktok", "scheduledAt": "2026-07-10T14:00:00.000Z", "scheduleId": "sch_…" }

Fields: clipId and platform required; title, caption, privacy (public/unlisted/private), playlistId (YouTube), and scheduledAt optional. Platforms: youtube, tiktok, instagram, x, facebook, linkedin, pinterest, threads, reddit.

Webhooks

Instead of polling, register an https endpoint in your account settings and we'll POST to it when a clip job finishes. You get a signing secret once at creation.

Events: clip.completed and clip.failed. Payload:

POST https://your-app.com/webhooks/spikereel
X-SpikeReel-Event: clip.completed
X-SpikeReel-Signature: sha256=<hex hmac>
Content-Type: application/json

{
  "event": "clip.completed",
  "createdAt": "2026-07-03T12:05:00.000Z",
  "data": {
    "id": "job_a1b2c3d4e5f6",
    "status": "completed",
    "progress": 100,
    "title": "episode.mp4",
    "kind": "clip",
    "clipCount": 6,
    "createdAt": "2026-07-03T12:00:00.000Z",
    "error": null,
    "clips": [ { "id": "clip_1", "downloadUrl": "https://…", "score": 92, "...": "" } ]
  }
}

Verify the signature to confirm a delivery is from SpikeReel: compute an HMAC-SHA256 of the raw request body using your webhook secret and compare it to the X-SpikeReel-Signature header (constant-time).

// Node.js (Express raw body)
import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  const a = Buffer.from(header || "");
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Each delivery times out after 8 seconds. Failed deliveries (network errors or 5xx) are retried up to 2 times with exponential backoff (~2s, then ~8s); a 4xx is treated as a permanent failure and not retried, so keep your handler fast and return 2xx quickly (enqueue and return 200). The account page shows a per-webhook delivery log with the status and attempt count of recent deliveries.

Errors & limits

Errors return a JSON body { "error": "…", "code": "…" } with a standard HTTP status:

  • 401 — missing, malformed, or revoked key
  • 402 — free plan, or monthly quota exhausted
  • 413 — uploaded file exceeds your plan's size limit
  • 429 — rate limit exceeded (20 job submissions / 5 min); see the Retry-After header
  • 404 — job not found (or not owned by your key)
  • 409 — publish target platform isn't connected on your account
  • 502 — the platform rejected the publish (see error)

Processing consumes source-video minutes from your plan's monthly allowance, the same pool the web app uses. Check remaining minutes any time via GET /me.

Ready to start? Generate an API key →