> ## Documentation Index
> Fetch the complete documentation index at: https://docs.viggle.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Upscale Video (2x)

> Upscale an existing video by a fixed 2x with FlashVSR.

Starts an asynchronous fixed-2x video upscale. Supply one source video, then poll [Get Video](/v1/api-reference/videos/get) with the returned `vsr_` ID until it is ready. There is no target-resolution field: a 480p input becomes approximately 1080p, and a 768p input approximately 2K.

<Note>
  The service measures the source duration and charges **1 credit (\$0.01) per second, rounded up**. A 4.2-second source costs 5 credits.
</Note>

## Request parameters

Send `multipart/form-data`.

| Parameter   | Type    | Required | Default | Description                                                                                                 |
| ----------- | ------- | :------: | ------- | ----------------------------------------------------------------------------------------------------------- |
| `video`     | file    |  One of  | —       | Source video upload. Maximum 100 MiB; duration 0.5–600 seconds; dimensions must be at least 64×64 and even. |
| `video_url` | string  |  One of  | —       | Publicly reachable source-video URL. Use instead of `video` and keep it accessible during ingestion.        |
| `watermark` | boolean |    No    | `false` | Whether to include the service watermark in the upscaled result.                                            |

Provide exactly one of `video` or `video_url`.

```bash cURL theme={null}
curl -X POST "https://apis.viggle.ai/v1/videos/super-resolution" \
  -H "Authorization: Bearer $VIGGLE_API_KEY" \
  -F "video=@input.mp4" \
  -F "watermark=false"
```

## Response

Returns `200 OK` with `{id, status, progress, created_at}`. The ID begins with `vsr_`; use it unchanged with `GET /v1/videos/{video_id}`. The completed Video has `stage=null`, `alpha_url=null`, and no `seed` field.


## OpenAPI

````yaml openapi.yaml POST /v1/videos/super-resolution
openapi: 3.0.3
info:
  title: Viggle API
  description: Generate AI-powered character animation videos
  version: 2.0.0
  contact:
    name: Viggle Support
    url: https://viggle.ai
servers:
  - url: https://apis.viggle.ai
    description: Production server
security:
  - bearerAuth: []
tags:
  - name: Renders
    description: Prepare inputs, create renders, observe progress, and retrieve results.
  - name: Credits
    description: Read the credit balance available to the calling principal.
  - name: Characters
    description: |
      Create, list, inspect, and delete reusable character assets. `type`
      selects whether creation also extracts a 3D vsplat; export its
      download URL separately once ready.
  - name: Motions
    description: |
      Create, list, inspect, and delete reusable motion assets, and import one
      from an official motion template. `type` selects whether creation also
      extracts or generates a 3D animation; export its download URL
      separately once ready.
  - name: Videos
    description: |
      Generate a MiniMax H3 text-to-video (`vid_` prefix) or a
      character-animation video from a character image and/or driving video
      (`anim_` prefix), and read the unified view over every video the
      caller owns — H3 generations, character-animation generations, and
      character+motion Renders (`render_` prefix) — merged into one
      resource.
