Skip to content

Assets, jobs and delivery

Upload media, preserve task identity and recover work without duplicate submissions.

Import a file in two steps

First call upload_create with the original filename, exact byte count, SHA-256 digest, source, license and rightsConfirmed: true. The result includes uploadUrl and method: PUT. Upload the raw bytes to that returned path on the same runtime origin with the same Bearer key. The completed upload returns an asset record; use its id in later operations. Remote runtimes cannot read a path on your computer.

FieldType / requirement
namestring · Original filename.
bytespositive integer · Exact file length.
sha256string · Digest of the same bytes you will upload.
source / licensestrings · Accurate provenance and usage rights.
rightsConfirmedtrue · Only for media you have permission to use.

Node.js upload example

Append this to the API guide’s callTool helper. Replace ./product.png with your own file. The local upload route accepts up to 100 MiB; a selected model may impose smaller limits, dimensions or duration requirements. Validate those separately before preparing generation.

javascript
import { readFile } from "node:fs/promises";
import { createHash } from "node:crypto";

const bytes = await readFile("./product.png");
const intent = await callTool("upload_create", {
  name: "product.png",
  bytes: bytes.byteLength,
  sha256: createHash("sha256").update(bytes).digest("hex"),
  source: "My product photography",
  license: "Owned by me",
  rightsConfirmed: true,
});
const uploadUrl = new URL(intent.uploadUrl, base);
if (uploadUrl.origin !== new URL(base).origin) throw new Error("Unexpected upload origin");
const response = await fetch(uploadUrl, {
  method: "PUT",
  headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/octet-stream" },
  body: bytes,
});
const body = await response.json();
if (!response.ok || body.error) throw new Error(body.error?.code || `HTTP ${response.status}`);
console.log(body.result.id);

Submit once, then observe

Prepare model generation with generation_prepare, then pass its exact validated operation to job_submit. Keep preparedRequestId when present. Store a stable idempotencyKey before submission and reuse it only with the same input when retrying. A quoteId is optional in this runtime; quote_create can produce an estimate when requested. Request controls or selecting a model do not authorize a purchase. Honor the requested task and any explicit spending limit.

json
{ "type": "job", "id": "<job-id-returned-by-submission>" }

Job states and recovery

StateNext action
queued / runningPoll record_get with the same job ID. Back off between reads; do not submit again.
completedInspect outputs and retrieve the workspace result when applicable.
failedRead the error. job_resume is only for a known provider request eligible for recovery.
submission_unknownStop automatic resubmission and resolve the original provider request or settlement.
cancelledCheck the final task and billing records; upstream cancellation is not a refund guarantee.

Edit and deliver the result

Read workspace_snapshot before editing. Submit workspace_commit with projectId, the current baseRevisionId and a stable idempotencyKey. On REVISION_CONFLICT, read the snapshot again and reapply the intended edit. workspace_commit queues a local render; it does not buy new generated footage. Use workspace_result for progress and final delivery, including its workspace link. If the MCP host exposes workspace_export, use it to save the completed files again without rendering or generating. HTTP clients can refresh delivery links through workspace_result; workspace_export is a host-side MCP helper, not an HTTP tool endpoint.

This reference was last checked against rikoko 0.1.30 on October 21, 2026. The public installer has a separate version. Confirm exact schemas and model availability with your connected runtime.