Skip to content
Create a key

Paste a key to use it in the examples on these pages. The key stays in this browser tab. These pages never send it anywhere.

Brainstorm video ideas

brainstorm_ideasPOST/v1/brainstormsBeta

Starts writing ideas for short videos on a topic, and returns the tool run that holds them once it is done.

Beta. This endpoint is supported and can gain new fields. If a change would break your code, we tell you before it takes effect and list it in the changelog.

About

Call this to get ideas for short videos on a topic: each idea has a title, a hook, an outline, a format and why it works. Say the kind of video with videoType (get_setting_options (GET /v1/reference/setting-options) lists them), the language of the ideas and how many you want. The call answers 202 at once with the run, queued, and a Location to follow; read it with get_tool_run (GET /v1/tool-runs/{toolRunId}) (with ?wait= to hold the request) until it is done, then read the ideas in its ideas field. Always send an Idempotency-Key, the same one on every retry: a retry of the same request returns the same run and never uses a second tool run.

Example use

Each Monday a content team asks for ten ideas about its next product launch, with videoType any. It reads the hooks and outlines from get_tool_run (GET /v1/tool-runs/{toolRunId}) and picks the ones to film.

Endpoint

Code
POST https://api.gpt-video.com/v1/brainstorms
  • Scope spend.
  • Rate limit 10 requests a minute for each key and 20 for each account, shared by every spend call. See rate limits.
  • Idempotency-Key is required.
  • It starts work that runs on its own. The answer comes back before the work is done.

Parameters

Headers

NameTypeRequiredDescription
Idempotency-KeystringRequiredThis operation spends, so the key is required. Create it once, before the request, and send the same key on every retry. From 1 to 255 visible characters, such as a UUID. See idempotency.

Body

NameTypeRequiredDescription
topicstringRequiredWhat the videos are about, up to 300 characters. From 1 to 300 characters.
tonestringOptionalThe tone of the videos, like funny or serious, up to 60 characters. At most 60 characters.
audiencestringOptionalWho the videos are for, up to 200 characters. At most 200 characters.
videoTypestringRequiredThe kind of video the ideas are for: story, fake_text, split_screen, or any. One of story, fake_text, split_screen, any.
languagestringRequiredThe language of the ideas: en for English, it for Italian. One of en, it.
countintegerRequiredHow many ideas to write, from 3 to 30. From 3 to 30.

Send only the fields listed here. Any other field is refused with UNKNOWN_PARAMETER.

Request

Ideas for story videos.

Request example
# Create the key once. Send this same key again if you retry this request.
IDEMPOTENCY_KEY=$(uuidgen)
curl -X POST "https://api.gpt-video.com/v1/brainstorms" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "Morning routines for busy parents",
    "videoType": "story",
    "language": "en",
    "count": 5
  }'
// Create the key once. Send this same key again if you retry this request.
const idempotencyKey = crypto.randomUUID();
const res = await fetch("https://api.gpt-video.com/v1/brainstorms", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
    "Idempotency-Key": idempotencyKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "topic": "Morning routines for busy parents",
    "videoType": "story",
    "language": "en",
    "count": 5
  }),
});
const data = await res.json();
console.log(data);
import os
import uuid

import requests

# Create the key once. Send this same key again if you retry this request.
idempotency_key = str(uuid.uuid4())
r = requests.post(
    "https://api.gpt-video.com/v1/brainstorms",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
        "Idempotency-Key": idempotency_key,
    },
    json={
        "topic": "Morning routines for busy parents",
        "videoType": "story",
        "language": "en",
        "count": 5
    },
)
data = r.json()
print(data)
{
  "method": "tools/call",
  "params": {
    "name": "brainstorm_ideas",
    "arguments": {
      "topic": "Morning routines for busy parents",
      "videoType": "story",
      "language": "en",
      "count": 5,
      "confirm": true,
      "idempotencyKey": "REPLACE-WITH-A-NEW-UUID-FOR-THIS-CALL"
    }
  }
}

Response

A successful call answers HTTP 202. Returns a Tool run object in toolRun.

Fields to check

NameTypeDescription
toolRun.idstringThe tool run id. It starts with run_.
toolRun.statusstringqueued and running are still working; done and failed are final.
toolRun.file.downloadUrlstring or nullA link to download the file, on a read of a finished run; null otherwise.
toolRun.file.downloadUrlExpiresAtstring or nullAn ISO 8601 time in UTC.
toolRun.jobIdstring or nullThe job that carries out the run, to follow with get_job (GET /v1/jobs/{jobId}); null once it is gone.
paidWithstring or nullWho paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time.

Response example

  • Location: https://api.gpt-video.com/v1/tool-runs/run_5e8a1c3f7d2b4096a1e4
HTTP 202
{
  "toolRun": {
    "id": "run_5e8a1c3f7d2b4096a1e4",
    "tool": "brainstorm",
    "status": "queued",
    "progress": 0,
    "errorMessage": null,
    "file": null,
    "ideas": null,
    "jobId": "job_2c7f9e1a4d6b48035f9e",
    "createdAt": "2026-09-01T11:00:00.000Z",
    "finishedAt": null,
    "voiceover": null,
    "separation": null,
    "brainstorm": {
      "topic": "Morning routines for busy parents",
      "tone": "",
      "audience": "",
      "videoType": "story",
      "language": "en",
      "count": 5
    }
  },
  "paidWith": "plan"
}
All response fields
NameTypeRequiredDescription
toolRunTool run objectRequiredDescribed in Tool run object.
paidWithstring or nullRequiredWho paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time. One of plan, api_bonus.
More examples

The tool runs of the day are used up

POST /v1/brainstorms

Request body
{
  "topic": "Morning routines for busy parents",
  "videoType": "any",
  "language": "en",
  "count": 10
}
HTTP 429
{
  "error": {
    "code": "DAILY_LIMIT_REACHED",
    "message": "Daily limit of tool runs reached (100). It resets at 00:00 UTC. Upgrade your plan for a higher limit.",
    "hint": "The limit resets at 00:00 UTC. A higher plan raises it: https://www.gpt-video.com/app/billing.",
    "requestId": "req_6a2d9f1c4e8b3a7d0f5c2e94"
  }
}

Errors

CodeStatusWhenWhat to do
INSUFFICIENT_CREDITS402See the error reference.Stop and tell the user.
PLAN_REQUIRED402See the error reference.Stop and tell the user.
DAILY_LIMIT_REACHED429The tool runs of the day are used upStop until the limit resets at 00:00 UTC.

Every call can also answer these errors. VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED, UNAUTHORIZED, SCOPE_MISSING, IDEMPOTENCY_IN_PROGRESS, PAYLOAD_TOO_LARGE, IDEMPOTENCY_KEY_REUSED, RATE_LIMITED, INTERNAL, UNAVAILABLE.

Cost

Uses one tool run of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the run fails.

  • Paid by the API bonus, it uses 1 bonus credit.
  • When the API bonus pays, an account can run 10 tools a day.
  • See API pricing for who pays first.

Questions

What happens if my request times out and I send it again?

Send it again with the same Idempotency-Key. You get the same run back and no second tool run is used from the daily allowance. A new key starts a new run.

Where are the ideas?

In the ideas field of the run, once get_tool_run (GET /v1/tool-runs/{toolRunId}) says it is done. Until then ideas is null.

View as Markdown