# EntireFeed complete documentation Contract source: https://entirefeed.com/openapi.json --- # EntireFeed documentation > Build and operate media generation, reusable workflows, agent actions, and publishing through EntireFeed's public and Console surfaces. Canonical: https://entirefeed.com/docs EntireFeed exposes a public REST API for media generation, a signed-in Console for operator work, and Console MCP for delegated agent actions. Start with the task you need to complete, then use the credential shown for that surface. ## Choose the right surface - Use **Public REST** for direct media generation, Workflow Starters, generation status, read-only billing data, and webhooks. - Use the **signed-in Console** to create credentials, manage reusable workflows, inspect usage, and operate publishing. - Use **Console MCP** when an agent should act with the current Console user's delegated organization authority. These authorities are intentionally separate. A Public REST API key is not a Console session or an MCP credential. ## Start with a cost-safe request The [Quickstart](/docs/get-started/quickstart) discovers a supported generation task and estimates it before showing the optional paid request. Discovery and estimation create no media and spend no balance. ## Machine-readable contracts Every page has a raw Markdown variant. Agents can also load the concise [`llms.txt`](/llms.txt), the consolidated [`llms-full.txt`](/llms-full.txt), or the public [`openapi.json`](/openapi.json). ## Product surfaces - [Get started](/docs/get-started): Choose a surface, understand credentials, and make a first request. - [Generate](/docs/generate): Discover supported image and video generation tasks. - [Workflows](/docs/workflows): Run curated starters or build reusable multi-step workflows. - [Agents](/docs/agents): Connect Console MCP with delegated operator authority. - [Publishing](/docs/publishing): Move reviewed media into accounts, schedules, and posts. - [Operate](/docs/operate): Monitor lifecycle, billing, webhooks, errors, and retries. - [Reference](/docs/reference): Inspect public REST, model, pricing, and MCP contracts. --- # Get started with EntireFeed > Choose the shortest self-serve path from account creation to an API-ready workspace, without requiring a paid run. Canonical: https://entirefeed.com/docs/get-started Start with a Console account, then choose the credential for the surface you intend to use. Direct REST integrations need a Public REST API key. Console-only work uses your signed-in session, while an agent connected through Console MCP needs a separate delegated MCP credential. ## The shortest API-ready path 1. Create a Console account with passwordless email sign-in. 2. For a direct REST integration, create an organization API key and store the secret when it is shown. 3. Discover a current task and model. 4. Estimate the request without authentication or spending balance. At that point your workspace is API-ready. Running a generation, using Playground, connecting MCP, configuring webhooks, and setting up publishing are optional next steps. ## Continue by intent - Follow the [Quickstart](/docs/get-started/quickstart) for a complete estimate-before-run REST example. - Read [Authentication](/docs/get-started/authentication) before storing credentials or connecting an agent. - Browse [Generate](/docs/generate) to inspect supported generation tasks and models. - Open [Workflows](/docs/workflows) when one direct request is not enough. > Estimation does not create media or spend balance. The Quickstart marks the first paid request explicitly. --- # Estimate, create, and track your first generation > Discover a supported generation task, estimate it without authentication, and optionally create and monitor a paid generation. Canonical: https://entirefeed.com/docs/get-started/quickstart This guide uses the current public `video.create` task with `seedance-2`. You can complete discovery and estimation without an API key, creating media, or spending balance. ## Before you begin Create an account in Console, open **API Keys**, and create a key if you intend to run the optional generation step. The full `efapi_live_...` secret is displayed once. Keep it out of source control, browser URLs, and prompts. New organizations start with a zero balance. Discovery and estimation still work without funding. If you continue to the optional paid generation, a signed-in billing manager must [add balance in Console](https://console.entirefeed.com/billing) after estimating and before creation. The example price is representative of current pricing. Always use the response from `POST /v1/estimate` as the request-specific estimate immediately before paid creation. ## Discover the contract Read the task catalog before constructing input. This request is public, creates no media, and spends no balance: ### cURL ```bash curl https://api.entirefeed.com/v1/tasks \ -X GET ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/tasks", { method: "GET", }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/tasks", timeout=30, ) response.raise_for_status() print(response.json()) ``` Confirm that `video.create` is `available`, select the `seedance-2` variant, and use that variant's `input_schema` and `defaults`. ## Estimate before any paid request Estimation uses the exact generation payload but requires no credential and creates no media: ### cURL ```bash curl https://api.entirefeed.com/v1/estimate \ -X POST \ -H "Content-Type: application/json" \ -d '{ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/estimate", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/estimate", headers={"Content-Type": "application/json"}, json={ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p", }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` Expected response: ```json { "estimated_cost": { "amount_usd": "1.64" }, "line_items": [ { "type": "video_generation", "model": "seedance-2", "quantity": 1, "unit": "operation", "amount_usd": "1.64" } ] } ``` The response is the request-specific estimate in USD. You can stop here without spending balance. ## Optional: create the generation **This is the first paid request, and it requires balance.** New organizations start with $0. Estimate-only users can stop above without spending. A signed-in billing manager can [add balance in Console](https://console.entirefeed.com/billing) after estimating and before creation. The request requires a Public REST API key. The estimated amount is held from your balance while the generation runs. Use a stable `Idempotency-Key` for this intended request. ### cURL ```bash curl https://api.entirefeed.com/v1/generations \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: quickstart-video-001" \ -H "Content-Type: application/json" \ -d '{ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Idempotency-Key": "quickstart-video-001", "Content-Type": "application/json", }, body: JSON.stringify({ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/generations", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Idempotency-Key": "quickstart-video-001", "Content-Type": "application/json"}, json={ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p", }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` A successful create returns `201` with the queued generation and its estimate: ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "queued", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "estimated_cost": { "amount_usd": "1.64" }, "links": { "self": "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef" } } ``` ## Monitor to a terminal state Read the URL in `links.self` until `status` is `succeeded`, `failed`, `cancelled`, or `manual_review`: ### cURL ```bash curl https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` A succeeded response includes output assets and final usage: ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "succeeded", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:31:14Z", "output": { "assets": [ { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/product-reveal.mp4", "mime_type": "video/mp4", "expires_at": null } ] }, "usage": { "amount_usd": "1.64", "line_items": [ { "type": "video_generation", "model": "seedance-2", "quantity": 1, "unit": "operation", "amount_usd": "1.64" } ], "billing_status": "settled" }, "error": null, "metadata": null } ``` ## Lifecycle, cost, and common errors - `queued` and `running` are active states. Keep reading the generation resource rather than inferring completion from elapsed time. - `succeeded`, `failed`, and `cancelled` are terminal. `manual_review` is terminal for automation and requires operator attention. - The estimated amount is held while the generation runs. Final usage shows the amount charged or released in `usage.amount_usd` and `usage.billing_status`. - `authentication_error` means the API key is missing, invalid, inactive, or revoked. - `idempotency_conflict` means the same key was reused with a different body. - `insufficient_balance` and `rate_limit_exceeded` are explicit failures; inspect the current generation before repeating a paid request. --- # Authentication and authority > Understand Public REST API keys, signed-in Console sessions, and delegated MCP credentials before integrating EntireFeed. Canonical: https://entirefeed.com/docs/get-started/authentication EntireFeed uses separate credentials because each surface represents a different authority model. Select the credential by the route or tool you are calling, not by convenience. ## Authority is surface-specific Public discovery and estimation are unauthenticated. Public execution and organization-scoped API reads use a Public REST API key. Browser Console actions use a signed-in session. Console MCP uses a separately revocable delegated credential for the current user and organization. Never substitute one credential for another. Console routes do not accept an `efapi_live_...` key as a browser session, and Public REST routes do not treat an `efmcp_live_...` credential as an API key. ## Handle secrets once API key and MCP secrets are shown in full when they are created and remain valid until revoked. Store them in a secret manager or local environment variable, name credentials by integration, and revoke credentials that are exposed or no longer needed. ## Credential matrix | Surface | Credential | Authority | | --- | --- | --- | | Public discovery and estimate | `None` | Current public task, model, pricing, and request estimate contracts | | Public REST execution | `efapi_live_...` | Organization-scoped execution and reads; any active REST key for the organization can access its public operations | | Signed-in Console | `Session cookie or Console token` | The current user, organization membership, role, and capabilities | | Console MCP | `efmcp_live_...` | Delegated current-user authority, re-evaluated on every request | ## Public REST API keys Create keys in [Console](https://console.entirefeed.com) and send them as `Authorization: Bearer efapi_live_...`. The key is organization-scoped, is shown in full once, and should be named and revoked per integration. Public discovery and `POST /v1/estimate` do not require it. ## Signed-in Console sessions Passwordless email sign-in establishes a browser session for Console routes. The session acts as the current user in the selected organization and is constrained by current membership, role, and capabilities. Do not export the browser cookie as an integration credential. ## Delegated MCP credentials Create a separate `efmcp_live_...` credential for a trusted MCP client. It delegates the owner's current Console authority and can be revoked independently from browser sessions and REST keys. Membership or role changes take effect when each MCP request resolves. --- # Generate images and video > Discover supported image and video tasks, select an available model when required, and use explicit input contracts. Canonical: https://entirefeed.com/docs/generate EntireFeed exposes stable generation tasks such as `video.create` and `image.edit`. The catalog below lists the tasks, models, and required inputs currently available through the public API. ## Follow the generation journey 1. [Choose a model and task](/docs/generate/models), including model-less processing tasks. 2. [Estimate the exact request](/docs/generate/estimate) without creating media or spending balance. 3. [Create and monitor the generation](/docs/generate/create-and-monitor) when you are ready for paid work. 4. [Cancel or retry](/docs/generate/cancel-and-retry) only after reading the current generation state. ## Choose a task, then a model when required Choose a task for the result you need. Tasks that support models list the available choices and each model's input schema. Tasks that do not use a model omit `model` entirely rather than sending `null`. Use [Quickstart](/docs/get-started/quickstart) for a complete request sequence. Detailed generation lifecycle and operating guides build on this section without changing the task contracts shown here. ## Estimate the exact request `POST /v1/estimate` accepts the same `task`, optional `model`, and `input` object used by generation creation. Estimation creates no media and spends no balance. Use the returned USD amount before any paid `POST /v1/generations` call. ## Current public contract The public catalog currently contains 11 available tasks, 11 available models, and 23 published prices. Coming-soon entries are marked non-runnable. ## Available generation tasks ### `image.create` - Media: image - Availability: Available - Model: `gpt-image-2`, `nano-banana-2`, `nano-banana-2-lite`, `nano-banana-pro`, `seedream-5-pro` - Required input: `prompt` ### `image.edit` - Media: image - Availability: Available - Model: `gpt-image-2`, `nano-banana-2`, `nano-banana-2-lite`, `nano-banana-pro`, `seedream-5-pro` - Required input: `prompt`, `images` ### `social.search` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `platform`, `query` ### `video.add_audio` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video`, `audio` ### `video.concat` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `videos` ### `video.create` - Media: video - Availability: Available - Model: `gemini-omni`, `gemini-omni-flash`, `seedance-2`, `seedance-2-fast`, `seedance-2-mini` - Required input: `prompt` ### `video.extract_audio` - Media: audio - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.extract_frame` - Media: image - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.lipsync` - Media: video - Availability: Available - Model: `sync-lipsync-v3` - Required input: `video`, `audio` ### `video.split_scenes` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.trim` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video`, `end_seconds` --- # Choose a generation task and model > Start with the result you need, select a supported model when required, and build input from the published task schema. Canonical: https://entirefeed.com/docs/generate/models Every request starts with a `task`. Use `image.create`, `image.edit`, `video.create`, or a supported processing task to describe the result you need. Then choose one of that task's available models when the task requires it. ## Read the task before building input `GET /v1/tasks` returns each task's availability, models, variants, input schemas, defaults, and output schema. `GET /v1/models` provides the inverse view: each model and the tasks it supports. For a model-backed task, send both `task` and `model`. For a model-less task, omit `model` entirely. Do not send `null`. ## Apply defaults deliberately Defaults are valid starting values, not hidden request fields. Send explicit values when dimensions, duration, resolution, or processing thresholds matter to your integration. ## Understand social search context `social.search` applies a US search context where the selected platform integration supports country selection. TikTok searches are pinned to the US. The current Instagram Reels and YouTube Shorts integrations do not accept a country or locale, so those searches use the integration's default context and do not guarantee US-localized results. See the generated [models and tasks reference](/docs/reference/models) for complete current schemas and prices. ## Current public contract The public catalog currently contains 11 available tasks, 11 available models, and 23 published prices. Coming-soon entries are marked non-runnable. ## Available generation tasks ### `image.create` - Media: image - Availability: Available - Model: `gpt-image-2`, `nano-banana-2`, `nano-banana-2-lite`, `nano-banana-pro`, `seedream-5-pro` - Required input: `prompt` ### `image.edit` - Media: image - Availability: Available - Model: `gpt-image-2`, `nano-banana-2`, `nano-banana-2-lite`, `nano-banana-pro`, `seedream-5-pro` - Required input: `prompt`, `images` ### `social.search` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `platform`, `query` ### `video.add_audio` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video`, `audio` ### `video.concat` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `videos` ### `video.create` - Media: video - Availability: Available - Model: `gemini-omni`, `gemini-omni-flash`, `seedance-2`, `seedance-2-fast`, `seedance-2-mini` - Required input: `prompt` ### `video.extract_audio` - Media: audio - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.extract_frame` - Media: image - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.lipsync` - Media: video - Availability: Available - Model: `sync-lipsync-v3` - Required input: `video`, `audio` ### `video.split_scenes` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video` ### `video.trim` - Media: video - Availability: Available - Model: Omit `model`; this task is model-less - Required input: `video`, `end_seconds` --- # Estimate a generation request > Price the exact task, model, and input payload before deciding whether to create paid media. Canonical: https://entirefeed.com/docs/generate/estimate `POST /v1/estimate` is public. It requires no API key, creates no media, and spends no balance. ## Estimate the payload you intend to run Send the same `task`, optional `model`, and `input` object you would send to `POST /v1/generations`. This catches unsupported combinations and returns a request-specific USD estimate with line items. Use static prices to understand units. Use the estimate response as the decision point for a concrete request, especially when duration or quantity changes the total. ## Estimate again after input changes Treat an estimate as a snapshot of one payload. Estimate again after changing the task, model, duration, quantity, resolution, or source media. Creation performs its own current estimate before reserving balance. Continue to [Create and monitor](/docs/generate/create-and-monitor) only when the estimated amount is acceptable. ## Estimate a model-backed task `POST /v1/estimate` is public, creates no media, and spends no balance. ### cURL ```bash curl https://api.entirefeed.com/v1/estimate \ -X POST \ -H "Content-Type: application/json" \ -d '{ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/estimate", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/estimate", headers={"Content-Type": "application/json"}, json={ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p", }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` Expected response: ```json { "estimated_cost": { "amount_usd": "1.64" }, "line_items": [ { "type": "video_generation", "model": "seedance-2", "quantity": 1, "unit": "operation", "amount_usd": "1.64" } ] } ``` ## Estimate a model-less task Model-less tasks omit `model` entirely: ### cURL ```bash curl https://api.entirefeed.com/v1/estimate \ -X POST \ -H "Content-Type: application/json" \ -d '{ "task": "video.split_scenes", "input": { "video": { "url": "https://cdn.example.com/source/interview.mp4" }, "threshold": 24, "minimum_scene_length_seconds": 1.5 } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/estimate", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "task": "video.split_scenes", "input": { "video": { "url": "https://cdn.example.com/source/interview.mp4" }, "threshold": 24, "minimum_scene_length_seconds": 1.5 } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/estimate", headers={"Content-Type": "application/json"}, json={ "task": "video.split_scenes", "input": { "video": { "url": "https://cdn.example.com/source/interview.mp4", }, "threshold": 24, "minimum_scene_length_seconds": 1.5, }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "estimated_cost": { "amount_usd": "0.00" }, "line_items": [ { "type": "split_scenes", "model": null, "quantity": 1, "unit": "operation", "amount_usd": "0.00" } ] } ``` --- # Create and monitor a generation > Submit an estimated request with an API key, then read the generation until it reaches a terminal state. Canonical: https://entirefeed.com/docs/generate/create-and-monitor Creation is the first paid step. It requires an organization API key and enough available balance for the current estimate. Running a request in Playground is optional; direct API integrations can create it through REST. ## Create one intended generation Send a stable `Idempotency-Key` with the same payload you estimated. A successful request returns `201`, a `gen_...` identifier, the queued status, the estimated cost, and a `links.self` URL. ## Read until terminal Poll `links.self` while status is `queued` or `running`. Stop when status becomes `succeeded`, `failed`, `cancelled`, or `manual_review`. Successful output contains an ordered `assets` array. Tasks that return structured results also include `output.data`. Asset URLs can expire, so persist finished media according to your own retention requirements. Read [Statuses](/docs/reference/statuses) before automating terminal handling. ## Submit the generation Creation requires an organization API key and sufficient balance. Send a stable `Idempotency-Key` to make uncertain retries safe. ### cURL ```bash curl https://api.entirefeed.com/v1/generations \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: quickstart-video-001" \ -H "Content-Type: application/json" \ -d '{ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Idempotency-Key": "quickstart-video-001", "Content-Type": "application/json", }, body: JSON.stringify({ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p" } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/generations", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Idempotency-Key": "quickstart-video-001", "Content-Type": "application/json"}, json={ "task": "video.create", "model": "seedance-2", "input": { "prompt": "A crisp product reveal on a clean studio set", "duration_seconds": 8, "aspect_ratio": "9:16", "resolution": "720p", }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "queued", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "estimated_cost": { "amount_usd": "1.64" }, "links": { "self": "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef" } } ``` ## Poll the generation resource ### cURL ```bash curl https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "succeeded", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:31:14Z", "output": { "assets": [ { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/product-reveal.mp4", "mime_type": "video/mp4", "expires_at": null } ] }, "usage": { "amount_usd": "1.64", "line_items": [ { "type": "video_generation", "model": "seedance-2", "quantity": 1, "unit": "operation", "amount_usd": "1.64" } ], "billing_status": "settled" }, "error": null, "metadata": null } ``` ## Read output and final usage - Preserve `output.assets` order when a task returns more than one file. - Processing tasks can add machine-readable results under `output.data`. - Read `usage.amount_usd` and `usage.billing_status` together after terminal completion. --- # Cancel or retry a generation > Cancel active work safely and retry eligible failures as new, independently billed generations. Canonical: https://entirefeed.com/docs/generate/cancel-and-retry Cancellation and retry have different cost and identity behavior. Read the current generation before choosing either action. ## Cancel active work `POST /v1/generations/{generation_id}/cancel` requests cancellation for queued or running work. If the generation is already terminal, the endpoint returns its current state. Cancellation does not guarantee a release: final usage depends on whether billable work occurred before cancellation completed. ## Retry only eligible terminal work Only failed or cancelled generations can be retried. Succeeded and manual-review generations cannot. Retry the latest generation in a retry sequence, and wait for any active retry to finish before starting another. A retry accepts no request body overrides. It creates a new generation with a new `gen_...` identifier, a new current estimate, and its own balance reservation. Use a stable `Idempotency-Key` for that retry intent. See [Errors and manual review](/docs/operate/errors-and-manual-review) before retrying an uncertain failure. ## Cancel queued or running work ### cURL ```bash curl https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/cancel \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/cancel", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/cancel", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` Read the returned generation. Cancellation can still produce settled usage when paid work completed before cancellation. ## Retry eligible terminal work Retry only the latest failed or cancelled generation. A retry accepts no body overrides and creates a new paid generation with its own ID and reservation. ### cURL ```bash curl https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/retry \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: retry-product-video-001" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/retry", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Idempotency-Key": "retry-product-video-001", }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/generations/gen_0123456789abcdef0123456789abcdef/retry", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Idempotency-Key": "retry-product-video-001"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "gen_fedcba9876543210fedcba9876543210", "object": "generation", "status": "queued", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T09:10:00Z", "estimated_cost": { "amount_usd": "1.20" }, "links": { "self": "https://api.entirefeed.com/v1/generations/gen_fedcba9876543210fedcba9876543210" } } ``` --- # Run multi-step media workflows > Use versioned Workflow Starters through the API, or build organization-owned workflows in Console. Canonical: https://entirefeed.com/docs/workflows Workflows combine generation and processing into repeatable runs. The self-serve API path is a Workflow Starter: a curated contract you can discover, estimate, run, and monitor without constructing workflow definitions. ## Run a Workflow Starter through the API 1. [Discover a starter and read its versioned contract](/docs/workflows/discover-starters). 2. [Estimate exact inputs, then create one intended run](/docs/workflows/estimate-and-run). 3. [Monitor, cancel, retry, and reconcile final usage](/docs/workflows/monitor-cancel-retry). Every request uses a Public REST API key. Estimation is mandatory before creation, and the run response exposes a stable `wrun_...` ID without implementation details. ## Build a custom workflow Signed-in operators can [build and edit organization-owned workflows](/docs/workflows/build-and-edit) in Console. This path is useful when the published starters do not cover the required sequence. Agents can use supported workflow actions through delegated Console MCP authority. Read [Authentication](/docs/get-started/authentication) before connecting a client. --- # Discover Workflow Starters > Authenticate, list published starters, and read one versioned input and output contract before integration. Canonical: https://entirefeed.com/docs/workflows/discover-starters A Workflow Starter is a curated public contract for a multi-step result. Discovery returns only starters that can accept public inputs, produce the published output, and provide an estimate before a run. Use the returned `slug`, `version`, schemas, requirements, and links as the integration contract. Do not construct workflow definitions or depend on identifiers that are not present in the response. Continue with [Estimate and run](/docs/workflows/estimate-and-run) after validating the selected starter's current input schema. ## Authenticate every starter request Send `Authorization: Bearer $ENTIREFEED_API_KEY` on list, detail, estimate, run, lifecycle, webhook, and billing requests. Create and revoke organization API keys in Console; never expose a key in client-side code. ## List published starters List the currently published starter contracts: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-starters \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-starters", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/workflow-starters", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "data": [ { "id": "text-to-video-basic", "object": "workflow_starter", "slug": "text-to-video-basic", "title": "Text to Video Basic", "description": "Turn one video idea into a finished video.", "category": "video", "version": "st_0123456789abcdef01234567", "input_schema": { "type": "object", "properties": { "video_idea": { "type": "string", "title": "Video idea", "description": "Describe the video to create, including subject, action, and visual direction.", "minLength": 1, "maxLength": 10000 } }, "required": [ "video_idea" ], "additionalProperties": false }, "output_schema": { "type": "object", "properties": { "video": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "const": "video" }, "url": { "type": "string", "format": "uri" }, "mime_type": { "type": [ "string", "null" ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "type", "url" ], "additionalProperties": false } }, "required": [ "video" ], "additionalProperties": false }, "requirements": [], "links": { "self": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic", "estimate": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/estimate", "runs": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/runs" } } ] } ``` ## Read one versioned contract Read the selected starter before constructing inputs. Validate against `input_schema`, plan for `output_schema`, preserve `version`, and follow the returned links: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "text-to-video-basic", "object": "workflow_starter", "slug": "text-to-video-basic", "title": "Text to Video Basic", "description": "Turn one video idea into a finished video.", "category": "video", "version": "st_0123456789abcdef01234567", "input_schema": { "type": "object", "properties": { "video_idea": { "type": "string", "title": "Video idea", "description": "Describe the video to create, including subject, action, and visual direction.", "minLength": 1, "maxLength": 10000 } }, "required": [ "video_idea" ], "additionalProperties": false }, "output_schema": { "type": "object", "properties": { "video": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "const": "video" }, "url": { "type": "string", "format": "uri" }, "mime_type": { "type": [ "string", "null" ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "type", "url" ], "additionalProperties": false } }, "required": [ "video" ], "additionalProperties": false }, "requirements": [], "links": { "self": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic", "estimate": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/estimate", "runs": "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/runs" } } ``` A version changes when the public contract or its execution behavior changes. Re-read the starter and revalidate inputs instead of guessing around a version mismatch. --- # Estimate and run a Workflow Starter > Price exact starter inputs, preserve the returned versions, and create one idempotent workflow run. Canonical: https://entirefeed.com/docs/workflows/estimate-and-run Estimate the exact `inputs`, `starter_version`, and optional `account_id` you intend to run. Estimation creates no media. A run is accepted only when its estimate and starter versions are still current and every paid step has a known cost. Creation is the paid action. Send the estimate response's versions with the same inputs and a stable `Idempotency-Key`. Playground use is optional; direct API integrations follow the same contract. After creation, use the returned `links.self` URL as described in [Monitor, cancel, and retry](/docs/workflows/monitor-cancel-retry). ## Estimate the exact inputs Estimate the exact intended inputs and current starter version. This request creates no media: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/estimate \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background" }, "starter_version": "st_0123456789abcdef01234567" }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/estimate", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background" }, "starter_version": "st_0123456789abcdef01234567" }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/estimate", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Content-Type": "application/json"}, json={ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background", }, "starter_version": "st_0123456789abcdef01234567", }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "object": "workflow_starter_estimate", "starter_slug": "text-to-video-basic", "starter_version": "st_0123456789abcdef01234567", "estimated_cost": { "amount_usd": "1.53" }, "estimated_micro_usd": 1530000, "line_items": [ { "label": "Video generation", "amount_usd": "1.53", "confidence": "exact", "reason": "Calculated from the current starter inputs." } ], "unknown_costs": [], "estimate_version": "estimate_v1" } ``` Use the returned amount as current pricing for this request; example amounts are illustrative. Continue only when `unknown_costs` is empty. ## Create one intended run Creation is paid and requires available balance. Send the same inputs, `starter_version`, and `estimate_version`, plus one `Idempotency-Key` for this intended run: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/runs \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: launch-video-042" \ -H "Content-Type: application/json" \ -d '{ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background" }, "starter_version": "st_0123456789abcdef01234567", "estimate_version": "estimate_v1", "metadata": { "customer_job_id": "launch-video-042" } }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/runs", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Idempotency-Key": "launch-video-042", "Content-Type": "application/json", }, body: JSON.stringify({ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background" }, "starter_version": "st_0123456789abcdef01234567", "estimate_version": "estimate_v1", "metadata": { "customer_job_id": "launch-video-042" } }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/workflow-starters/text-to-video-basic/runs", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Idempotency-Key": "launch-video-042", "Content-Type": "application/json"}, json={ "inputs": { "video_idea": "A slow product reveal with soft daylight and a clean studio background", }, "starter_version": "st_0123456789abcdef01234567", "estimate_version": "estimate_v1", "metadata": { "customer_job_id": "launch-video-042", }, }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "wrun_0123456789abcdef0123456789abcdef", "object": "workflow_run", "status": "queued", "starter_slug": "text-to-video-basic", "starter_version": "st_0123456789abcdef01234567", "created_at": "2026-07-14T08:30:00Z", "estimated_cost": { "amount_usd": "1.53" }, "metadata": { "customer_job_id": "launch-video-042" }, "links": { "self": "https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef" } } ``` ## Replay uncertain requests safely After a timeout or dropped response, repeat the same create request with the same key. The API returns the original `wrun_...` resource instead of creating duplicate work. Changed inputs or metadata require a new key and a new estimate. ## Handle preflight failures - `409 workflow_estimate_required`: Estimate the workflow starter before running it. Estimate before creating the run. - `409 workflow_estimate_stale`: Workflow estimate is stale. Estimate again before running. Estimate the same intended inputs again. - `409 starter_version_stale`: Workflow starter version is stale. Read the starter, revalidate, and estimate again. - `409 idempotency_conflict`: Idempotency-Key was reused with a different request body. Use the original body or a new intent key. - `422 unknown_workflow_cost`: Workflow contains paid steps whose cost cannot be estimated. Stop; the run cannot reserve a known amount. An unpriceable run is rejected before creation: ```json { "error": { "type": "unknown_workflow_cost", "code": "unknown_workflow_cost", "message": "Workflow contains paid steps whose cost cannot be estimated.", "request_id": "req_0123456789abcdef" } } ``` --- # Monitor, cancel, and retry workflow runs > Follow a workflow run to terminal status, cancel active work, retry eligible failures, and reconcile final usage. Canonical: https://entirefeed.com/docs/workflows/monitor-cancel-retry Use the public `wrun_...` identifier for every lifecycle request. Poll while a run is `queued` or `running`; stop automatic polling at `succeeded`, `failed`, `cancelled`, or `manual_review`. Webhooks can replace frequent polling for state changes, but the run resource remains the current source of truth. Final `usage` and billing ledger entries show the settled or released amount for the run. Read [Errors and review](/docs/operate/errors-and-manual-review) before automating retry behavior. ## Poll to a terminal state Poll `links.self` while status is `queued` or `running`. Stop at `succeeded`, `failed`, `cancelled`, `manual_review`: ### cURL ```bash set -euo pipefail API_URL="https://api.entirefeed.com/v1" INPUTS='{"video_idea":"A slow product reveal with soft daylight"}' STARTERS=$(curl -fsS "$API_URL/workflow-starters" \ -H "Authorization: Bearer $ENTIREFEED_API_KEY") STARTER_VERSION=$(printf '%s' "$STARTERS" | jq -r '.data[] | select(.slug == "text-to-video-basic") | .version') ESTIMATE=$(curl -fsS "$API_URL/workflow-starters/text-to-video-basic/estimate" \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Content-Type: application/json" \ -d "$(jq -n --argjson inputs "$INPUTS" --arg version "$STARTER_VERSION" '{inputs: $inputs, starter_version: $version}')") if [ "$(printf '%s' "$ESTIMATE" | jq '.unknown_costs | length')" -ne 0 ]; then printf '%s\n' "Estimate contains unknown costs; run creation stopped." >&2 exit 1 fi ESTIMATE_VERSION=$(printf '%s' "$ESTIMATE" | jq -r '.estimate_version') RUN=$(curl -fsS "$API_URL/workflow-starters/text-to-video-basic/runs" \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: launch-video-042" \ -H "Content-Type: application/json" \ -d "$(jq -n --argjson inputs "$INPUTS" --arg starter "$STARTER_VERSION" --arg estimate "$ESTIMATE_VERSION" '{inputs: $inputs, starter_version: $starter, estimate_version: $estimate}')") RUN_ID=$(printf '%s' "$RUN" | jq -r '.id') while :; do RUN=$(curl -fsS "$API_URL/workflow-runs/$RUN_ID" \ -H "Authorization: Bearer $ENTIREFEED_API_KEY") STATUS=$(printf '%s' "$RUN" | jq -r '.status') case "$STATUS" in succeeded|failed|cancelled|manual_review) break ;; esac sleep 2 done printf '%s' "$RUN" | jq '{status, output, usage}' ``` ### TypeScript ```typescript const apiUrl = "https://api.entirefeed.com/v1"; const terminal = new Set(["succeeded","failed","cancelled","manual_review"]); const baseHeaders = { Authorization: `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Content-Type": "application/json", }; type Starter = { slug: string; version: string }; type Estimate = { estimate_version: string; unknown_costs: string[] }; type Run = { id: string; status: string; output: unknown; usage: unknown }; async function api(path: string, init: RequestInit = {}): Promise { const response = await fetch(`${apiUrl}${path}`, { ...init, headers: { ...baseHeaders, ...init.headers }, }); if (!response.ok) throw new Error(await response.text()); return (await response.json()) as T; } const { data } = await api<{ data: Starter[] }>("/workflow-starters"); const starter = data.find(({ slug }) => slug === "text-to-video-basic"); if (!starter) throw new Error("Starter is not currently published"); const inputs = { video_idea: "A slow product reveal with soft daylight" }; const estimate = await api( "/workflow-starters/text-to-video-basic/estimate", { method: "POST", body: JSON.stringify({ inputs, starter_version: starter.version }) }, ); if (estimate.unknown_costs.length) throw new Error("Cost cannot be determined"); let run = await api("/workflow-starters/text-to-video-basic/runs", { method: "POST", headers: { "Idempotency-Key": "launch-video-042" }, body: JSON.stringify({ inputs, starter_version: starter.version, estimate_version: estimate.estimate_version, }), }); while (!terminal.has(run.status)) { await new Promise((resolve) => setTimeout(resolve, 2000)); run = await api(`/workflow-runs/${run.id}`); } console.log({ status: run.status, output: run.output, usage: run.usage }); ``` ### Python ```python import os import time import requests API_URL = "https://api.entirefeed.com/v1" TERMINAL = set(['succeeded','failed','cancelled','manual_review']) HEADERS = {"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"} starters_response = requests.get( f"{API_URL}/workflow-starters", headers=HEADERS, timeout=30 ) starters_response.raise_for_status() starters = starters_response.json() starter = next(item for item in starters["data"] if item["slug"] == "text-to-video-basic") inputs = {"video_idea": "A slow product reveal with soft daylight"} estimate_response = requests.post( f"{API_URL}/workflow-starters/text-to-video-basic/estimate", headers=HEADERS, json={"inputs": inputs, "starter_version": starter["version"]}, timeout=30, ) estimate_response.raise_for_status() estimate = estimate_response.json() if estimate["unknown_costs"]: raise RuntimeError("Cost cannot be determined") run_response = requests.post( f"{API_URL}/workflow-starters/text-to-video-basic/runs", headers={**HEADERS, "Idempotency-Key": "launch-video-042"}, json={ "inputs": inputs, "starter_version": starter["version"], "estimate_version": estimate["estimate_version"], }, timeout=30, ) run_response.raise_for_status() run = run_response.json() while run["status"] not in TERMINAL: time.sleep(2) run_response = requests.get( f"{API_URL}/workflow-runs/{run['id']}", headers=HEADERS, timeout=30 ) run_response.raise_for_status() run = run_response.json() print({"status": run["status"], "output": run.get("output"), "usage": run["usage"]}) ``` ```json { "id": "wrun_0123456789abcdef0123456789abcdef", "object": "workflow_run", "status": "succeeded", "starter_slug": "text-to-video-basic", "starter_version": "st_0123456789abcdef01234567", "created_at": "2026-07-14T08:30:00Z", "started_at": "2026-07-14T08:30:03Z", "completed_at": "2026-07-14T08:31:20Z", "output": { "video": { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/launch-video.mp4", "mime_type": "video/mp4", "expires_at": null } }, "usage": { "amount_usd": "1.47", "line_items": [ { "label": "Video generation", "amount_usd": "1.47", "confidence": "exact", "reason": "Final cost confirmed after completion." } ], "billing_status": "settled", "billing_reason": "final_cost_confirmed" }, "error": null, "metadata": { "customer_job_id": "launch-video-042" }, "links": { "self": "https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef" } } ``` ## Cancel active work Cancel queued or running work. Cancellation is a request, so read the returned run and continue polling if it has not reached `cancelled`: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/cancel \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reason": "Campaign was paused" }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/cancel", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ "reason": "Campaign was paused" }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/cancel", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Content-Type": "application/json"}, json={ "reason": "Campaign was paused", }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ## Retry eligible terminal work Retry only the latest failed or cancelled run after work started and when its retry lineage has no active run. A retry is new work with a new public ID and requires its own `Idempotency-Key`: ### cURL ```bash curl https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/retry \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Idempotency-Key: launch-video-042-retry-1" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/retry", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Idempotency-Key": "launch-video-042-retry-1", }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef/retry", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Idempotency-Key": "launch-video-042-retry-1"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "wrun_fedcba9876543210fedcba9876543210", "object": "workflow_run", "status": "queued", "starter_slug": "text-to-video-basic", "starter_version": "st_0123456789abcdef01234567", "created_at": "2026-07-14T08:35:00Z", "estimated_cost": { "amount_usd": "1.53" }, "metadata": { "customer_job_id": "launch-video-042" }, "links": { "self": "https://api.entirefeed.com/v1/workflow-runs/wrun_fedcba9876543210fedcba9876543210" } } ``` After an uncertain response, replay the same source run and key to recover the original retry. Reusing that key for another source returns `idempotency_conflict`. If a newer retry exists, operate on the latest run instead. ## Receive signed run events Register the run events you need. The signing secret is returned once: ### cURL ```bash curl https://api.entirefeed.com/v1/webhooks/endpoints \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/entirefeed", "events": [ "workflow_run.succeeded", "workflow_run.failed", "workflow_run.cancelled", "workflow_run.manual_review" ] }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/webhooks/endpoints", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ "url": "https://example.com/webhooks/entirefeed", "events": [ "workflow_run.succeeded", "workflow_run.failed", "workflow_run.cancelled", "workflow_run.manual_review" ] }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/webhooks/endpoints", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Content-Type": "application/json"}, json={ "url": "https://example.com/webhooks/entirefeed", "events": [ "workflow_run.succeeded", "workflow_run.failed", "workflow_run.cancelled", "workflow_run.manual_review", ], }, timeout=30, ) response.raise_for_status() print(response.json()) ``` Supported events are `workflow_run.queued`, `workflow_run.running`, `workflow_run.succeeded`, `workflow_run.failed`, `workflow_run.cancelled`, `workflow_run.manual_review`. Omitting `events` uses the endpoint defaults: `generation.succeeded`, `generation.failed`, `workflow_run.succeeded`, `workflow_run.failed`. ```json { "id": "f419d0cf-5d8e-4b4c-82bb-6042b17e68f8", "url": "https://example.com/webhooks/entirefeed", "events": [ "workflow_run.succeeded", "workflow_run.failed", "workflow_run.cancelled", "workflow_run.manual_review" ], "secret": "whsec_store_this_value_once" } ``` Verify `EntireFeed-Signature` against the exact raw body before parsing, store `EntireFeed-Event-ID`, and return `2xx` after durable receipt: ### TypeScript ```typescript import { createHmac, timingSafeEqual } from "node:crypto"; const parts = Object.fromEntries( signatureHeader.split(",").map((part) => part.split("=", 2)), ); const timestamp = Number(parts.t); const received = Buffer.from(parts.v1 ?? "", "hex"); const expected = Buffer.from( createHmac("sha256", process.env.ENTIREFEED_WEBHOOK_SECRET!) .update(Buffer.concat([Buffer.from(String(timestamp) + "."), rawBody])) .digest("hex"), "hex", ); const fresh = Math.abs(Date.now() / 1000 - timestamp) <= 300; const valid = fresh && received.length === expected.length && timingSafeEqual(received, expected); ``` ### Python ```python import hashlib import hmac import os import time parts = dict(part.split("=", 1) for part in signature_header.split(",")) timestamp = int(parts["t"]) signed = f"{timestamp}.".encode() + raw_body expected = hmac.new( os.environ["ENTIREFEED_WEBHOOK_SECRET"].encode(), signed, hashlib.sha256, ).hexdigest() fresh = abs(time.time() - timestamp) <= 300 valid = fresh and hmac.compare_digest(parts["v1"], expected) ``` ```json { "id": "evt_0123456789abcdef0123456789abcdef", "type": "workflow_run.succeeded", "created_at": "2026-07-14T08:31:20Z", "data": { "object": { "id": "wrun_0123456789abcdef0123456789abcdef", "object": "workflow_run", "status": "succeeded", "starter_slug": "text-to-video-basic", "starter_version": "st_0123456789abcdef01234567", "created_at": "2026-07-14T08:30:00Z", "started_at": "2026-07-14T08:30:03Z", "completed_at": "2026-07-14T08:31:20Z", "output": { "video": { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/launch-video.mp4", "mime_type": "video/mp4", "expires_at": null } }, "usage": { "amount_usd": "1.47", "line_items": [ { "label": "Video generation", "amount_usd": "1.47", "confidence": "exact", "reason": "Final cost confirmed after completion." } ], "billing_status": "settled", "billing_reason": "final_cost_confirmed" }, "error": null, "metadata": { "customer_job_id": "launch-video-042" }, "links": { "self": "https://api.entirefeed.com/v1/workflow-runs/wrun_0123456789abcdef0123456789abcdef" } } } } ``` ## Reconcile final usage The terminal run's `usage` is the run-level billing outcome. Filter the ledger by `workflow_run_id` to reconcile reservation, settlement, and release entries: ### cURL ```bash curl https://api.entirefeed.com/v1/billing/ledger?workflow_run_id=wrun_0123456789abcdef0123456789abcdef \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/billing/ledger?workflow_run_id=wrun_0123456789abcdef0123456789abcdef", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/billing/ledger?workflow_run_id=wrun_0123456789abcdef0123456789abcdef", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "data": [ { "id": "2f55ef4d-1f48-45db-9406-23754a3287ba", "type": "RESERVE", "amount_usd": "-1.53", "available_after_usd": "8.47", "reserved_after_usd": "1.53", "workflow_run_id": "wrun_0123456789abcdef0123456789abcdef", "description": "Reserved estimated operation cost.", "created_at": "2026-07-14T08:30:00Z" }, { "id": "923fce22-42b1-4c74-8dc7-fafaf8fd64c4", "type": "SETTLE", "amount_usd": "-1.47", "available_after_usd": "8.47", "reserved_after_usd": "0.06", "workflow_run_id": "wrun_0123456789abcdef0123456789abcdef", "description": "Settled final operation cost.", "created_at": "2026-07-14T08:31:20Z" }, { "id": "f0d251ef-a44f-41c3-b2f8-9d8db0ac9505", "type": "RELEASE", "amount_usd": "0.06", "available_after_usd": "8.53", "reserved_after_usd": "0.00", "workflow_run_id": "wrun_0123456789abcdef0123456789abcdef", "description": "Released unused reservation.", "created_at": "2026-07-14T08:31:20Z" } ], "next_cursor": null } ``` --- # Build and edit custom workflows > Use Console for organization-owned workflows when a published Workflow Starter does not cover the required sequence. Canonical: https://entirefeed.com/docs/workflows/build-and-edit Custom workflows are a signed-in Console surface. They are separate from the public Workflow Starter API: creating or editing a custom workflow does not publish a new starter or create a public starter contract. ## Choose the right path Use a Workflow Starter when its published input and output schemas match the result you need. The starter API is the shortest self-serve path because discovery, pricing, execution, and lifecycle handling use stable public resources. Use a custom workflow when an operator needs to arrange a different sequence, configure steps, or reuse organization-specific setup. ## Build and edit in Console Create or open a workflow in Console, make the required changes, and save deliberately. Editing alone does not run paid work. Estimate the current saved workflow before deciding whether to run it, and estimate again after execution-affecting changes. Custom workflows stay scoped to the signed-in organization. Their editing surface and permissions are governed by the current user's Console access. ## Connect an agent A trusted agent can discover and operate supported custom workflow actions through a delegated MCP credential. The credential uses the owner's current authority and can be revoked independently. Start with [Connect Console MCP](/docs/agents/connect), then read [Tasks and workflows](/docs/agents/tasks-and-workflows). Discovery and read actions can be used without starting a paid run. --- # Connect EntireFeed to your agent > Use Console MCP to let a trusted agent operate supported generation, workflow, and publishing tools with delegated current-user authority. Canonical: https://entirefeed.com/docs/agents Console MCP gives a trusted client a separately revocable `efmcp_live_...` credential. Each request resolves against the credential owner's current organization membership and capabilities. The current tool catalog includes generation task discovery, estimates, generation status, workflows, and publishing actions. Load the current tool schemas rather than relying on a fixed tool list. ## Delegate Console authority Create the MCP credential while signed in, add the hosted server to your client, and load the server's operating guidance before making changes or starting paid work. Role changes, membership removal, organization deletion, and credential revocation affect access immediately. Do not put a Public REST API key in MCP configuration. REST keys authorize public API operations; MCP credentials delegate the signed-in Console user's supported tools. Continue with [Connect an MCP client](/docs/agents/connect), then use [Tasks and workflows](/docs/agents/tasks-and-workflows) for read, estimate, run, and lifecycle sequences. ## Keep paid actions explicit An agent should inspect the relevant contract and estimate paid work before execution. Human review remains appropriate for ambiguous requests, publishing decisions, and operations whose cost or output cannot be confirmed in advance. Use [Paid actions and review](/docs/agents/paid-actions-and-review) for approval, idempotency, capability, and revocation behavior. --- # Connect an MCP client > Create a delegated Console MCP credential, configure a trusted client, verify read-only access, and revoke it safely. Canonical: https://entirefeed.com/docs/agents/connect Console MCP is a hosted remote server. You do not need to install a package, clone a server, or expose a local process. Create a separate credential for each trusted client or environment. The credential is displayed in full after creation and remains valid until you revoke it; it is not a single-use key. Connection verification is read-only. You do not need to run a workflow, create media, or schedule a post to confirm that the client is connected. ## Create a delegated credential Open [Console MCP settings](https://console.entirefeed.com/mcp) while signed in to the organization the agent should operate. Create a named credential for one trusted client or environment. - The credential starts with `efmcp_live_...` and is separate from Public REST API keys. - Its full value is displayed after creation. Store it then; the value remains valid until revoked. - Create separate credentials for separate clients so access can be revoked independently. ## Configure the MCP client Use the hosted Streamable HTTP endpoint `https://api.entirefeed.com/mcp/`. Console provides setup instructions for Claude Code, Codex, Cursor, GitHub Copilot, Windsurf, and other remote MCP clients. Keep the bearer credential in a local-only secret or environment variable and out of committed files. ### Remote HTTP connection ```json { "name": "entirefeed-console", "transport": "streamable-http", "url": "https://api.entirefeed.com/mcp/", "headers": { "Authorization": "Bearer " } } ``` ### Codex config ```toml [mcp_servers.entirefeed-console] url = "https://api.entirefeed.com/mcp/" bearer_token_env_var = "ENTIREFEED_MCP_TOKEN" ``` ### Local environment ```shell export ENTIREFEED_MCP_TOKEN="" ``` ## Verify access without spending Restart or refresh the client, confirm that `entirefeed-console` can list tools, then make one read-only guidance call. This verifies the connection without creating media, running a workflow, or changing a post: ### get_console_agent_best_practices ```json { "tool": "get_console_agent_best_practices", "arguments": { "topic": "topics" } } ``` ## Rotate or revoke access Revoke an exposed, unused, or retired credential from [Console MCP settings](https://console.entirefeed.com/mcp). Revocation takes effect on the next request. A replacement credential requires updating the client secret and reconnecting. - Authority: Delegated current-user authority. - Organization: The organization where the credential was created. - Evaluation: Current membership, role, and capabilities on every request. - Revocation: Rejected immediately after revocation. --- # Run tasks and workflows with an agent > Discover compact MCP resources, load one detailed contract, estimate paid work, start it deliberately, and follow its lifecycle. Canonical: https://entirefeed.com/docs/agents/tasks-and-workflows Use list tools for compact discovery, then fetch one task, workflow, starter, generation, or run when you need its full contract. This keeps agent context focused and avoids acting on stale summaries. A generation task creates or processes media directly. A workflow starter exposes a curated input and output contract. A Console workflow is an organization-owned reusable graph and must be read before edits or runs so the current `definition_hash` can guard the action. ## Discover compact resources first - Generation: list compact tasks or models, then get one task for its schemas and defaults. - Workflow starters: list compact starters, then get one starter for its current input and output contract. - Console workflows: list or search, then get one workflow before editing, estimating, or running it. - Existing work: list compact generations or runs, then get one resource for output, usage, and errors. ## Estimate and run a generation Use the exact task, optional model, and input from the estimate when creating. The create call is optional and should happen only after the estimate is accepted. Supply a stable caller-generated idempotency key: ### list_console_generation_tasks ```json { "tool": "list_console_generation_tasks", "arguments": {} } ``` ### get_console_generation_task ```json { "tool": "get_console_generation_task", "arguments": { "task_id": "video.create" } } ``` ### estimate_console_generation ```json { "tool": "estimate_console_generation", "arguments": { "task": "video.create", "model": "seedance-2", "input": { "prompt": "A clean product reveal on a studio table.", "duration_seconds": 4, "aspect_ratio": "9:16", "resolution": "1080p" } } } ``` ### create_console_generation ```json { "tool": "create_console_generation", "arguments": { "task": "video.create", "model": "seedance-2", "input": { "prompt": "A clean product reveal on a studio table.", "duration_seconds": 4, "aspect_ratio": "9:16", "resolution": "1080p" }, "idempotency_key": "campaign-42-product-reveal-v1" } } ``` ### get_console_generation ```json { "tool": "get_console_generation", "arguments": { "generation_id": "gen_0123456789abcdef0123456789abcdef" } } ``` ## Run a workflow starter Use a starter returned by discovery. Pass the `estimate_version` returned for the same starter version and inputs into the run call; do not invent or reuse an old estimate version: ### list_public_workflow_starters ```json { "tool": "list_public_workflow_starters", "arguments": {} } ``` ### get_public_workflow_starter ```json { "tool": "get_public_workflow_starter", "arguments": { "starter_slug": "" } } ``` ### estimate_public_workflow_starter_run ```json { "tool": "estimate_public_workflow_starter_run", "arguments": { "starter_slug": "", "inputs": { "brief": "Create a short vertical product reel." } } } ``` ### run_public_workflow_starter ```json { "tool": "run_public_workflow_starter", "arguments": { "starter_slug": "", "estimate_version": "estimate_v1", "idempotency_key": "campaign-42-starter-v1", "inputs": { "brief": "Create a short vertical product reel." } } } ``` ### get_public_workflow_run ```json { "tool": "get_public_workflow_run", "arguments": { "workflow_run_id": "wrun_0123456789abcdef0123456789abcdef" } } ``` ## Run a Console workflow Read the workflow first and pass its returned `definition_hash` as `expected_definition_hash` to estimate and run. Pass the estimate response's `estimate_version` into the run call: ### list_console_workflows ```json { "tool": "list_console_workflows", "arguments": {} } ``` ### get_console_workflow ```json { "tool": "get_console_workflow", "arguments": { "workflow_id": "11111111-1111-4111-8111-111111111111" } } ``` ### estimate_console_workflow_run ```json { "tool": "estimate_console_workflow_run", "arguments": { "workflow_id": "11111111-1111-4111-8111-111111111111", "expected_definition_hash": "sha256:current-definition-hash", "inputs": { "brief": "Create a short vertical product reel." } } } ``` ### run_console_workflow ```json { "tool": "run_console_workflow", "arguments": { "workflow_id": "11111111-1111-4111-8111-111111111111", "expected_definition_hash": "sha256:current-definition-hash", "estimate_version": "estimate_v1", "idempotency_key": "campaign-42-workflow-v1", "inputs": { "brief": "Create a short vertical product reel." } } } ``` ### get_console_workflow_run ```json { "tool": "get_console_workflow_run", "arguments": { "run_id": "55555555-5555-4555-8555-555555555555" } } ``` ## Follow lifecycle and output - Use the returned generation or run ID for subsequent reads; do not infer completion from elapsed time. - Continue reading while work is queued or running. On success, inspect output and final usage before the next action. - On failure or cancellation, inspect the current resource before deciding whether a retry is intended. - A retry creates new paid work. Give it a new caller-generated idempotency key for that retry intent. - Stop automation on manual review or ambiguous output and preserve the resource ID for the user. Retry only after inspecting a failed or cancelled resource. Each retry below is new paid work and has its own intent key: ### retry_console_generation ```json { "tool": "retry_console_generation", "arguments": { "generation_id": "gen_0123456789abcdef0123456789abcdef", "idempotency_key": "campaign-42-product-reveal-retry-1" } } ``` ### retry_console_workflow_run ```json { "tool": "retry_console_workflow_run", "arguments": { "run_id": "55555555-5555-4555-8555-555555555555", "idempotency_key": "campaign-42-workflow-retry-1" } } ``` ### retry_public_workflow_run ```json { "tool": "retry_public_workflow_run", "arguments": { "workflow_run_id": "wrun_0123456789abcdef0123456789abcdef", "idempotency_key": "campaign-42-starter-retry-1" } } ``` --- # Approve paid actions and review results > Apply current delegated authority, estimate before spending, use idempotency keys, and stop for review when intent or output is uncertain. Canonical: https://entirefeed.com/docs/agents/paid-actions-and-review Connecting an agent does not approve paid execution. Unless the current instruction explicitly delegates autonomous paid work for the relevant scope, the agent should present the estimate and obtain approval before creating a generation or running a workflow. Approval is an operating instruction, not a separate token or server-side approval gate. Current organization membership, role, and capabilities still determine whether each tool call is allowed. ## Apply current delegated authority An MCP credential delegates the current user in the organization where the credential was created. Membership, role, capabilities, and revocation are evaluated for every request; creating a credential does not grant additional access. | Action | Required capability | | --- | --- | | Discover and inspect generation | `generations:read` | | Estimate, create, or retry generation | `playground:run` | | Prepare a local media upload | `workflows:run` | | Cancel generation | `generations:cancel` | | Read, edit, or run workflows | `workflows:read, workflows:manage, workflows:run` | | Read or edit publishing drafts | `publishing:read, publishing:manage` | | Schedule, reschedule, or cancel | `publishing:schedule` | | Read publishing analytics | `publishing:analytics:read` | ## Estimate, then confirm paid work 1. Discover the current task, starter, or workflow contract. 2. Estimate the exact input that would run. 3. Present the estimated amount and intended output unless autonomous paid execution was explicitly delegated for this scope. 4. Create or run only after that decision. A read-only connection test never requires paid work. Approval is an instruction between the user and agent. There is no separate approval token to pass to a tool, and connection alone is not approval. ## Give every paid write an intent key - Generate one stable idempotency key for each intended generation create, generation retry, workflow run, or workflow retry. - Reuse that key only when replaying the same tool call after an uncertain response. - Use a new key for changed inputs, a new run, or a deliberate retry because each is new paid work. - Publishing mutations do not accept idempotency keys. Re-read the post or scheduled action before repeating one. ## Stop at review boundaries - Review generated assets, structured output, final usage, and errors before feeding output into another paid action. - Review workflow output and the current workflow hash before edits, pins, unpins, or another run. - Require explicit account, media, caption, time, and timezone confirmation before scheduling, rescheduling, or cancelling publication. - Stop and ask when intent is ambiguous, the estimate changed, the requested capability is unavailable, or a resource requires manual review. --- # Publish and schedule reviewed media > Use signed-in Console and supported MCP tools to move generated assets into connected publishing accounts and schedules. Canonical: https://entirefeed.com/docs/publishing Generation and publishing are separate operations. A successful media generation produces assets; publishing selects reviewed assets, connected accounts, timing, and post state through the supported Console surface. ## Use Console authority Publishing management is a signed-in Console capability. A trusted agent can use the publishing tools exposed by Console MCP when its delegated user and organization currently have permission. Public REST API keys are not publishing credentials. Do not send `efapi_live_...` keys to Console publishing routes or MCP clients. Start with [Accounts and posts](/docs/publishing/accounts-and-posts) to select a publishable account and create or edit a draft. Use [Schedules](/docs/publishing/schedules) only after the media, account, caption, time, and timezone are explicit. ## Review before distribution Inspect output assets and account selection before scheduling or publishing. Treat rescheduling, cancellation, retries, and failed delivery as explicit lifecycle actions rather than assuming a generation's status controls a post. --- # Work with publishing accounts and posts > Select an account that can publish, create a TikTok draft from reviewed HTTPS media, and inspect or update it before scheduling. Canonical: https://entirefeed.com/docs/publishing/accounts-and-posts Publishing starts with a connected account and a draft. MCP currently creates TikTok drafts with `VIDEO`, `IMAGE`, or `CAROUSEL` content and HTTPS media URLs. Creating or updating a draft does not schedule or publish it. Always read `can_publish` and `publish_unavailable_reason` from account discovery. For an existing post, use the compact list to find it and then load its full detail before changing captions, media, or account selection. ## Find an account that can publish List accounts before creating a post for an unfamiliar account. Proceed only when the selected account returns `can_publish: true`; otherwise show `publish_unavailable_reason` and stop: ### list_console_publishing_accounts ```json { "tool": "list_console_publishing_accounts", "arguments": {} } ``` ### list_console_publishing_posts ```json { "tool": "list_console_publishing_posts", "arguments": { "account_id": "33333333-3333-4333-8333-333333333333", "limit": 20, "sort": "updated_desc" } } ``` ```json { "accounts": [ { "id": "33333333-3333-4333-8333-333333333333", "platform": "TIKTOK", "username": "brandstudio", "is_active": true, "is_verified": true, "can_publish": true, "publish_unavailable_reason": null } ], "count": 1 } ``` ## Create a draft from reviewed media Draft creation currently accepts `TIKTOK` with `VIDEO`, `IMAGE`, `CAROUSEL` content. Every media URL must use HTTPS. Creation does not schedule or publish the draft: ### create_console_publishing_post ```json { "tool": "create_console_publishing_post", "arguments": { "account_id": "33333333-3333-4333-8333-333333333333", "platform": "TIKTOK", "content_type": "VIDEO", "media_urls": [ "https://cdn.example.com/product-reveal.mp4" ], "caption": "A closer look at the new release.", "hashtags": [ "launch", "product" ] } } ``` ```json { "post": { "id": "22222222-2222-4222-8222-222222222222", "platform": "TIKTOK", "content_type": "VIDEO", "status": "DRAFT", "media_urls": [ "https://cdn.example.com/product-reveal.mp4" ], "caption": "A closer look at the new release." }, "next": "Use schedule_console_publishing_post when the draft is approved." } ``` ## Inspect and update the draft Use the compact post list for discovery, then get the full post before updating it. Omitted patch fields stay unchanged; explicit `null` clears nullable fields. Re-read after the write, and re-read before repeating a mutation after an uncertain response: ### get_console_publishing_post (before edit) ```json { "tool": "get_console_publishing_post", "arguments": { "post_id": "22222222-2222-4222-8222-222222222222" } } ``` ### update_console_publishing_post ```json { "tool": "update_console_publishing_post", "arguments": { "post_id": "22222222-2222-4222-8222-222222222222", "patch": { "caption": "A closer look at the new release. Available now.", "hashtags": [ "launch", "product", "newrelease" ] } } } ``` ### get_console_publishing_post (after edit) ```json { "tool": "get_console_publishing_post", "arguments": { "post_id": "22222222-2222-4222-8222-222222222222" } } ``` ## Understand post status | Status | Phase | Required action | | --- | --- | --- | | `DRAFT`, `PENDING_REVIEW`, `APPROVED` | Preparation | Review the full post and account availability before scheduling. | | `SCHEDULED`, `QUEUED`, `PUBLISHING` | Active | Read the current post and scheduled action; do not schedule it again. | | `PUBLISHED` | Complete | Read the post and analytics; no further scheduling action is needed. | | `FAILED` | Failed | Inspect the post and error before deciding whether new scheduling is intended. | | `ARCHIVED` | Terminal | Do not schedule an archived post. | --- # Schedule, reschedule, or cancel a post > Schedule an approved draft at an explicit time and IANA timezone, then use the scheduled action ID for later changes. Canonical: https://entirefeed.com/docs/publishing/schedules Scheduling is a separate mutation from draft creation. Confirm the post, account, media, caption, exact time, and IANA timezone before calling the schedule tool. MCP intentionally does not expose a publish-now action. The schedule response returns a `scheduled_post_id`. Keep that ID: reschedule and cancel operations require it and cannot infer a scheduled action from a post ID. ## Schedule at an explicit local time Schedule only after the user confirms the draft and exact time. Supply an ISO 8601 `scheduled_for` value and an IANA timezone. The response returns the scheduled action ID used for later changes: ### schedule_console_publishing_post ```json { "tool": "schedule_console_publishing_post", "arguments": { "post_id": "22222222-2222-4222-8222-222222222222", "scheduled_for": "2030-07-15T10:00:00+09:00", "timezone": "Asia/Tokyo" } } ``` ```json { "scheduled_post": { "id": "44444444-4444-4444-8444-444444444444", "post_id": "22222222-2222-4222-8222-222222222222", "scheduled_for": "2030-07-15T01:00:00Z", "display_scheduled_for": "2030-07-15T10:00:00+09:00", "timezone": "Asia/Tokyo", "status": "PENDING" } } ``` ## Reschedule by scheduled action ID Reschedule only a `PENDING`, `QUEUED`, `CLAIMED`, `FAILED` action. Use its `scheduled_post_id`, not its post ID, and confirm the replacement time and timezone: ### reschedule_console_publishing_scheduled_post ```json { "tool": "reschedule_console_publishing_scheduled_post", "arguments": { "scheduled_post_id": "44444444-4444-4444-8444-444444444444", "scheduled_for": "2030-07-15T13:00:00+09:00", "timezone": "Asia/Tokyo" } } ``` ## Cancel without deleting the draft Cancellation uses the scheduled action ID and leaves the draft post intact. Confirm the cancellation, then re-read before repeating it after an uncertain response: ### cancel_console_publishing_scheduled_post ```json { "tool": "cancel_console_publishing_scheduled_post", "arguments": { "scheduled_post_id": "44444444-4444-4444-8444-444444444444" } } ``` ## Inspect status and analytics Scheduled statuses: `PENDING`, `QUEUED`, `CLAIMED`, `RUNNING`, `COMPLETED`, `FAILED`, `CANCELLED`, `SKIPPED`. Use compact schedule and analytics reads to inspect current state; do not infer success from the requested time: ### list_console_publishing_scheduled_posts ```json { "tool": "list_console_publishing_scheduled_posts", "arguments": { "statuses": [ "PENDING", "QUEUED", "CLAIMED", "FAILED" ], "limit": 50 } } ``` ### get_console_publishing_schedule_board ```json { "tool": "get_console_publishing_schedule_board", "arguments": { "activity_since": "2026-07-01T00:00:00Z", "limit": 50 } } ``` ### get_console_publishing_analytics_summary ```json { "tool": "get_console_publishing_analytics_summary", "arguments": { "from_time": "2026-07-01T00:00:00Z", "to_time": "2026-07-31T23:59:59Z" } } ``` ### get_console_publishing_analytics_timeseries ```json { "tool": "get_console_publishing_analytics_timeseries", "arguments": { "from_time": "2026-07-01T00:00:00Z", "to_time": "2026-07-31T23:59:59Z", "interval": "day" } } ``` ### get_console_publishing_analytics_breakdown ```json { "tool": "get_console_publishing_analytics_breakdown", "arguments": { "group_by": "status", "from_time": "2026-07-01T00:00:00Z" } } ``` MCP has no publish-now tool. Draft creation and scheduling remain separate, reviewable actions. --- # Operate lifecycle, usage, and failures > Monitor operation status, settled usage, billing reads, webhooks, idempotency, retries, and manual-review outcomes. Canonical: https://entirefeed.com/docs/operate Every paid request has a status and a cost lifecycle. Estimate first, then monitor the request until it finishes; final usage shows the amount charged or released. ## Choose an operating guide - [Billing and usage](/docs/operate/billing-and-usage) explains available balance, reservations, final usage, and ledger reads. - [Webhooks](/docs/operate/webhooks) covers registration, signature verification, event handling, and delivery retries. - [Idempotency and rate limits](/docs/operate/idempotency-and-rate-limits) prevents duplicate paid work and retry storms. - [Errors and manual review](/docs/operate/errors-and-manual-review) maps failures to safe next actions. ## Read the current status Read the generation or workflow-run resource until it reaches a terminal state. Do not infer completion from elapsed time or a local UI state. Treat `manual_review` as a deliberate outcome that requires operator attention. ## Make writes idempotent Use a stable `Idempotency-Key` for each intended create or retry. Reusing a key for the same request returns the existing operation; changing the request while reusing a key is an integration error. Start with [Quickstart](/docs/get-started/quickstart) to see the lifecycle and settled usage fields together. Public billing endpoints are read-only; top-ups and payment management remain signed-in Console actions. --- # Understand billing and usage > Follow available and reserved balance through estimate, reservation, settlement, release, and ledger records. Canonical: https://entirefeed.com/docs/operate/billing-and-usage EntireFeed uses prepaid usage billing. Estimation is free. Creating a paid generation reserves its current estimate from available balance while work is active. ## Read balance without changing it `GET /v1/billing/summary` returns `available`, `reserved`, and `total` USD amounts. `GET /v1/billing/ledger` returns immutable balance movements and supports cursor, type, date, and generation filters. Public API keys can only read billing data. Adding balance and managing payment methods remain signed-in Console actions. ## Reconcile each generation Read `usage.billing_status` on the generation. `reserved` means the estimate is still held. `settled` means usage was charged. `released` means held balance returned to available balance. `manual_review` means automation must stop until the cost is resolved. The ledger is the audit trail. A single generation can produce a reserve followed by settlement, release, or a bounded adjustment. When final cost exceeds the reservation, any extra debit is capped at the current available balance and cannot make that balance negative. ## Read available and reserved balance ### cURL ```bash curl https://api.entirefeed.com/v1/billing/summary \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/billing/summary", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/billing/summary", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "available": { "amount_usd": "23.80" }, "reserved": { "amount_usd": "1.20" }, "total": { "amount_usd": "25.00" }, "currency": "usd" } ``` ## Read the usage ledger ### cURL ```bash curl https://api.entirefeed.com/v1/billing/ledger?generation_id=gen_0123456789abcdef0123456789abcdef \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/billing/ledger?generation_id=gen_0123456789abcdef0123456789abcdef", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/billing/ledger?generation_id=gen_0123456789abcdef0123456789abcdef", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "data": [ { "id": "8e2dc660-4b75-4a51-9176-6d70fe0b2c08", "type": "RESERVE", "amount_usd": "-1.20", "available_after_usd": "23.80", "reserved_after_usd": "1.20", "generation_id": "gen_0123456789abcdef0123456789abcdef", "description": "Reserved estimated operation cost.", "created_at": "2026-07-12T08:30:00Z" } ], "next_cursor": null } ``` ## Interpret billing status | Status | Meaning | Balance behavior | | --- | --- | --- | | `reserved` | The current estimate is held while work is active. | Included in reserved balance, not available balance. | | `settled` | Final usage was charged. | The settled amount remains spent; unused hold can be released. | | `released` | The held amount was returned. | Released funds are available again. | | `manual_review` | Final cost could not be resolved automatically. | The hold remains unavailable until resolution. | ## Reconcile releases and bounded adjustments | Scenario | Amounts | Result | | --- | --- | --- | | Final cost below reservation | $1.20 reserved; $0.90 final | Settle $0.90 and release $0.30 to available balance. | | Overage covered | $1.20 reserved; $1.50 final; at least $0.30 available | Settle $1.20 and debit a $0.30 adjustment. | | Overage capped | $1.20 reserved; $1.50 final; $0.20 available | Settle $1.20 and debit a $0.20 adjustment. Available balance stops at $0.00. | Additional debit is capped at the current `available_balance` and cannot create a negative balance. --- # Receive generation webhooks > Register an HTTPS endpoint, verify signed generation events, and handle retries without duplicate work. Canonical: https://entirefeed.com/docs/operate/webhooks Webhooks notify your integration when a generation changes state. Register only the generation events you need and continue to treat the generation resource as the current source of truth. ## Register a public HTTPS endpoint Create an endpoint with an organization API key. The URL must use public HTTPS and must not resolve to a private or local address. The response returns a `whsec_...` signing secret once; store it securely. ## Verify before processing Verify `EntireFeed-Signature` against the exact raw request body before parsing JSON. The signed message is the timestamp, a period, and the raw body using HMAC-SHA256. Also record `EntireFeed-Event-ID` and ignore duplicate event IDs. ## Return success promptly Return any `2xx` response after durable receipt. Failed deliveries are retried with the same event ID. Make your handler idempotent and fetch the generation when your workflow needs the latest state. Only the generation events listed in the [webhook reference](/docs/reference/webhooks) are currently supported. ## Register an endpoint The endpoint response returns its `whsec_...` signing secret once. ### cURL ```bash curl https://api.entirefeed.com/v1/webhooks/endpoints \ -X POST \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/entirefeed", "events": [ "generation.succeeded", "generation.failed", "generation.manual_review" ] }' ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/webhooks/endpoints", { method: "POST", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ "url": "https://example.com/webhooks/entirefeed", "events": [ "generation.succeeded", "generation.failed", "generation.manual_review" ] }), }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "POST", "https://api.entirefeed.com/v1/webhooks/endpoints", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}", "Content-Type": "application/json"}, json={ "url": "https://example.com/webhooks/entirefeed", "events": [ "generation.succeeded", "generation.failed", "generation.manual_review", ], }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ```json { "id": "f419d0cf-5d8e-4b4c-82bb-6042b17e68f8", "url": "https://example.com/webhooks/entirefeed", "events": [ "generation.succeeded", "generation.failed", "generation.manual_review" ], "secret": "whsec_store_this_value_once" } ``` ## List or deactivate endpoints List endpoints: ### cURL ```bash curl https://api.entirefeed.com/v1/webhooks/endpoints \ -X GET \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/webhooks/endpoints", { method: "GET", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` ### Python ```python import os import requests response = requests.request( "GET", "https://api.entirefeed.com/v1/webhooks/endpoints", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json()) ``` Deactivate an endpoint. A successful response has no body: ### cURL ```bash curl https://api.entirefeed.com/v1/webhooks/endpoints/f419d0cf-5d8e-4b4c-82bb-6042b17e68f8 \ -X DELETE \ -H "Authorization: Bearer $ENTIREFEED_API_KEY" ``` ### TypeScript ```typescript const response = await fetch("https://api.entirefeed.com/v1/webhooks/endpoints/f419d0cf-5d8e-4b4c-82bb-6042b17e68f8", { method: "DELETE", headers: { "Authorization": `Bearer ${process.env.ENTIREFEED_API_KEY}`, }, }); if (!response.ok) throw new Error(await response.text()); console.log(response.status); ``` ### Python ```python import os import requests response = requests.request( "DELETE", "https://api.entirefeed.com/v1/webhooks/endpoints/f419d0cf-5d8e-4b4c-82bb-6042b17e68f8", headers={"Authorization": f"Bearer {os.environ['ENTIREFEED_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.status_code) ``` ## Verify the signature Verify `EntireFeed-Signature` against the exact raw body before parsing JSON: ### TypeScript ```typescript import { createHmac, timingSafeEqual } from "node:crypto"; const parts = Object.fromEntries( signatureHeader.split(",").map((part) => part.split("=", 2)), ); const timestamp = Number(parts.t); const received = Buffer.from(parts.v1 ?? "", "hex"); const expected = Buffer.from( createHmac("sha256", process.env.ENTIREFEED_WEBHOOK_SECRET!) .update(Buffer.concat([Buffer.from(String(timestamp) + "."), rawBody])) .digest("hex"), "hex", ); const fresh = Math.abs(Date.now() / 1000 - timestamp) <= 300; const valid = fresh && received.length === expected.length && timingSafeEqual(received, expected); ``` ### Python ```python import hashlib import hmac import os import time parts = dict(part.split("=", 1) for part in signature_header.split(",")) timestamp = int(parts["t"]) signed = f"{timestamp}.".encode() + raw_body expected = hmac.new( os.environ["ENTIREFEED_WEBHOOK_SECRET"].encode(), signed, hashlib.sha256, ).hexdigest() fresh = abs(time.time() - timestamp) <= 300 valid = fresh and hmac.compare_digest(parts["v1"], expected) ``` ## Process deliveries idempotently ```json { "id": "evt_0123456789abcdef0123456789abcdef", "type": "generation.succeeded", "created_at": "2026-07-12T08:31:14Z", "data": { "object": { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "succeeded", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:31:14Z", "output": { "assets": [ { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/product-reveal.mp4", "mime_type": "video/mp4", "expires_at": null } ] }, "usage": { "amount_usd": "1.20", "line_items": [], "billing_status": "settled" }, "error": null, "metadata": null } } } ``` Persist `EntireFeed-Event-ID` before returning `2xx`. Repeated delivery of that ID must not repeat customer-side effects. Requests time out after 10 seconds. Failed deliveries retry after 1m, 5m, 30m, 2h, 12h. --- # Handle idempotency and rate limits > Give each intended write a stable key, replay safely after uncertainty, and back off from explicit limits. Canonical: https://entirefeed.com/docs/operate/idempotency-and-rate-limits Network uncertainty must not create duplicate paid work. Send an `Idempotency-Key` on generation create and retry requests, even though discovery, estimation, and reads do not need one. ## A key identifies one intent Generate a unique, non-secret string for one logical create or retry. Reuse it when repeating that same request after a timeout or lost response. Do not rotate it merely because the response was uncertain. Reusing the key with the same intent returns the existing generation. Reusing it for a different body returns `409 idempotency_conflict`. A retry key identifies the retry itself, not the original create. ## Back off from limits Limits apply to authenticated request volume, generation creation frequency, and concurrent active generations. A rejected request returns `429 rate_limit_exceeded`. Do not fan out immediate retries; reduce concurrency and use bounded exponential backoff. ## Use one key for one write intent - A key names one create or retry intent. It is not a secret. - Reuse the same key after a timeout with the same intended request. - Use a new key for new work; changing a request while reusing a key returns `idempotency_conflict`. ## Respond to explicit limits - 60 authenticated requests per 60 seconds per API key. - 10 generation creates or retries per 60 seconds per API key. - 10 upload authorizations per 60 seconds per API key or MCP organization. - 1 active upload per organization, with 2 active uploads across the service. - 5 concurrent queued or running generations per organization. A `429 rate_limit_exceeded` response means a limit was reached. Reduce concurrency and use bounded exponential backoff. Keep the original idempotency key when replaying the same write intent. --- # Handle errors and manual review > Classify request errors, inspect generation failures, and stop automation when cost requires review. Canonical: https://entirefeed.com/docs/operate/errors-and-manual-review HTTP errors and terminal generation failures answer different questions. An HTTP error means the attempted API action was rejected. A generation with `status: failed` represents accepted work that later failed. ## Preserve the request ID API error responses include `type`, `code`, `message`, and `request_id`. Log the request ID with your own operation metadata. Validation errors can also include structured `details`. ## Retry by category, not by status code alone Fix authentication, input, balance, and idempotency errors before retrying. Back off from rate limits and temporary availability failures. Before repeating a paid create after a timeout, read by the original response or replay the same idempotency key. ## Stop on manual review `manual_review` is terminal for automation. The generation's cost could not be finalized automatically, so do not cancel, retry, or create a replacement solely because time elapsed. Keep the generation ID and wait for the status and billing outcome to be resolved. Use the [error reference](/docs/reference/errors) for stable codes and next actions. ## Read the error envelope ```json { "error": { "type": "invalid_request", "code": "invalid_request", "message": "Request validation failed.", "request_id": "req_0123456789abcdef", "details": [ { "loc": [ "body", "input", "duration_seconds" ], "msg": "Input should be less than or equal to 12", "type": "less_than_equal" } ] } } ``` ## Choose the next action by code - `authentication_error`: The bearer API key is missing, invalid, inactive, or revoked. Create or replace the organization API key. - `invalid_request`: The path, body, headers, or task input failed validation. Fix the request using the current task and OpenAPI schemas. - `task_not_found`: The requested task is not available. Choose a task returned by the tasks endpoint. - `task_unavailable`: The requested task is visible but not currently runnable. Choose a task marked as available. - `model_required`: The selected task requires a model. Choose an available model listed for that task. - `model_not_allowed`: The selected task does not accept a model. Remove the model field and send the task inputs directly. - `model_not_found`: The requested model is not available. Choose an available model returned by the models endpoint. - `model_unavailable`: The requested model is visible but not currently runnable. Choose a model marked as available. - `unsupported_task`: The requested model does not support the selected task. Choose a model listed for that task. - `insufficient_balance`: Available balance is below the request's current estimate. Add balance in Console or reduce the estimated request. - `generation_not_found`: The generation does not exist in the key's organization. Check the generation ID and organization credential. - `workflow_starter_not_found`: The Workflow Starter is not currently published. List starters and choose a returned slug. - `workflow_run_not_found`: The workflow run does not exist in the key's organization. Check the public run ID and organization credential. - `webhook_endpoint_not_found`: The webhook endpoint does not exist in the key's organization. List endpoints and use an endpoint ID returned for this organization. - `idempotency_key_required`: The create or retry request omitted its intent key. Send one stable Idempotency-Key for the intended write. - `idempotency_conflict`: The same idempotency key was reused for a different intent. Replay the original request or use a new key for new work. - `starter_version_stale`: The Workflow Starter contract changed. Read the starter, revalidate inputs, and estimate again. - `workflow_estimate_required`: The workflow run has not been estimated. Estimate the exact intended starter inputs before creation. - `workflow_estimate_stale`: The workflow estimate no longer matches current pricing. Estimate the same intended inputs again. - `invalid_workflow_contract`: The published starter contract cannot be executed safely. Stop and report the starter slug and request ID to support. - `invalid_workflow_inputs`: The inputs do not match the starter's current schema. Read the starter and correct inputs against input_schema. - `unknown_workflow_cost`: One or more paid steps cannot be estimated. Do not create the run until every cost is known. - `retry_not_allowed`: The current attempt is not eligible for retry. Read the latest attempt and retry only after it fails or is cancelled. - `active_retry_exists`: This attempt or a later retry is still active. Monitor the active attempt before deciding on another retry. - `retry_not_latest`: A newer attempt already exists in this retry sequence. Retry the latest attempt instead. - `rate_limit_exceeded`: Request volume or active generation concurrency is too high. Reduce concurrency and retry with bounded exponential backoff. - `invalid_media_upload`: The filename, content type, or uploaded bytes are not a supported media file. Upload a supported image, video, or audio file with matching metadata. - `media_upload_timeout`: The media upload did not complete within the allowed time. Retry the upload over a stable connection with bounded exponential backoff. - `media_upload_too_large`: The media file exceeds the current upload size limit. Use a smaller source file before requesting another upload. - `media_storage_unavailable`: The media file could not be stored temporarily. Retry the upload later with bounded exponential backoff. - `service_unavailable`: The media service is temporarily unavailable. Retry later with bounded exponential backoff and the same write key. - `generation_failed`: Accepted work reached a terminal failure. Inspect final usage, then retry only when the generation is eligible. - `invalid_output`: Completed work did not satisfy the task's public output contract. Treat the generation as failed and preserve its ID for support. ## Inspect a failed generation ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "failed", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:31:14Z", "output": null, "usage": { "amount_usd": "1.20", "line_items": [], "billing_status": "settled", "billing_reason": "final_cost_confirmed" }, "error": { "code": "invalid_output", "message": "Completed work did not satisfy the public task contract." }, "metadata": null } ``` This accepted request reached a terminal failure. Inspect both the generation error and final usage before deciding whether to retry. ## Stop automation for manual review ```json { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "manual_review", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:42:00Z", "output": null, "usage": { "amount_usd": "1.20", "line_items": [], "billing_status": "manual_review", "billing_reason": "cost_requires_review" }, "error": null, "metadata": null } ``` Do not retry this generation. Preserve its ID and wait for a resolved terminal status and billing outcome. --- # Public contract reference > Inspect public REST paths, generation tasks, pricing, MCP tools, and machine-readable documentation. Canonical: https://entirefeed.com/docs/reference Use the formats below to inspect the same public contracts described throughout these docs. ## Browse reference pages - [REST API](/docs/reference/rest) - [Models, tasks, schemas, and pricing](/docs/reference/models) - [Generation and billing statuses](/docs/reference/statuses) - [Errors](/docs/reference/errors) - [Webhooks](/docs/reference/webhooks) - [Billing](/docs/reference/billing) - [MCP tools](/docs/reference/mcp) ## Pick the contract format - Use [`openapi.json`](/openapi.json) for REST paths, request schemas, and response schemas. - Use the [MCP tool reference](/docs/reference/mcp) for delegated agent tools and their checked input and output schemas. - Use [`llms.txt`](/llms.txt) for a concise agent navigation index. - Use [`llms-full.txt`](/llms-full.txt) for one consolidated Markdown document. - Open any page's raw Markdown variant from its page actions. These files describe the currently published public API and supported agent tools. ## Public REST API OpenAPI 3.1.0; 15 public operations from `https://api.entirefeed.com`. - `GET` `/v1/billing/ledger`: Get Billing Ledger. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 BillingLedgerListResponse, 400 ApiErrorResponse (invalid_request), 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `GET` `/v1/billing/summary`: Get Billing Summary. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 BillingSummaryResponse, 401 ApiErrorResponse (authentication_error), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/estimate`: Estimate. Auth: Public. Headers: none. Request: EstimateRequest. Responses: 200 EstimateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 422 ApiErrorResponse (invalid_request), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/generations`: List Generations. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationListResponse, 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/generations`: Create. Auth: Bearer API key. Headers: Idempotency-Key optional. Request: GenerationCreateRequest. Responses: 201 GenerationCreateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 401 ApiErrorResponse (authentication_error), 402 ApiErrorResponse (insufficient_balance), 409 ApiErrorResponse (idempotency_conflict), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/generations/{generation_id}`: Get. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationResponse, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (generation_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/generations/{generation_id}/cancel`: Cancel. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationResponse, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (generation_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `POST` `/v1/generations/{generation_id}/retry`: Retry. Auth: Bearer API key. Headers: Idempotency-Key optional. Request: No body. Responses: 201 GenerationCreateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 401 ApiErrorResponse (authentication_error), 402 ApiErrorResponse (insufficient_balance), 404 ApiErrorResponse (generation_not_found), 409 ApiErrorResponse (active_retry_exists, idempotency_conflict, retry_not_allowed, retry_not_latest), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/models`: List Models. Auth: Public. Headers: none. Request: No body. Responses: 200 PublicModelListResponse, 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/pricing`: Get Pricing. Auth: Public. Headers: none. Request: No body. Responses: 200 PricingResponse, 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/tasks`: List Tasks. Auth: Public. Headers: none. Request: No body. Responses: 200 PublicTaskListResponse, 503 ApiErrorResponse (service_unavailable). - `POST` `/v1/uploads`: Upload Media. Auth: Bearer API key. Headers: none. Request: multipart/form-data field: file. Responses: 201 MediaUploadResponse, 400 ApiErrorResponse (invalid_media_upload), 401 ApiErrorResponse (authentication_error), 408 ApiErrorResponse (media_upload_timeout), 413 ApiErrorResponse (media_upload_too_large), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (media_storage_unavailable, service_unavailable). - `GET` `/v1/webhooks/endpoints`: List Endpoints. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 WebhookEndpointListResponse, 401 ApiErrorResponse (authentication_error), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/webhooks/endpoints`: Create Endpoint. Auth: Bearer API key. Headers: none. Request: WebhookEndpointCreateRequest. Responses: 200 WebhookEndpointCreateResponse, 400 ApiErrorResponse (invalid_request), 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `DELETE` `/v1/webhooks/endpoints/{endpoint_id}`: Deactivate Endpoint. Auth: Bearer API key. Headers: none. Request: No body. Responses: 204 no body, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (webhook_endpoint_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). ## Machine-readable artifacts - [OpenAPI JSON](/openapi.json) - [Concise agent index](/llms.txt) - [Complete agent-readable docs](/llms-full.txt) --- # REST API reference > Inspect media generation, billing, and webhook methods, authentication requirements, and response contracts. Canonical: https://entirefeed.com/docs/reference/rest The generated operation list below covers media generation, billing, and webhook methods from the public OpenAPI document. Use [`openapi.json`](/openapi.json) for the complete public contract. ## Public REST API OpenAPI 3.1.0; 15 public operations from `https://api.entirefeed.com`. - `GET` `/v1/billing/ledger`: Get Billing Ledger. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 BillingLedgerListResponse, 400 ApiErrorResponse (invalid_request), 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `GET` `/v1/billing/summary`: Get Billing Summary. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 BillingSummaryResponse, 401 ApiErrorResponse (authentication_error), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/estimate`: Estimate. Auth: Public. Headers: none. Request: EstimateRequest. Responses: 200 EstimateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 422 ApiErrorResponse (invalid_request), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/generations`: List Generations. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationListResponse, 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/generations`: Create. Auth: Bearer API key. Headers: Idempotency-Key optional. Request: GenerationCreateRequest. Responses: 201 GenerationCreateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 401 ApiErrorResponse (authentication_error), 402 ApiErrorResponse (insufficient_balance), 409 ApiErrorResponse (idempotency_conflict), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/generations/{generation_id}`: Get. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationResponse, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (generation_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/generations/{generation_id}/cancel`: Cancel. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 GenerationResponse, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (generation_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `POST` `/v1/generations/{generation_id}/retry`: Retry. Auth: Bearer API key. Headers: Idempotency-Key optional. Request: No body. Responses: 201 GenerationCreateResponse, 400 ApiErrorResponse (invalid_request, task_not_found, task_unavailable, model_required, model_not_allowed, model_not_found, model_unavailable, unsupported_task), 401 ApiErrorResponse (authentication_error), 402 ApiErrorResponse (insufficient_balance), 404 ApiErrorResponse (generation_not_found), 409 ApiErrorResponse (active_retry_exists, idempotency_conflict, retry_not_allowed, retry_not_latest), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/models`: List Models. Auth: Public. Headers: none. Request: No body. Responses: 200 PublicModelListResponse, 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/pricing`: Get Pricing. Auth: Public. Headers: none. Request: No body. Responses: 200 PricingResponse, 503 ApiErrorResponse (service_unavailable). - `GET` `/v1/tasks`: List Tasks. Auth: Public. Headers: none. Request: No body. Responses: 200 PublicTaskListResponse, 503 ApiErrorResponse (service_unavailable). - `POST` `/v1/uploads`: Upload Media. Auth: Bearer API key. Headers: none. Request: multipart/form-data field: file. Responses: 201 MediaUploadResponse, 400 ApiErrorResponse (invalid_media_upload), 401 ApiErrorResponse (authentication_error), 408 ApiErrorResponse (media_upload_timeout), 413 ApiErrorResponse (media_upload_too_large), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (media_storage_unavailable, service_unavailable). - `GET` `/v1/webhooks/endpoints`: List Endpoints. Auth: Bearer API key. Headers: none. Request: No body. Responses: 200 WebhookEndpointListResponse, 401 ApiErrorResponse (authentication_error), 429 ApiErrorResponse (rate_limit_exceeded). - `POST` `/v1/webhooks/endpoints`: Create Endpoint. Auth: Bearer API key. Headers: none. Request: WebhookEndpointCreateRequest. Responses: 200 WebhookEndpointCreateResponse, 400 ApiErrorResponse (invalid_request), 401 ApiErrorResponse (authentication_error), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded), 503 ApiErrorResponse (service_unavailable). - `DELETE` `/v1/webhooks/endpoints/{endpoint_id}`: Deactivate Endpoint. Auth: Bearer API key. Headers: none. Request: No body. Responses: 204 no body, 401 ApiErrorResponse (authentication_error), 404 ApiErrorResponse (webhook_endpoint_not_found), 422 ApiErrorResponse (invalid_request), 429 ApiErrorResponse (rate_limit_exceeded). ## Machine-readable artifacts - [OpenAPI JSON](/openapi.json) - [Concise agent index](/llms.txt) - [Complete agent-readable docs](/llms-full.txt) --- # Models, tasks, schemas, and pricing > Inspect every customer-visible model, availability state, generation task, input schema, output contract, and published unit price. Canonical: https://entirefeed.com/docs/reference/models This reference is generated from the same checked catalog used by docs and pricing. Use task discovery at runtime before constructing requests, and use `POST /v1/estimate` for a concrete total. ## Model availability Current catalog: 11 available tasks and 11 available models. Coming-soon entries are marked non-runnable. ### `gemini-omni` - Gemini Omni Availability: Available. Tasks: `video.create`. ### `gemini-omni-flash` - Gemini Omni Flash Availability: Available. Tasks: `video.create`. ### `gpt-image-2` - GPT Image 2 Availability: Available. Tasks: `image.create`, `image.edit`. ### `nano-banana-2` - Nano Banana 2 Availability: Available. Tasks: `image.create`, `image.edit`. ### `nano-banana-2-lite` - Nano Banana 2 Lite Availability: Available. Tasks: `image.create`, `image.edit`. ### `nano-banana-pro` - Nano Banana Pro Availability: Available. Tasks: `image.create`, `image.edit`. ### `seedance-2` - Seedance 2 Availability: Available. Tasks: `video.create`. ### `seedance-2-fast` - Seedance 2 Fast Availability: Available. Tasks: `video.create`. ### `seedance-2-mini` - Seedance 2 Mini Availability: Available. Tasks: `video.create`. ### `seedance-2.5` - Seedance 2.5 Availability: Coming soon - not runnable. This model is unavailable and has no runnable task contract, pricing calculator, or create example. ### `seedream-5-pro` - Seedream 5.0 Pro Availability: Available. Tasks: `image.create`, `image.edit`. ### `sync-lipsync-v3` - Sync Lipsync V3 Availability: Available. Tasks: `video.lipsync`. ## Task contracts ### `image.create` - Create Image Media type: `image` Published prices: - `gpt-image-2`: $0.03 per image; minimum $0.03 - `nano-banana-2`: $0.045 per image; minimum $0.045 - `nano-banana-2-lite`: $0.0336 per image; minimum $0.0336 - `nano-banana-pro`: $0.134 per image; minimum $0.134 - `seedream-5-pro`: $0.035 per image; minimum $0.035 #### gpt-image-2 input ```json { "model": "gpt-image-2", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "3:2", "2:3", "4:3", "3:4", "16:9", "9:16", "2:1", "1:2", "3:1", "1:3", "21:9", "9:21", "5:4", "4:5" ], "type": "string" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 16, "type": "array" }, "resolution": { "default": "1K", "description": "Output size. Some extreme aspect ratios are limited to 1K.", "enum": [ "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### nano-banana-2 input ```json { "model": "nano-banana-2", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9", "1:4", "4:1", "1:8", "8:1" ], "type": "string" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "type": "array" }, "resolution": { "default": "1K", "enum": [ "0.5K", "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### nano-banana-2-lite input ```json { "model": "nano-banana-2-lite", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9", "1:4", "4:1", "1:8", "8:1" ], "type": "string" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "type": "array" }, "resolution": { "default": "1K", "enum": [ "1K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### nano-banana-pro input ```json { "model": "nano-banana-pro", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9" ], "type": "string" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "type": "array" }, "resolution": { "default": "1K", "enum": [ "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### seedream-5-pro input ```json { "model": "seedream-5-pro", "defaults": { "aspect_ratio": "1:1", "output_format": "png", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "1:1", "enum": [ "1:1", "4:3", "3:4", "16:9", "9:16", "2:3", "3:2", "21:9" ], "type": "string" }, "output_format": { "default": "png", "enum": [ "png", "jpeg" ], "type": "string" }, "prompt": { "maxLength": 5000, "minLength": 3, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 10, "type": "array" }, "resolution": { "default": "1K", "enum": [ "1K", "2K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `image.edit` - Edit Image Media type: `image` Published prices: - `gpt-image-2`: $0.03 per image; minimum $0.03 - `nano-banana-2`: $0.045 per image; minimum $0.04556 - `nano-banana-2-lite`: $0.0336 per image; minimum $0.03388 - `nano-banana-pro`: $0.134 per image; minimum $0.1351 - `seedream-5-pro`: $0.035 per image; minimum $0.035 #### gpt-image-2 input ```json { "model": "gpt-image-2", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "3:2", "2:3", "4:3", "3:4", "16:9", "9:16", "2:1", "1:2", "3:1", "1:3", "21:9", "9:21", "5:4", "4:5" ], "type": "string" }, "images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 16, "minItems": 1, "type": "array" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "resolution": { "default": "1K", "description": "Output size. Some extreme aspect ratios are limited to 1K.", "enum": [ "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt", "images" ], "type": "object" } } ``` #### nano-banana-2 input ```json { "model": "nano-banana-2", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9", "1:4", "4:1", "1:8", "8:1" ], "type": "string" }, "images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "minItems": 1, "type": "array" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "resolution": { "default": "1K", "enum": [ "0.5K", "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt", "images" ], "type": "object" } } ``` #### nano-banana-2-lite input ```json { "model": "nano-banana-2-lite", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9", "1:4", "4:1", "1:8", "8:1" ], "type": "string" }, "images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "minItems": 1, "type": "array" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "resolution": { "default": "1K", "enum": [ "1K" ], "type": "string" } }, "required": [ "prompt", "images" ], "type": "object" } } ``` #### nano-banana-pro input ```json { "model": "nano-banana-pro", "defaults": { "aspect_ratio": "auto", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "auto", "enum": [ "auto", "1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9" ], "type": "string" }, "images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 14, "minItems": 1, "type": "array" }, "prompt": { "maxLength": 32000, "minLength": 1, "pattern": "\\S", "type": "string" }, "resolution": { "default": "1K", "enum": [ "1K", "2K", "4K" ], "type": "string" } }, "required": [ "prompt", "images" ], "type": "object" } } ``` #### seedream-5-pro input ```json { "model": "seedream-5-pro", "defaults": { "aspect_ratio": "1:1", "output_format": "png", "resolution": "1K" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "1:1", "enum": [ "1:1", "4:3", "3:4", "16:9", "9:16", "2:3", "3:2", "21:9" ], "type": "string" }, "images": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 10, "minItems": 1, "type": "array" }, "output_format": { "default": "png", "enum": [ "png", "jpeg" ], "type": "string" }, "prompt": { "maxLength": 5000, "minLength": 3, "pattern": "\\S", "type": "string" }, "resolution": { "default": "1K", "enum": [ "1K", "2K" ], "type": "string" } }, "required": [ "prompt", "images" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `social.search` - Search Social Videos Media type: `video` Published prices: - Omit `model`: $0.35 per operation; exact price varies by platform and result limit; minimum $0.01 #### Model-less input ```json { "model": null, "defaults": { "limit": 20, "max_duration_seconds": null, "min_views": null, "published_after": null, "sort": "relevance" }, "input_schema": { "$defs": { "SocialPlatform": { "enum": [ "tiktok", "instagram_reels", "youtube_shorts" ], "type": "string" }, "SocialSort": { "enum": [ "relevance", "recent", "popular" ], "type": "string" } }, "additionalProperties": false, "properties": { "limit": { "default": 20, "maximum": 50, "minimum": 1, "type": "integer" }, "max_duration_seconds": { "anyOf": [ { "exclusiveMinimum": 0, "maximum": 600, "type": "number" }, { "type": "null" } ], "default": null }, "min_views": { "anyOf": [ { "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null }, "platform": { "$ref": "#/$defs/SocialPlatform", "description": "TikTok searches use a US context. Instagram Reels and YouTube Shorts use their search integration's default context because those integrations do not support country selection." }, "published_after": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "query": { "maxLength": 500, "minLength": 1, "type": "string" }, "sort": { "$ref": "#/$defs/SocialSort", "default": "relevance" } }, "required": [ "platform", "query" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" }, "SocialCreator": { "properties": { "display_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "follower_count": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null }, "profile_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "username": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null } }, "type": "object" }, "SocialMetrics": { "properties": { "comments": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null }, "likes": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null }, "shares": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null }, "views": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null } }, "type": "object" }, "SocialPlatform": { "enum": [ "tiktok", "instagram_reels", "youtube_shorts" ], "type": "string" }, "SocialSearchResult": { "properties": { "count": { "minimum": 0, "type": "integer" }, "platform": { "$ref": "#/$defs/SocialPlatform" }, "query": { "type": "string" }, "videos": { "items": { "$ref": "#/$defs/SocialVideo" }, "type": "array" } }, "required": [ "platform", "query", "videos", "count" ], "type": "object" }, "SocialVideo": { "properties": { "caption": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "creator": { "$ref": "#/$defs/SocialCreator" }, "duration_seconds": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "default": null }, "hashtags": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "metrics": { "$ref": "#/$defs/SocialMetrics" }, "platform": { "$ref": "#/$defs/SocialPlatform" }, "published_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "thumbnail_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "type": "string" } }, "required": [ "id", "platform", "url", "creator" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 0, "type": "array" }, "data": { "$ref": "#/$defs/SocialSearchResult" } }, "required": [ "assets", "data" ], "type": "object" } ``` ### `video.add_audio` - Add Audio to Video Media type: `video` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": { "audio_volume": 1, "mode": "replace", "original_audio_volume": null }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "audio": { "$ref": "#/$defs/ReferenceUrlInput" }, "audio_volume": { "default": 1, "description": "Volume level for the added audio (1.0 = normal)", "maximum": 2, "minimum": 0, "type": "number" }, "mode": { "default": "replace", "enum": [ "replace", "mix" ], "type": "string" }, "original_audio_volume": { "anyOf": [ { "maximum": 2, "minimum": 0, "type": "number" }, { "type": "null" } ], "default": null, "description": "Existing video audio volume when mode is mix." }, "video": { "$ref": "#/$defs/ReferenceUrlInput" } }, "required": [ "video", "audio" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 1, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.concat` - Concatenate Videos Media type: `video` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": {}, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "videos": { "items": { "$ref": "#/$defs/ReferenceUrlInput" }, "maxItems": 8, "minItems": 2, "type": "array" } }, "required": [ "videos" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" }, "VideoConcatOutputData": { "properties": { "duration_seconds": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "default": null } }, "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 1, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "$ref": "#/$defs/VideoConcatOutputData" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.create` - Create Video Media type: `video` Published prices: - `gemini-omni`: $0.315 per generation; minimum $0.315 - `gemini-omni-flash`: $0.315 per generation; minimum $0.315 - `seedance-2`: $0.0575 per second; minimum $0.345 - `seedance-2-fast`: $0.045 per second; minimum $0.27 - `seedance-2-mini`: $0.03 per second; minimum $0.18 #### gemini-omni input ```json { "model": "gemini-omni", "defaults": { "aspect_ratio": "9:16", "duration_seconds": 4, "reference_video": null, "seed": null }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "allOf": [ { "if": { "properties": { "reference_video": { "type": "object" } }, "required": [ "reference_video" ] }, "then": { "properties": { "reference_images": { "maxItems": 5 } } } } ], "properties": { "aspect_ratio": { "default": "9:16", "enum": [ "9:16", "16:9" ], "type": "string" }, "duration_seconds": { "default": 4, "enum": [ 4, 6, 8 ], "type": "integer" }, "prompt": { "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 7, "type": "array" }, "reference_video": { "anyOf": [ { "$ref": "#/$defs/ReferenceMediaInput" }, { "type": "null" } ], "default": null }, "seed": { "anyOf": [ { "maximum": 2147483647, "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null, "description": "Random seed for reproducibility (leave empty for random)." } }, "required": [ "prompt" ], "type": "object" } } ``` #### gemini-omni-flash input ```json { "model": "gemini-omni-flash", "defaults": { "aspect_ratio": "9:16", "duration_seconds": 4, "reference_video": null, "seed": null }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "allOf": [ { "if": { "properties": { "reference_video": { "type": "object" } }, "required": [ "reference_video" ] }, "then": { "properties": { "reference_images": { "maxItems": 5 } } } } ], "properties": { "aspect_ratio": { "default": "9:16", "enum": [ "9:16", "16:9" ], "type": "string" }, "duration_seconds": { "default": 4, "enum": [ 4, 6, 8 ], "type": "integer" }, "prompt": { "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 7, "type": "array" }, "reference_video": { "anyOf": [ { "$ref": "#/$defs/ReferenceMediaInput" }, { "type": "null" } ], "default": null }, "seed": { "anyOf": [ { "maximum": 2147483647, "minimum": 0, "type": "integer" }, { "type": "null" } ], "default": null, "description": "Random seed for reproducibility (leave empty for random)." } }, "required": [ "prompt" ], "type": "object" } } ``` #### seedance-2 input ```json { "model": "seedance-2", "defaults": { "aspect_ratio": "9:16", "duration_seconds": 8, "first_frame": null, "generate_audio": true, "last_frame": null, "resolution": "720p" }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" }, "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "9:16", "enum": [ "16:9", "9:16", "4:3", "3:4", "1:1", "21:9" ], "type": "string" }, "duration_seconds": { "default": 8, "enum": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], "type": "integer" }, "first_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "generate_audio": { "default": true, "description": "Generate synchronized audio with video", "type": "boolean" }, "last_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "prompt": { "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_audio": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 9, "type": "array" }, "reference_videos": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "resolution": { "default": "720p", "description": "Output resolution. Standard Seedance 2 supports up to 4K.", "enum": [ "480p", "720p", "1080p", "4K" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### seedance-2-fast input ```json { "model": "seedance-2-fast", "defaults": { "aspect_ratio": "9:16", "duration_seconds": 8, "first_frame": null, "generate_audio": true, "last_frame": null, "resolution": "720p" }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" }, "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "9:16", "enum": [ "16:9", "9:16", "4:3", "3:4", "1:1", "21:9" ], "type": "string" }, "duration_seconds": { "default": 8, "enum": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], "type": "integer" }, "first_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "generate_audio": { "default": true, "description": "Generate synchronized audio with video", "type": "boolean" }, "last_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "prompt": { "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_audio": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 9, "type": "array" }, "reference_videos": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "resolution": { "default": "720p", "description": "Output resolution. Seedance 2 Fast supports 480p and 720p.", "enum": [ "480p", "720p" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` #### seedance-2-mini input ```json { "model": "seedance-2-mini", "defaults": { "aspect_ratio": "9:16", "duration_seconds": 8, "first_frame": null, "generate_audio": true, "last_frame": null, "resolution": "720p" }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" }, "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "aspect_ratio": { "default": "9:16", "enum": [ "16:9", "9:16", "4:3", "3:4", "1:1", "21:9", "adaptive" ], "type": "string" }, "duration_seconds": { "default": 8, "enum": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], "type": "integer" }, "first_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "generate_audio": { "default": true, "description": "Generate synchronized audio with video", "type": "boolean" }, "last_frame": { "anyOf": [ { "$ref": "#/$defs/ReferenceUrlInput" }, { "type": "null" } ], "default": null }, "prompt": { "minLength": 1, "pattern": "\\S", "type": "string" }, "reference_audio": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "reference_images": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 9, "type": "array" }, "reference_videos": { "items": { "$ref": "#/$defs/ReferenceMediaInput" }, "maxItems": 3, "type": "array" }, "resolution": { "default": "720p", "description": "Output resolution. Seedance 2 Mini supports 480p and 720p.", "enum": [ "480p", "720p" ], "type": "string" } }, "required": [ "prompt" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.extract_audio` - Extract Audio Media type: `audio` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": { "bitrate": "192k", "format": "mp3" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "bitrate": { "default": "192k", "enum": [ "128k", "192k", "320k" ], "type": "string" }, "format": { "default": "mp3", "enum": [ "mp3", "wav", "aac" ], "type": "string" }, "video": { "$ref": "#/$defs/ReferenceUrlInput" } }, "required": [ "video" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 1, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.extract_frame` - Extract Video Frame Media type: `image` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": { "format": "jpg", "timestamp_seconds": 0 }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "format": { "default": "jpg", "enum": [ "jpg", "png", "webp" ], "type": "string" }, "timestamp_seconds": { "default": 0, "description": "Frame timestamp in seconds.", "minimum": 0, "type": "number" }, "video": { "$ref": "#/$defs/ReferenceUrlInput" } }, "required": [ "video" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" }, "VideoExtractFrameOutputData": { "properties": { "height": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null }, "width": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null } }, "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 1, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "$ref": "#/$defs/VideoExtractFrameOutputData" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.lipsync` - Lip Sync Video Media type: `video` Published prices: - `sync-lipsync-v3`: $8.00 per minute; minimum $0.133333 #### sync-lipsync-v3 input ```json { "model": "sync-lipsync-v3", "defaults": { "sync_mode": "cut_off" }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "audio": { "$ref": "#/$defs/ReferenceUrlInput" }, "sync_mode": { "default": "cut_off", "description": "How to handle audio and video duration mismatches.", "enum": [ "cut_off", "loop", "bounce", "silence", "remap" ], "type": "string" }, "video": { "$ref": "#/$defs/ReferenceUrlInput" } }, "required": [ "video", "audio" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ### `video.split_scenes` - Split Video Into Scenes Media type: `video` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": { "minimum_scene_length_seconds": 0, "threshold": 20 }, "input_schema": { "$defs": { "ReferenceMediaInput": { "additionalProperties": false, "properties": { "role": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "minimum_scene_length_seconds": { "default": 0, "maximum": 60, "minimum": 0, "type": "number" }, "threshold": { "default": 20, "maximum": 100, "minimum": 1, "type": "number" }, "video": { "$ref": "#/$defs/ReferenceMediaInput" } }, "required": [ "video" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" }, "SceneRecord": { "properties": { "asset_index": { "minimum": 0, "type": "integer" }, "duration_seconds": { "exclusiveMinimum": 0, "type": "number" }, "end_seconds": { "minimum": 0, "type": "number" }, "start_seconds": { "minimum": 0, "type": "number" } }, "required": [ "asset_index", "start_seconds", "end_seconds", "duration_seconds" ], "type": "object" }, "SplitScenesOutputData": { "properties": { "fps": { "exclusiveMinimum": 0, "type": "number" }, "scene_count": { "minimum": 1, "type": "integer" }, "scenes": { "items": { "$ref": "#/$defs/SceneRecord" }, "type": "array" }, "total_frame_count": { "minimum": 1, "type": "integer" } }, "required": [ "scene_count", "fps", "total_frame_count", "scenes" ], "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "minItems": 1, "type": "array" }, "data": { "$ref": "#/$defs/SplitScenesOutputData" } }, "required": [ "assets", "data" ], "type": "object" } ``` ### `video.trim` - Trim Video Media type: `video` Published prices: - Omit `model`: $0.00 per operation; minimum $0.00 #### Model-less input ```json { "model": null, "defaults": { "start_seconds": 0 }, "input_schema": { "$defs": { "ReferenceUrlInput": { "additionalProperties": false, "properties": { "url": { "format": "uri", "minLength": 1, "pattern": "^https://(?:\\[[0-9A-Fa-f:.]+\\]|[^@\\s/:?#]+)(?::443)?(?:[/?#]|$)", "type": "string" } }, "required": [ "url" ], "type": "object" } }, "additionalProperties": false, "properties": { "end_seconds": { "description": "End timestamp in seconds.", "minimum": 0, "type": "number" }, "start_seconds": { "default": 0, "description": "Start timestamp in seconds.", "minimum": 0, "type": "number" }, "video": { "$ref": "#/$defs/ReferenceUrlInput" } }, "required": [ "video", "end_seconds" ], "type": "object" } } ``` Output schema: ```json { "$defs": { "PublicAsset": { "properties": { "expires_at": { "anyOf": [ { "format": "date-time", "type": "string" }, { "type": "null" } ], "default": null }, "id": { "type": "string" }, "mime_type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null }, "type": { "type": "string" }, "url": { "format": "uri", "minLength": 1, "type": "string" } }, "required": [ "id", "type", "url" ], "type": "object" }, "VideoTrimOutputData": { "properties": { "duration_seconds": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "default": null } }, "type": "object" } }, "properties": { "assets": { "items": { "$ref": "#/$defs/PublicAsset" }, "maxItems": 1, "minItems": 1, "type": "array" }, "data": { "anyOf": [ { "$ref": "#/$defs/VideoTrimOutputData" }, { "type": "null" } ], "default": null } }, "required": [ "assets" ], "type": "object" } ``` ## Guide coverage - `image.create`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `image.edit`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `social.search`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.add_audio`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.concat`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.create`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.extract_audio`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.extract_frame`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.lipsync`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.split_scenes`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) - `video.trim`: [models](/docs/generate/models), [estimate](/docs/generate/estimate), [create and monitor](/docs/generate/create-and-monitor), [cancel and retry](/docs/generate/cancel-and-retry), [billing and usage](/docs/operate/billing-and-usage), [errors and manual review](/docs/operate/errors-and-manual-review); [schemas and prices](/docs/reference/models) --- # Generation and billing statuses > Map execution and billing states to safe polling, completion, retry, and review behavior. Canonical: https://entirefeed.com/docs/reference/statuses Execution status and billing status are related but distinct. Always inspect both before deciding that work is complete or balance is available again. ## Generation status | Status | Phase | Required action | | --- | --- | --- | | `queued` | Active | Keep polling. Cancellation can be requested. | | `running` | Active | Keep polling. Cancellation is best effort. | | `succeeded` | Terminal | Read ordered output assets, structured data, and final usage. | | `failed` | Terminal | Inspect error and usage. Retry only after classifying the failure. | | `cancelled` | Terminal | Inspect final usage. The latest cancelled attempt may be retried. | | `manual_review` | Terminal for automation | Stop automated actions until status and billing are resolved. | ## Billing status | Status | Meaning | Balance behavior | | --- | --- | --- | | `reserved` | The current estimate is held while work is active. | Included in reserved balance, not available balance. | | `settled` | Final usage was charged. | The settled amount remains spent; unused hold can be released. | | `released` | The held amount was returned. | Released funds are available again. | | `manual_review` | Final cost could not be resolved automatically. | The hold remains unavailable until resolution. | --- # Error reference > Identify common API and generation error codes, their meaning, and the safe next action. Canonical: https://entirefeed.com/docs/reference/errors Branch on `error.code`, not message text. Messages add context, while codes are the stable value for integration behavior. ## Error response shape ```json { "error": { "type": "invalid_request", "code": "invalid_request", "message": "Request validation failed.", "request_id": "req_0123456789abcdef", "details": [ { "loc": [ "body", "input", "duration_seconds" ], "msg": "Input should be less than or equal to 12", "type": "less_than_equal" } ] } } ``` Generation error schema: ```json { "properties": { "code": { "title": "Code", "type": "string" }, "message": { "title": "Message", "type": "string" } }, "required": [ "code", "message" ], "title": "GenerationErrorResponse", "type": "object" } ``` ## Common error codes | Code | HTTP | Meaning and action | | --- | --- | --- | | `authentication_error` | 401 | The bearer API key is missing, invalid, inactive, or revoked. Create or replace the organization API key. | | `invalid_request` | 400 / 422 | The path, body, headers, or task input failed validation. Fix the request using the current task and OpenAPI schemas. | | `task_not_found` | 400 | The requested task is not available. Choose a task returned by the tasks endpoint. | | `task_unavailable` | 400 | The requested task is visible but not currently runnable. Choose a task marked as available. | | `model_required` | 400 | The selected task requires a model. Choose an available model listed for that task. | | `model_not_allowed` | 400 | The selected task does not accept a model. Remove the model field and send the task inputs directly. | | `model_not_found` | 400 | The requested model is not available. Choose an available model returned by the models endpoint. | | `model_unavailable` | 400 | The requested model is visible but not currently runnable. Choose a model marked as available. | | `unsupported_task` | 400 | The requested model does not support the selected task. Choose a model listed for that task. | | `insufficient_balance` | 402 | Available balance is below the request's current estimate. Add balance in Console or reduce the estimated request. | | `generation_not_found` | 404 | The generation does not exist in the key's organization. Check the generation ID and organization credential. | | `workflow_starter_not_found` | 404 | The Workflow Starter is not currently published. List starters and choose a returned slug. | | `workflow_run_not_found` | 404 | The workflow run does not exist in the key's organization. Check the public run ID and organization credential. | | `webhook_endpoint_not_found` | 404 | The webhook endpoint does not exist in the key's organization. List endpoints and use an endpoint ID returned for this organization. | | `idempotency_key_required` | 400 | The create or retry request omitted its intent key. Send one stable Idempotency-Key for the intended write. | | `idempotency_conflict` | 409 | The same idempotency key was reused for a different intent. Replay the original request or use a new key for new work. | | `starter_version_stale` | 409 | The Workflow Starter contract changed. Read the starter, revalidate inputs, and estimate again. | | `workflow_estimate_required` | 409 | The workflow run has not been estimated. Estimate the exact intended starter inputs before creation. | | `workflow_estimate_stale` | 409 | The workflow estimate no longer matches current pricing. Estimate the same intended inputs again. | | `invalid_workflow_contract` | 422 | The published starter contract cannot be executed safely. Stop and report the starter slug and request ID to support. | | `invalid_workflow_inputs` | 422 | The inputs do not match the starter's current schema. Read the starter and correct inputs against input_schema. | | `unknown_workflow_cost` | 422 | One or more paid steps cannot be estimated. Do not create the run until every cost is known. | | `retry_not_allowed` | 409 | The current attempt is not eligible for retry. Read the latest attempt and retry only after it fails or is cancelled. | | `active_retry_exists` | 409 | This attempt or a later retry is still active. Monitor the active attempt before deciding on another retry. | | `retry_not_latest` | 409 | A newer attempt already exists in this retry sequence. Retry the latest attempt instead. | | `rate_limit_exceeded` | 429 | Request volume or active generation concurrency is too high. Reduce concurrency and retry with bounded exponential backoff. | | `invalid_media_upload` | 400 | The filename, content type, or uploaded bytes are not a supported media file. Upload a supported image, video, or audio file with matching metadata. | | `media_upload_timeout` | 408 | The media upload did not complete within the allowed time. Retry the upload over a stable connection with bounded exponential backoff. | | `media_upload_too_large` | 413 | The media file exceeds the current upload size limit. Use a smaller source file before requesting another upload. | | `media_storage_unavailable` | 503 | The media file could not be stored temporarily. Retry the upload later with bounded exponential backoff. | | `service_unavailable` | 503 | The media service is temporarily unavailable. Retry later with bounded exponential backoff and the same write key. | | `generation_failed` | Generation error | Accepted work reached a terminal failure. Inspect final usage, then retry only when the generation is eligible. | | `invalid_output` | Generation error | Completed work did not satisfy the task's public output contract. Treat the generation as failed and preserve its ID for support. | --- # Webhook reference > Inspect supported generation events, endpoint schemas, payload shape, signature headers, and delivery behavior. Canonical: https://entirefeed.com/docs/reference/webhooks Webhook payloads carry the same public generation object returned by the REST API. Workflow-run events are not part of the current registration contract. ## Endpoint management | Method | Path | Behavior | | --- | --- | --- | | `POST` | `/v1/webhooks/endpoints` | Create an active endpoint and receive its signing secret once. | | `GET` | `/v1/webhooks/endpoints` | List endpoints without returning signing secrets. | | `DELETE` | `/v1/webhooks/endpoints/{endpoint_id}` | Deactivate an endpoint. A successful response has no body. | ## Supported events - `generation.queued` - `generation.running` - `generation.succeeded` - `generation.failed` - `generation.cancelled` - `generation.manual_review` - `workflow_run.queued` - `workflow_run.running` - `workflow_run.succeeded` - `workflow_run.failed` - `workflow_run.cancelled` - `workflow_run.manual_review` ## Payload shape ```json { "id": "evt_0123456789abcdef0123456789abcdef", "type": "generation.succeeded", "created_at": "2026-07-12T08:31:14Z", "data": { "object": { "id": "gen_0123456789abcdef0123456789abcdef", "object": "generation", "status": "succeeded", "model": "seedance-2", "task": "video.create", "created_at": "2026-07-12T08:30:00Z", "completed_at": "2026-07-12T08:31:14Z", "output": { "assets": [ { "id": "asset_0123456789abcdef0123456789abcdef", "type": "video", "url": "https://cdn.entirefeed.com/examples/product-reveal.mp4", "mime_type": "video/mp4", "expires_at": null } ] }, "usage": { "amount_usd": "1.20", "line_items": [], "billing_status": "settled" }, "error": null, "metadata": null } } } ``` ## Signature headers - `EntireFeed-Signature`: `t={unix_seconds},v1={hmac_sha256_hex}`; HMAC-SHA256 over timestamp + period + exact raw body. - `EntireFeed-Event-ID`: stable across retries; use it for deduplication. - Retry delays: 1m, 5m, 30m, 2h, 12h; each request times out after 10 seconds. --- # Billing reference > Inspect balance fields, usage states, ledger entry types, filters, and read-only billing endpoints. Canonical: https://entirefeed.com/docs/reference/billing All public billing amounts are decimal USD strings. Do not parse them as binary floating-point values when exact accounting matters. ## Balance response ```json { "properties": { "available": { "$ref": "#/components/schemas/Money" }, "currency": { "const": "usd", "default": "usd", "title": "Currency", "type": "string" }, "reserved": { "$ref": "#/components/schemas/Money" }, "total": { "$ref": "#/components/schemas/Money" } }, "required": [ "available", "reserved", "total" ], "title": "BillingSummaryResponse", "type": "object" } ``` ## Usage status - `reserved`: The current estimate is held while work is active. Included in reserved balance, not available balance. - `settled`: Final usage was charged. The settled amount remains spent; unused hold can be released. - `released`: The held amount was returned. Released funds are available again. - `manual_review`: Final cost could not be resolved automatically. The hold remains unavailable until resolution. ## Ledger entries Entry types: `TOP_UP`, `RESERVE`, `RELEASE`, `SETTLE`, `ADJUSTMENT`, `REFUND`, `ADMIN_CREDIT`. ```json { "properties": { "amount_usd": { "title": "Amount Usd", "type": "string" }, "available_after_usd": { "title": "Available After Usd", "type": "string" }, "created_at": { "format": "date-time", "title": "Created At", "type": "string" }, "description": { "title": "Description", "type": "string" }, "generation_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Generation Id" }, "id": { "title": "Id", "type": "string" }, "reserved_after_usd": { "title": "Reserved After Usd", "type": "string" }, "type": { "enum": [ "TOP_UP", "RESERVE", "RELEASE", "SETTLE", "ADJUSTMENT", "REFUND", "ADMIN_CREDIT" ], "title": "Type", "type": "string" }, "workflow_run_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Workflow Run Id" } }, "required": [ "id", "type", "amount_usd", "available_after_usd", "reserved_after_usd", "description", "created_at" ], "title": "BillingLedgerEntryResponse", "type": "object" } ``` ## Adjustment limit | Scenario | Amounts | Result | | --- | --- | --- | | Final cost below reservation | $1.20 reserved; $0.90 final | Settle $0.90 and release $0.30 to available balance. | | Overage covered | $1.20 reserved; $1.50 final; at least $0.30 available | Settle $1.20 and debit a $0.30 adjustment. | | Overage capped | $1.20 reserved; $1.50 final; $0.20 available | Settle $1.20 and debit a $0.20 adjustment. Available balance stops at $0.00. | Maximum additional debit: `available_balance`. A settlement never creates a negative available balance. --- # MCP tool reference > Inspect every Console MCP tool, delegated authority rule, required input, and generated input and output schema. Canonical: https://entirefeed.com/docs/reference/mcp This reference mirrors the current public MCP catalog. Clients should load the live server's tool list when connecting and use this page for review, indexing, and agent-readable schema detail. ## Authority and connection Endpoint: `https://api.entirefeed.com/mcp/` Credential: `efmcp_live_...`; delegated current-user authority. Current membership, role, and capabilities on every request. Server operating guidance: Call get_console_agent_best_practices with the topic closest to your next action before workflow edits, paid runs, output review, or publishing actions. Estimate generation requests before creating them. Stable caller-generated idempotency keys are required for generation create and retry. Use compact task/model lists, then get one task for full schemas. For local media, prepare a one-time upload and send raw multipart bytes to the returned handoff before using its HTTPS URL. Use workflow list/search tools for compact discovery. Call get_console_workflow before editing or running a workflow, then pass the returned definition_hash as expected_definition_hash. Do not compute workflow hashes yourself. For publishing, list compact summaries first, call get_console_publishing_post before edits, schedule with explicit scheduled_for and IANA timezone, and use scheduled_post_id for reschedule or cancel. publish-now is intentionally unavailable. | Action | Required capability | | --- | --- | | Discover and inspect generation | `generations:read` | | Estimate, create, or retry generation | `playground:run` | | Prepare a local media upload | `workflows:run` | | Cancel generation | `generations:cancel` | | Read, edit, or run workflows | `workflows:read, workflows:manage, workflows:run` | | Read or edit publishing drafts | `publishing:read, publishing:manage` | | Schedule, reschedule, or cancel | `publishing:schedule` | | Read publishing analytics | `publishing:analytics:read` | ## Generated tool contracts Current catalog: 52 tools across 5 guide categories. ### Guidance #### `get_console_agent_best_practices` Return concise, topic-specific best-practice guidance for Console agents. Use when the agent needs output-quality, workflow-construction, format-analysis, prompting, asset, or publishing-quality, or billing guidance. Topics: workflow_construction, prompting, reference_video_analysis, workflow_validation, billing, video_generation, output_review, assets_personas_voices, publishing_approval, anti_overfitting. Required inputs: none. Input schema: ```json { "properties": { "topic": { "default": "workflow_construction", "title": "Topic", "type": "string" } }, "title": "get_console_agent_best_practicesArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_agent_best_practicesDictOutput", "type": "object" } ``` ### Media uploads #### `prepare_console_media_upload` Prepare a short-lived, one-time multipart upload for a local image, video, or audio file. Send the raw file bytes directly to the returned URL using its method, headers, and form field; do not encode the file as base64. The upload response URL can be used in generation and workflow inputs. Required inputs: `filename`, `content_type`, `size_bytes`. Input schema: ```json { "properties": { "content_type": { "maxLength": 100, "minLength": 1, "title": "Content Type", "type": "string" }, "filename": { "maxLength": 255, "minLength": 1, "title": "Filename", "type": "string" }, "sha256": { "anyOf": [ { "maxLength": 64, "minLength": 64, "type": "string" }, { "type": "null" } ], "default": null, "title": "Sha256" }, "size_bytes": { "exclusiveMinimum": 0, "title": "Size Bytes", "type": "integer" } }, "required": [ "filename", "content_type", "size_bytes" ], "title": "prepare_console_media_uploadArguments", "type": "object" } ``` Output schema: ```json { "$defs": { "MediaUploadHandoffResponse": { "properties": { "expires_at": { "format": "date-time", "title": "Expires At", "type": "string" }, "form_field": { "const": "file", "default": "file", "title": "Form Field", "type": "string" }, "headers": { "additionalProperties": { "type": "string" }, "title": "Headers", "type": "object" }, "max_size_bytes": { "exclusiveMinimum": 0, "title": "Max Size Bytes", "type": "integer" }, "method": { "const": "POST", "default": "POST", "title": "Method", "type": "string" }, "url": { "title": "Url", "type": "string" } }, "required": [ "url", "headers", "expires_at", "max_size_bytes" ], "title": "MediaUploadHandoffResponse", "type": "object" } }, "properties": { "next": { "title": "Next", "type": "string" }, "upload": { "$ref": "#/$defs/MediaUploadHandoffResponse" } }, "required": [ "upload", "next" ], "title": "MediaUploadHandoffToolResponse", "type": "object" } ``` ### Generation #### `cancel_console_generation` Cancel one queued or running generation by gen_... id. Required inputs: `generation_id`. Input schema: ```json { "properties": { "generation_id": { "title": "Generation Id", "type": "string" } }, "required": [ "generation_id" ], "title": "cancel_console_generationArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "cancel_console_generationDictOutput", "type": "object" } ``` #### `create_console_generation` Create one generation. Supply a stable caller-generated idempotency key to deduplicate retries. Model-less tasks must omit model. Required inputs: `task`, `input`, `idempotency_key`. Input schema: ```json { "properties": { "idempotency_key": { "maxLength": 255, "minLength": 1, "title": "Idempotency Key", "type": "string" }, "input": { "additionalProperties": true, "title": "Input", "type": "object" }, "metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Metadata" }, "model": { "default": null, "title": "Model", "type": "string" }, "task": { "title": "Task", "type": "string" } }, "required": [ "task", "input", "idempotency_key" ], "title": "create_console_generationArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "create_console_generationDictOutput", "type": "object" } ``` #### `estimate_console_generation` Estimate one generation request without creating it. Model-less tasks must omit model. Required inputs: `task`, `input`. Input schema: ```json { "properties": { "input": { "additionalProperties": true, "title": "Input", "type": "object" }, "model": { "default": null, "title": "Model", "type": "string" }, "task": { "title": "Task", "type": "string" } }, "required": [ "task", "input" ], "title": "estimate_console_generationArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "estimate_console_generationDictOutput", "type": "object" } ``` #### `get_console_generation` Get one generation with its output, usage, error, and metadata. Required inputs: `generation_id`. Input schema: ```json { "properties": { "generation_id": { "title": "Generation Id", "type": "string" } }, "required": [ "generation_id" ], "title": "get_console_generationArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_generationDictOutput", "type": "object" } ``` #### `get_console_generation_task` Get one generation task with its available models, schemas, defaults, and output schema. Required inputs: `task_id`. Input schema: ```json { "properties": { "task_id": { "title": "Task Id", "type": "string" } }, "required": [ "task_id" ], "title": "get_console_generation_taskArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_generation_taskDictOutput", "type": "object" } ``` #### `list_console_generation_models` List generation models as compact summaries. Schemas and defaults are intentionally omitted; inspect the relevant task with get_console_generation_task. Required inputs: none. Input schema: ```json { "properties": {}, "title": "list_console_generation_modelsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_generation_modelsDictOutput", "type": "object" } ``` #### `list_console_generation_tasks` List generation tasks as compact summaries, including available and coming-soon tasks. Call get_console_generation_task for schemas and defaults. Required inputs: none. Input schema: ```json { "properties": {}, "title": "list_console_generation_tasksArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_generation_tasksDictOutput", "type": "object" } ``` #### `list_console_generations` List generations as compact summaries without API-key or input details. Required inputs: none. Input schema: ```json { "properties": { "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cursor" }, "limit": { "default": 50, "title": "Limit", "type": "integer" }, "model": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Model" }, "status": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Status" }, "task": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Task" } }, "title": "list_console_generationsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_generationsDictOutput", "type": "object" } ``` #### `retry_console_generation` Retry a failed or cancelled generation as a new billed request. Requires a caller-supplied idempotency key. Required inputs: `generation_id`, `idempotency_key`. Input schema: ```json { "properties": { "generation_id": { "title": "Generation Id", "type": "string" }, "idempotency_key": { "maxLength": 255, "minLength": 1, "title": "Idempotency Key", "type": "string" } }, "required": [ "generation_id", "idempotency_key" ], "title": "retry_console_generationArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "retry_console_generationDictOutput", "type": "object" } ``` ### Workflows #### `cancel_console_workflow_run` Cancel an active Console workflow run. Required inputs: `run_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Reason" }, "run_id": { "title": "Run Id", "type": "string" }, "run_tab_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Run Tab Id" } }, "required": [ "run_id" ], "title": "cancel_console_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "cancel_console_workflow_runDictOutput", "type": "object" } ``` #### `cancel_public_workflow_run` Cancel a queued or active public workflow starter run by wrun_... id. Required inputs: `workflow_run_id`. Input schema: ```json { "properties": { "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Reason" }, "workflow_run_id": { "title": "Workflow Run Id", "type": "string" } }, "required": [ "workflow_run_id" ], "title": "cancel_public_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "cancel_public_workflow_runDictOutput", "type": "object" } ``` #### `create_console_workflow` Create a Console workflow from a full workflow definition. Required inputs: `name`, `definition`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "definition": { "additionalProperties": true, "title": "Definition", "type": "object" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Description" }, "name": { "title": "Name", "type": "string" } }, "required": [ "name", "definition" ], "title": "create_console_workflowArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "create_console_workflowDictOutput", "type": "object" } ``` #### `create_console_workflow_from_starter` Create a Console workflow from a supported workflow starter template. Required inputs: `starter_slug`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Description" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Name" }, "starter_slug": { "title": "Starter Slug", "type": "string" } }, "required": [ "starter_slug" ], "title": "create_console_workflow_from_starterArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "create_console_workflow_from_starterDictOutput", "type": "object" } ``` #### `delete_console_workflow` Soft-delete a Console workflow from active workflow lists. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "delete_console_workflowArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": { "type": "string" }, "title": "delete_console_workflowDictOutput", "type": "object" } ``` #### `estimate_console_workflow_run` Estimate a Console workflow run and return cost plus estimate_version for run_console_workflow. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "definition_override": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Definition Override" }, "expected_definition_hash": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Expected Definition Hash" }, "inputs": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Inputs" }, "source_execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Source Execution Id" }, "target_node_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Target Node Id" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "estimate_console_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "estimate_console_workflow_runDictOutput", "type": "object" } ``` #### `estimate_public_workflow_starter_run` Estimate a public workflow starter run and return estimate_version for run_public_workflow_starter. Required inputs: `starter_slug`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "inputs": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Inputs" }, "starter_slug": { "title": "Starter Slug", "type": "string" }, "starter_version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Starter Version" } }, "required": [ "starter_slug" ], "title": "estimate_public_workflow_starter_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "estimate_public_workflow_starter_runDictOutput", "type": "object" } ``` #### `get_console_workflow` Get one Console workflow including its full definition and revision hashes. Use definition_hash as expected_definition_hash for edits and runs. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "get_console_workflowArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_workflowDictOutput", "type": "object" } ``` #### `get_console_workflow_node_schema` Fetch the full schema for one workflow node type. Required inputs: `node_type`. Input schema: ```json { "properties": { "node_type": { "title": "Node Type", "type": "string" } }, "required": [ "node_type" ], "title": "get_console_workflow_node_schemaArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_workflow_node_schemaDictOutput", "type": "object" } ``` #### `get_console_workflow_run` Get one Console workflow run with compact jobs, outputs, and error information. Required inputs: `run_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "include": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": "jobs", "title": "Include" }, "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id" ], "title": "get_console_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_workflow_runDictOutput", "type": "object" } ``` #### `get_public_workflow_run` Get one public workflow starter run by wrun_... id. Required inputs: `workflow_run_id`. Input schema: ```json { "properties": { "workflow_run_id": { "title": "Workflow Run Id", "type": "string" } }, "required": [ "workflow_run_id" ], "title": "get_public_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_public_workflow_runDictOutput", "type": "object" } ``` #### `get_public_workflow_starter` Get one public workflow starter with its public input/output schemas and example payloads. Required inputs: `starter_slug`. Input schema: ```json { "properties": { "starter_slug": { "title": "Starter Slug", "type": "string" } }, "required": [ "starter_slug" ], "title": "get_public_workflow_starterArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_public_workflow_starterDictOutput", "type": "object" } ``` #### `list_active_console_workflow_runs` List active Console workflow runs with compact status details. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "include": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Include" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "list_active_console_workflow_runsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_active_console_workflow_runsDictOutput", "type": "object" } ``` #### `list_console_workflow_nodes` List workflow node types as compact summaries. Use get_console_workflow_node_schema for one full schema. Required inputs: none. Input schema: ```json { "properties": { "category": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Category" }, "limit": { "default": 80, "title": "Limit", "type": "integer" } }, "title": "list_console_workflow_nodesArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_workflow_nodesDictOutput", "type": "object" } ``` #### `list_console_workflow_runs` List compact historical runs for a Console workflow. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "limit": { "default": 10, "title": "Limit", "type": "integer" }, "offset": { "default": 0, "title": "Offset", "type": "integer" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "list_console_workflow_runsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_workflow_runsDictOutput", "type": "object" } ``` #### `list_console_workflow_starters` List Console workflow starters that can create starter workflows. Required inputs: none. Input schema: ```json { "properties": {}, "title": "list_console_workflow_startersArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_workflow_startersDictOutput", "type": "object" } ``` #### `list_console_workflows` List Console workflows as compact summaries. Does not return workflow definitions. Use get_console_workflow when you need the full graph and definition_hash. Required inputs: none. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "limit": { "default": 50, "title": "Limit", "type": "integer" }, "offset": { "default": 0, "title": "Offset", "type": "integer" }, "search": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Search" } }, "title": "list_console_workflowsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_workflowsDictOutput", "type": "object" } ``` #### `list_public_workflow_runs` List public workflow starter runs with optional status and starter filters. Required inputs: none. Input schema: ```json { "properties": { "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cursor" }, "limit": { "default": 50, "title": "Limit", "type": "integer" }, "starter_slug": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Starter Slug" }, "status": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Status" } }, "title": "list_public_workflow_runsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_public_workflow_runsDictOutput", "type": "object" } ``` #### `list_public_workflow_starters` List public workflow starters that can be estimated and run without exposing the workflow builder. Required inputs: none. Input schema: ```json { "properties": {}, "title": "list_public_workflow_startersArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_public_workflow_startersDictOutput", "type": "object" } ``` #### `pin_console_workflow_node` Pin a Console workflow node from an existing completed workflow run/job. Only use when the user explicitly asks to pin or reuse a node output; pinning mutates workflow state and changes workflow hashes. source_execution_id must be the workflow run id returned by get_console_workflow_run, not the operation_id returned by run_console_workflow. Requires the current definition_hash as expected_definition_hash. Required inputs: `workflow_id`, `node_id`, `source_execution_id`, `expected_definition_hash`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "expected_definition_hash": { "title": "Expected Definition Hash", "type": "string" }, "node_id": { "title": "Node Id", "type": "string" }, "source_execution_id": { "title": "Source Execution Id", "type": "string" }, "source_job_ids": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Source Job Ids" }, "upstream_hash": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Upstream Hash" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id", "node_id", "source_execution_id", "expected_definition_hash" ], "title": "pin_console_workflow_nodeArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "pin_console_workflow_nodeDictOutput", "type": "object" } ``` #### `retry_console_workflow_run` Retry a failed or cancelled Console workflow run. Requires an idempotency_key. Required inputs: `run_id`, `idempotency_key`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "idempotency_key": { "title": "Idempotency Key", "type": "string" }, "run_id": { "title": "Run Id", "type": "string" } }, "required": [ "run_id", "idempotency_key" ], "title": "retry_console_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "retry_console_workflow_runDictOutput", "type": "object" } ``` #### `retry_public_workflow_run` Retry a failed or cancelled public workflow starter run. Requires an idempotency_key. Required inputs: `workflow_run_id`, `idempotency_key`. Input schema: ```json { "properties": { "idempotency_key": { "title": "Idempotency Key", "type": "string" }, "workflow_run_id": { "title": "Workflow Run Id", "type": "string" } }, "required": [ "workflow_run_id", "idempotency_key" ], "title": "retry_public_workflow_runArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "retry_public_workflow_runDictOutput", "type": "object" } ``` #### `run_console_workflow` Run a Console workflow after estimating it. Requires an idempotency_key for billable safety. Required inputs: `workflow_id`, `estimate_version`, `expected_definition_hash`, `idempotency_key`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "definition_override": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Definition Override" }, "estimate_version": { "title": "Estimate Version", "type": "string" }, "expected_definition_hash": { "title": "Expected Definition Hash", "type": "string" }, "idempotency_key": { "title": "Idempotency Key", "type": "string" }, "inputs": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Inputs" }, "source_execution_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Source Execution Id" }, "target_node_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Target Node Id" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id", "estimate_version", "expected_definition_hash", "idempotency_key" ], "title": "run_console_workflowArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "run_console_workflowDictOutput", "type": "object" } ``` #### `run_public_workflow_starter` Run a public workflow starter after estimating it. Requires an idempotency_key for billable safety. Required inputs: `starter_slug`, `estimate_version`, `idempotency_key`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "estimate_version": { "title": "Estimate Version", "type": "string" }, "idempotency_key": { "title": "Idempotency Key", "type": "string" }, "inputs": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Inputs" }, "metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Metadata" }, "starter_slug": { "title": "Starter Slug", "type": "string" }, "starter_version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Starter Version" } }, "required": [ "starter_slug", "estimate_version", "idempotency_key" ], "title": "run_public_workflow_starterArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "run_public_workflow_starterDictOutput", "type": "object" } ``` #### `search_console_workflow_nodes` Search workflow node types by node type, label, description, category, inputs, and outputs. Required inputs: `query`. Input schema: ```json { "properties": { "limit": { "default": 20, "title": "Limit", "type": "integer" }, "query": { "title": "Query", "type": "string" } }, "required": [ "query" ], "title": "search_console_workflow_nodesArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "search_console_workflow_nodesDictOutput", "type": "object" } ``` #### `unpin_console_workflow_node` Unpin a Console workflow node, restoring normal execution for that node. Requires the current definition_hash as expected_definition_hash. Required inputs: `workflow_id`, `node_id`, `expected_definition_hash`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "expected_definition_hash": { "title": "Expected Definition Hash", "type": "string" }, "node_id": { "title": "Node Id", "type": "string" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id", "node_id", "expected_definition_hash" ], "title": "unpin_console_workflow_nodeArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "unpin_console_workflow_nodeDictOutput", "type": "object" } ``` #### `update_console_workflow_definition` Replace a Console workflow definition. expected_definition_hash must be the definition_hash returned by get_console_workflow or the previous write result. Required inputs: `workflow_id`, `definition`, `expected_definition_hash`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "definition": { "additionalProperties": true, "title": "Definition", "type": "object" }, "expected_definition_hash": { "title": "Expected Definition Hash", "type": "string" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id", "definition", "expected_definition_hash" ], "title": "update_console_workflow_definitionArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "update_console_workflow_definitionDictOutput", "type": "object" } ``` #### `update_console_workflow_metadata` Update Console workflow metadata without changing the graph definition. Required inputs: `workflow_id`. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Description" }, "expected_definition_hash": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Expected Definition Hash" }, "is_active": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "default": null, "title": "Is Active" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Name" }, "workflow_id": { "title": "Workflow Id", "type": "string" } }, "required": [ "workflow_id" ], "title": "update_console_workflow_metadataArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "update_console_workflow_metadataDictOutput", "type": "object" } ``` ### Publishing #### `cancel_console_publishing_scheduled_post` Cancel an existing scheduled publishing action by explicit scheduled_post_id. This does not delete the draft post. PENDING, QUEUED, CLAIMED, and FAILED scheduled actions can be cancelled. Required inputs: `scheduled_post_id`. Input schema: ```json { "properties": { "scheduled_post_id": { "title": "Scheduled Post Id", "type": "string" } }, "required": [ "scheduled_post_id" ], "title": "cancel_console_publishing_scheduled_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "cancel_console_publishing_scheduled_postDictOutput", "type": "object" } ``` #### `create_console_publishing_post` Create a TikTok publishing draft from HTTPS media references. Supported content types are VIDEO, IMAGE, and CAROUSEL. This does not schedule or publish the post; call schedule_console_publishing_post separately with the returned post id. Required inputs: `account_id`, `platform`, `content_type`, `media_urls`. Input schema: ```json { "properties": { "account_id": { "title": "Account Id", "type": "string" }, "caption": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Caption" }, "caption_plain": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Caption Plain" }, "content": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Content" }, "content_type": { "enum": [ "VIDEO", "IMAGE", "CAROUSEL" ], "title": "Content Type", "type": "string" }, "generation_metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Generation Metadata" }, "generation_prompt": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Generation Prompt" }, "hashtags": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Hashtags" }, "media_count": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "default": null, "title": "Media Count" }, "media_urls": { "items": { "type": "string" }, "title": "Media Urls", "type": "array" }, "mentions": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Mentions" }, "platform": { "const": "TIKTOK", "title": "Platform", "type": "string" }, "platform_metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Platform Metadata" }, "render_metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Render Metadata" }, "source_metadata": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "default": null, "title": "Source Metadata" }, "source_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Source Url" }, "thumbnail_url": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Thumbnail Url" }, "title": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Title" } }, "required": [ "account_id", "platform", "content_type", "media_urls" ], "title": "create_console_publishing_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "create_console_publishing_postDictOutput", "type": "object" } ``` #### `get_console_publishing_analytics_breakdown` Get compact publishing analytics grouped by account, platform, status, or content_type. Required inputs: `group_by`. Input schema: ```json { "properties": { "from_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "From Time" }, "group_by": { "enum": [ "account", "platform", "status", "content_type" ], "title": "Group By", "type": "string" }, "to_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "To Time" } }, "required": [ "group_by" ], "title": "get_console_publishing_analytics_breakdownArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_publishing_analytics_breakdownDictOutput", "type": "object" } ``` #### `get_console_publishing_analytics_summary` Get a compact publishing analytics summary for an optional date, account, or post filter. Required inputs: none. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "from_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "From Time" }, "post_ids": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Post Ids" }, "to_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "To Time" } }, "title": "get_console_publishing_analytics_summaryArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_publishing_analytics_summaryDictOutput", "type": "object" } ``` #### `get_console_publishing_analytics_timeseries` Get compact daily publishing analytics points. Only day interval is supported. Required inputs: none. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "from_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "From Time" }, "interval": { "const": "day", "default": "day", "title": "Interval", "type": "string" }, "to_time": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "To Time" } }, "title": "get_console_publishing_analytics_timeseriesArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_publishing_analytics_timeseriesDictOutput", "type": "object" } ``` #### `get_console_publishing_post` Get one Console publishing post with full edit context, including captions, media URLs, sanitized metadata, schedules, and analytics snapshots. Required inputs: `post_id`. Input schema: ```json { "properties": { "post_id": { "title": "Post Id", "type": "string" } }, "required": [ "post_id" ], "title": "get_console_publishing_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_publishing_postDictOutput", "type": "object" } ``` #### `get_console_publishing_schedule_board` Get a compact publishing schedule board across active schedules and recent publish activity. Required inputs: none. Input schema: ```json { "properties": { "activity_since": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Activity Since" }, "limit": { "default": 250, "title": "Limit", "type": "integer" } }, "title": "get_console_publishing_schedule_boardArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "get_console_publishing_schedule_boardDictOutput", "type": "object" } ``` #### `list_console_publishing_accounts` List Console publishing accounts with compact capability and integration status. Required inputs: none. Input schema: ```json { "properties": {}, "title": "list_console_publishing_accountsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_publishing_accountsDictOutput", "type": "object" } ``` #### `list_console_publishing_posts` List Console publishing posts as compact summaries. Does not include full captions, metadata blobs, source metadata, generation metadata, analytics snapshots, or media URLs. Use get_console_publishing_post for full edit context. Required inputs: none. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "created_after": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Created After" }, "created_before": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Created Before" }, "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cursor" }, "limit": { "default": 50, "title": "Limit", "type": "integer" }, "platform": { "anyOf": [ { "const": "TIKTOK", "type": "string" }, { "type": "null" } ], "default": null, "title": "Platform" }, "published_after": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Published After" }, "published_before": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Published Before" }, "search": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Search" }, "sort": { "default": "created_desc", "enum": [ "created_desc", "updated_desc", "published_desc", "views_desc" ], "title": "Sort", "type": "string" }, "status": { "anyOf": [ { "enum": [ "DRAFT", "PENDING_REVIEW", "APPROVED", "SCHEDULED", "QUEUED", "PUBLISHING", "PUBLISHED", "FAILED", "ARCHIVED" ], "type": "string" }, { "type": "null" } ], "default": null, "title": "Status" } }, "title": "list_console_publishing_postsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_publishing_postsDictOutput", "type": "object" } ``` #### `list_console_publishing_scheduled_posts` List compact Console scheduled publishing actions. Use explicit scheduled_post_id for changes. Required inputs: none. Input schema: ```json { "properties": { "account_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Account Id" }, "completed_since": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Completed Since" }, "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cursor" }, "limit": { "default": 100, "title": "Limit", "type": "integer" }, "status": { "anyOf": [ { "enum": [ "PENDING", "QUEUED", "CLAIMED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED", "SKIPPED" ], "type": "string" }, { "type": "null" } ], "default": null, "title": "Status" }, "statuses": { "anyOf": [ { "items": { "enum": [ "PENDING", "QUEUED", "CLAIMED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED", "SKIPPED" ], "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Statuses" } }, "title": "list_console_publishing_scheduled_postsArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "list_console_publishing_scheduled_postsDictOutput", "type": "object" } ``` #### `reschedule_console_publishing_scheduled_post` Reschedule an existing scheduled publishing action. Requires explicit scheduled_post_id, scheduled_for, and IANA timezone; do not infer the schedule from a post id. PENDING, QUEUED, CLAIMED, and FAILED scheduled actions can be rescheduled. Required inputs: `scheduled_post_id`, `scheduled_for`, `timezone`. Input schema: ```json { "properties": { "scheduled_for": { "title": "Scheduled For", "type": "string" }, "scheduled_post_id": { "title": "Scheduled Post Id", "type": "string" }, "timezone": { "title": "Timezone", "type": "string" } }, "required": [ "scheduled_post_id", "scheduled_for", "timezone" ], "title": "reschedule_console_publishing_scheduled_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "reschedule_console_publishing_scheduled_postDictOutput", "type": "object" } ``` #### `schedule_console_publishing_post` Schedule an existing Console publishing post. Requires explicit scheduled_for and IANA timezone; do not parse fuzzy natural-language times or guess ambiguous user intent. Required inputs: `post_id`, `scheduled_for`, `timezone`. Input schema: ```json { "properties": { "post_id": { "title": "Post Id", "type": "string" }, "scheduled_for": { "title": "Scheduled For", "type": "string" }, "timezone": { "title": "Timezone", "type": "string" } }, "required": [ "post_id", "scheduled_for", "timezone" ], "title": "schedule_console_publishing_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "schedule_console_publishing_postDictOutput", "type": "object" } ``` #### `update_console_publishing_post` Partially update a Console publishing post. Pass a patch object using ConsolePublishingPostUpdateRequest fields; omitted fields stay unchanged, and explicit null clears nullable fields. This does not schedule or publish the post. Required inputs: `post_id`, `patch`. Input schema: ```json { "properties": { "patch": { "additionalProperties": true, "title": "Patch", "type": "object" }, "post_id": { "title": "Post Id", "type": "string" } }, "required": [ "post_id", "patch" ], "title": "update_console_publishing_postArguments", "type": "object" } ``` Output schema: ```json { "additionalProperties": true, "title": "update_console_publishing_postDictOutput", "type": "object" } ``` ## Guide coverage - `cancel_console_generation`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `cancel_console_publishing_scheduled_post`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `cancel_console_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `cancel_public_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `create_console_generation`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `create_console_publishing_post`: [guide](/docs/publishing/accounts-and-posts); [reference](/docs/reference/mcp) - `create_console_workflow`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `create_console_workflow_from_starter`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `delete_console_workflow`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `estimate_console_generation`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `estimate_console_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `estimate_public_workflow_starter_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_console_agent_best_practices`: [guide](/docs/agents/paid-actions-and-review); [reference](/docs/reference/mcp) - `get_console_generation`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_console_generation_task`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_console_publishing_analytics_breakdown`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `get_console_publishing_analytics_summary`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `get_console_publishing_analytics_timeseries`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `get_console_publishing_post`: [guide](/docs/publishing/accounts-and-posts); [reference](/docs/reference/mcp) - `get_console_publishing_schedule_board`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `get_console_workflow`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_console_workflow_node_schema`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_console_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_public_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `get_public_workflow_starter`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_active_console_workflow_runs`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_generation_models`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_generation_tasks`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_generations`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_publishing_accounts`: [guide](/docs/publishing/accounts-and-posts); [reference](/docs/reference/mcp) - `list_console_publishing_posts`: [guide](/docs/publishing/accounts-and-posts); [reference](/docs/reference/mcp) - `list_console_publishing_scheduled_posts`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `list_console_workflow_nodes`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_workflow_runs`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_workflow_starters`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_console_workflows`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_public_workflow_runs`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `list_public_workflow_starters`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `pin_console_workflow_node`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `prepare_console_media_upload`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `reschedule_console_publishing_scheduled_post`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `retry_console_generation`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `retry_console_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `retry_public_workflow_run`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `run_console_workflow`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `run_public_workflow_starter`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `schedule_console_publishing_post`: [guide](/docs/publishing/schedules); [reference](/docs/reference/mcp) - `search_console_workflow_nodes`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `unpin_console_workflow_node`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `update_console_publishing_post`: [guide](/docs/publishing/accounts-and-posts); [reference](/docs/reference/mcp) - `update_console_workflow_definition`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp) - `update_console_workflow_metadata`: [guide](/docs/agents/tasks-and-workflows); [reference](/docs/reference/mcp)