paths:
  /v1/videos/super-resolution:
    post:
      tags:
        - Videos
      summary: Upscale a video by 2x
      description: >-
        Supply exactly one of `video` or `video_url`. The fixed-2x result is
        billed at 1 credit per source-video second, rounded up. Poll the
        returned `vsr_` ID with Get Video.
      operationId: createVideoSuperResolution
      parameters:
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/SourceChannel'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateVideoSuperResolutionForm'
      responses:
        '200':
          description: Video upscale accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoCreateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/V1Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    RequestId:
      name: X-Request-Id
      in: header
      required: false
      description: >-
        Optional caller-supplied correlation ID, up to 128 characters. The
        service returns the effective value in the response header for tracing
        and support.
      schema:
        type: string
        minLength: 1
        maxLength: 128
    SourceChannel:
      name: X-Viggle-Source
      in: header
      required: false
      description: >-
        Optional source-channel label, up to 128 characters, used to attribute
        traffic to an SDK, integration, product surface, or internal workflow.
      schema:
        type: string
        minLength: 1
        maxLength: 128
  schemas:
    CreateVideoSuperResolutionForm:
      description: Supply exactly one video source. The output scale is always 2x.
      type: object
      properties:
        video:
          type: string
          format: binary
          description: >-
            Video upload, up to 100 MiB and 0.5–600 seconds long. Use instead of
            `video_url`.
        video_url:
          type: string
          format: uri
          description: >-
            Publicly reachable video URL. Use instead of `video` and keep it
            accessible during ingestion.
        watermark:
          type: boolean
          default: false
          description: Whether the upscaled result should include the service watermark.
    VideoCreateResponse:
      description: |
        Acceptance acknowledgment for `POST /v1/videos`, shared by all five
        generation modes. This is a queued confirmation, not the final
        result — poll `GET /v1/videos/{video_id}` (or watch it via
        `GET /v1/videos`) until `status` reaches `ready`, then read
        `video_url` from that response.
      type: object
      additionalProperties: false
      required:
        - id
        - status
        - progress
        - created_at
      properties:
        id:
          type: string
          description: >-
            Public video ID — `vid_`-prefixed for the four H3 modes,
            `anim_`-prefixed for character-animation mode.
          minLength: 1
        status:
          description: Lifecycle state at acceptance time; always `queued`.
          allOf:
            - $ref: '#/components/schemas/ResourceStatus'
        progress:
          type: integer
          description: Always null on acceptance.
          nullable: true
          minimum: 0
          maximum: 100
        created_at:
          type: string
          description: ISO 8601 creation timestamp, second precision.
          nullable: true
          format: date-time
    ResourceStatus:
      description: |
        The public lifecycle shared by every asynchronous resource. It carries
        the same values as `RenderStatus`.
      type: string
      enum:
        - queued
        - processing
        - ready
        - failed
        - cancelled
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          description: >-
            Top-level draft-flow error payload containing the stable code,
            message, retry guidance, correlation ID, and error-specific details.
          allOf:
            - $ref: '#/components/schemas/ErrorBody'
    ErrorBody:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - retryable
        - request_id
        - details
        - remediation
      properties:
        code:
          description: Stable error category from the draft-based render error vocabulary.
          allOf:
            - $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: >-
            Human-readable explanation suitable for logs or presentation to a
            developer.
        retryable:
          type: boolean
          description: >-
            Whether retrying the operation without changing its semantic input
            may succeed.
        request_id:
          type: string
          description: >-
            Correlation identifier for tracing and support. Include it when
            reporting the failure.
        details:
          type: object
          description: Error-specific structured context; available keys depend on `code`.
          additionalProperties: true
        remediation:
          description: Suggested recovery action and optional retry delay.
          allOf:
            - $ref: '#/components/schemas/ErrorRemediation'
    ErrorCode:
      description: |
        The failure vocabulary of the draft-based render flow. The resource
        operations project the same vocabulary onto the lower_snake_case codes
        described by `ResourceError`.
      type: string
      enum:
        - UNAUTHENTICATED
        - INVALID_CREDENTIAL
        - FORBIDDEN
        - INVALID_REQUEST
        - INVALID_CHARACTER
        - INVALID_MOTION
        - UNSUPPORTED_MEDIA
        - CONTENT_POLICY_VIOLATION
        - UPLOAD_REQUIRED
        - UPLOAD_MISMATCH
        - UPLOAD_EXPIRED
        - DRAFT_NOT_FOUND
        - DRAFT_ALREADY_CONSUMED
        - RENDER_NOT_FOUND
        - RENDER_NOT_CANCELLABLE
        - CHARACTER_NOT_FOUND
        - MOTION_NOT_FOUND
        - MOTION_NOT_READY
        - MOTION_TEMPLATE_NOT_FOUND
        - AVATAR_NOT_FOUND
        - ANIMATION_NOT_FOUND
        - EXTRACTION_UNAVAILABLE
        - EXTRACTION_FAILED
        - IDEMPOTENCY_KEY_REUSED
        - INSUFFICIENT_CREDITS
        - RATE_LIMITED
        - SERVICE_BUSY
        - INTERNAL_ERROR
    ErrorRemediation:
      type: object
      additionalProperties: false
      required:
        - action
        - retry_after_ms
      properties:
        action:
          type: string
          description: >-
            Suggested machine-readable or human-readable next action, such as
            retrying later, uploading media again, or correcting input.
        retry_after_ms:
          type: integer
          description: >-
            Recommended delay in milliseconds before retrying; null when no
            timed retry is advised.
          nullable: true
          format: int64
          minimum: 0
  responses:
    BadRequest:
      description: Invalid request.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    V1Unauthorized:
      description: Missing, invalid, or expired credential.
      headers:
        WWW-Authenticate:
          schema:
            type: string
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    PaymentRequired:
      description: Insufficient credits.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: Credential does not grant access to this resource.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: Rate limit exceeded.
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 0
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Unexpected server error.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServiceUnavailable:
      description: Service temporarily unavailable.
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 0
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  headers:
    RequestId:
      description: Stable request identifier for support and tracing.
      schema:
        type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key or OAuth access token
      description: |
        Server-side SDK clients use a project API key. Remote MCP clients use
        an OAuth access token. Never expose a project API key in browser code.

````