Hosted video generation
Request measured video through an approved host capability.
Use runtime: "capability" and permissions.capabilities: ["video.generate"]. Declare one text, script or brief prompt input, up to two image inputs for the first and last frame, and one video output. Every video model the app's own Blocks use is available — Seedance 2.0 (and Fast, Mini), Kling 3.0 Turbo, Wan 2.6 Flash, Veo 3.1 Lite, Vidu Q3 Turbo and Wan 2.7 — with their durations, resolutions, aspect ratios, image-to-video and first-and-last-frame modes (see generation models). Users pay with StillMade credits at StillMade's per-second price. The capability file is:
{"schemaVersion":1,"operation":"video.generate","prompt":{"$input":"prompt"},
"firstFrame":{"$input":"start"},"lastFrame":{"$input":"end"},
"settings":{"model":"veo-3.1-lite","duration":6,"resolution":"720p","aspectRatio":"16:9","generateAudio":true},
"negativePrompt":"blur","seed":7,"output":"video"}settings, firstFrame, lastFrame, negativePrompt and seed are optional; each setting must be one the model accepts (Veo locks 1080p to 8 seconds; Wan 2.7 needs a first frame). Never include provider endpoints, keys, prices or payment. The run dialog preselects the Block's defaults and the user may change them before seeing the exact price. The invocation is {operation:"video.generate",prompt} plus firstFrame, lastFrame, negativePrompt and seed when declared; frames must be the user's own saved images. Public trials use their separately reviewed acquisition policy and never account BYOK.
The canonical output has kind:"video", bounded assetId/versionId, a stored HTTPS or host media url, mimeType:"video/mp4", measured width, height, duration in seconds and bytes. The host keeps the provider's MP4 byte-for-byte after measuring its container. SDK limits are 60 seconds, 256 MiB, at most 3,840 pixels on either axis and 8,294,400 pixels per frame. Validating this shape does not verify ownership or real video bytes; the host must inspect, store and verify them.
Fixtures use kind:"video", format:"mp4" and explicit minDuration, maxDuration, minBytes, maxBytes, minWidth, maxWidth, minHeight, maxHeight bounds. See packages/block-sdk/video-generation-example.js. Provider fixtures require approval; they are not deterministic equality tests. validateGeneratedVideoReference, defaultCapabilityExpectations and validateCapabilityResult are available through the SDK. Media receipts bind the owner, run, invocation, storage key and SHA-256 digest to the complete output reference. Guest code cannot issue those receipts.
A host advertises only enabled operations. A valid package does not imply every deployment has video generation configured; unavailable hosts must reject it before billing or dispatch. Public video results use the same private media/claim lifecycle as other trial outputs and are retained when continuing in an account.
Authored state migration routes
A new JavaScript Block release can optionally declare manifest.state.migrations for explicit upgrades of its Step memory. A route's fromVersion is an older positive state schema version; its destination is the enclosing state.version. For example, a declaration for state version 2 can contain:
"migrations": [{
"fromVersion": 1,
"operations": [
{ "op": "rename", "from": "count", "to": "completed" },
{ "op": "default", "key": "labels", "value": [] },
{ "op": "remove", "key": "temporary" }
]
}]Operations run in order on safe ASCII top-level field names. Rename requires an existing source and absent destination; default writes only if absent; remove requires the field to exist. Nested values remain intact. There are at most 16 distinct older-version routes and 64 operations per route. Combined declarations and every intermediate state each fit within 64 KiB. An empty operation list explicitly advances only the schema version. There is no implicit chaining, downgrade, deep-path transformation, expression evaluation or code execution.
The portable SDK exports validateStateMigrations(stateDeclaration), stateMigrationRoute(manifest, fromVersion), and migrateBlockState(previousManifest, nextManifest, savedState). The last returns {state, operations, fromVersion, toVersion} without modifying its inputs. Both manifests must describe the same JavaScript Block identity, with valid state contracts. Matching state versions use an identity transfer; changed versions require an exact direct route. Runtime execution does not invoke migrations.
Migration declarations change package source: publish a new immutable Block release and keep its fixtures on the target schema. Do not guess existing state fields or reset user memory. In StillMade, owners review exact archived/current source pins, operations and before/after memory, then explicitly apply. The host rechecks account/project/source/state, retains rollback history and invalidates downstream results. External hosts must provide equivalent ownership, source verification, approval and rollback boundaries before accepting the result.