{
  "blueprintId": "blueprint-25",
  "kind": "recipe",
  "evidenceClass": "fixture-run",
  "contentVersion": "pilot-83451f4f909909d3c25616ab",
  "title": "Resume a video API task: bounded polling and verified download",
  "description": "A downloadable Node.js 24 client that resumes an existing public API task, handles 429 and terminal states, and saves output with a checkpoint, size limit and SHA-256. Includes 24 executed localhost fixture scenarios.",
  "goal": "Recover a known public API task after a client restart, finish polling within a fixed budget, and save one verifiable local output without submitting another generation.",
  "preparation": [
    "Install Node.js 24 and download client.mjs plus run-fixture.mjs into the same directory.",
    "Choose an existing public API task ID and its owner’s API key; browser-generated tasks may be outside this endpoint’s scope.",
    "Set SEEDANCE_API_KEY only in the server-side process environment, then choose a controlled output directory.",
    "Verify the exact managed HTTPS media origin before allowing a delivery host different from minimaxh3.studio."
  ],
  "steps": [
    {
      "title": "Run the offline contract fixture",
      "body": "Execute node run-fixture.mjs first. Its server uses only 127.0.0.1 and synthetic MP4-prefix bytes. The recorded Node v24.14.0 run passed 24 scenarios; this tests client control flow, not generation or video playback."
    },
    {
      "title": "Resume the original task ID",
      "body": "Run node client.mjs --task YOUR_EXISTING_API_TASK_ID --out ./saved-video. The client uses only GET /api/v1/tasks/{id}; a restart never submits a new video-generation request. Checkpoint data excludes credentials, raw responses and delivery URLs."
    },
    {
      "title": "Handle the exact public statuses",
      "body": "Read the direct task object, without a data envelope. processing keeps polling; completed requires output.video_url; failed exits with the task error code. A missing or differently owned public API task returns 404 and stops."
    },
    {
      "title": "Keep retries within a finite budget",
      "body": "Normal polling waits five seconds. 429 and 503 respect a bounded Retry-After or exponential fallback; all requests share a ten-minute deadline and a 120-request limit. A timeout is a reason to inspect and resume the existing task, not to replace it."
    },
    {
      "title": "Download only from a verified origin",
      "body": "If required, add --media-origin https://YOUR_VERIFIED_MEDIA_HOST after checking the managed delivery origin. Download requests carry no API key and reject redirects, URL user information, unexpected hosts and non-MP4 Content-Type."
    },
    {
      "title": "Verify the local file and retain the checkpoint",
      "body": "Media is streamed through an exclusive temporary file with a 256 MiB default limit. The client checks its MP4 ftyp prefix and SHA-256, refuses overwrite, and records final bytes/hash. Re-running a completed checkpoint first verifies the saved file. A real video still needs separate playback and content review."
    }
  ],
  "acceptance": [
    "The fixture passes all 24 recorded scenarios, uses only localhost GET requests, and closes its server after completion.",
    "The original task ID survives restart; no POST or paid task submission is present in the client.",
    "Checkpoint files contain no API key, raw task response or signed delivery URL.",
    "The completed local copy matches its recorded byte count and SHA-256; partial media is removed after a rejected download.",
    "401/404, terminal failure, poll/deadline exhaustion, unapproved hosts, redirects, unsafe names/symlinks, oversize output and checksum mismatch stop without a replacement generation."
  ],
  "troubleshooting": [
    {
      "symptom": "A valid-looking task returns not_found.",
      "change": "Confirm it was created by the public API and belongs to the same API key owner. Do not assume browser tasks are queryable here or generate a replacement automatically."
    },
    {
      "symptom": "Polling reaches its deadline while the task is processing.",
      "change": "Keep the checkpoint, inspect service state, then rerun with the same task ID. Adjust --timeout-ms only within a finite operating budget."
    },
    {
      "symptom": "The result URL is blocked or the saved file fails validation.",
      "change": "Verify the actual managed media origin, expected size and MP4 format before modifying --media-origin or --max-bytes. Supply --sha256 only with an independently trusted hash."
    },
    {
      "symptom": "The task reports failed and a refund is expected.",
      "change": "Inspect the actual error, credits_refunded and billing_status separately. The local fixture does not verify live billing and the client neither submits another task nor executes a refund."
    }
  ],
  "ending": "The source-backed API contract and executed fixture establish how the client resumes, stops and saves bytes. Live credentials, provider completion, billing/refunds, video decoding and model quality remain untested; validate those with a known existing task before production integration.",
  "assetCaption": "Downloadable original Node.js client, 24-scenario localhost fixture, bilingual instructions and actual execution receipt. Synthetic bytes are not generated video.",
  "prompt": ""
}
