ViewMax Studio Generation API

Create credit-consuming generation tasks.

Operations 5

POST /api/v1/videos Create a video generation task #
POST /api/v1/images Create an image generation task #
POST /api/v1/music Create a music generation task #
POST /api/v1/speech Convert text to speech #
POST /api/v1/sound-effects Create a sound effect #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/viewmax-studio:viewmax-studio-generation-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

viewmax-studio-generation-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ViewMax Studio Generation API
  summary: Public REST API for ViewMax Studio media generation.
  description: 'Create video, image, music, speech, and sound-effect tasks with a ViewMax API key, then poll GET /api/v1/tasks/{taskId} every 5–10 seconds until `success`, `failed`, or `canceled`.


    GET /api/v1/models and GET /api/v1/voices are public. Every other endpoint needs `Authorization: Bearer sk-...`; keys have full access to the account and REST does not check scopes. OAuth applies to the MCP server only.


    Credits are deducted when a task is created; `failed` and `canceled` tasks are refunded automatically. Send an `Idempotency-Key` header so a retried POST returns the original task instead of charging again.


    `/api/v1` sends no CORS headers: call it from a server.'
  version: 1.1.0
  contact:
    name: ViewMax Studio
    email: support@viewmax.studio
    url: https://viewmax.studio/developers
  license:
    name: ViewMax API terms
    url: https://viewmax.studio/terms-of-service
servers:
- url: https://viewmax.studio
  description: ViewMax Studio production
security:
- bearerAuth: []
tags:
- name: Generation
  description: Create credit-consuming generation tasks.
paths:
  /api/v1/videos:
    post:
      operationId: createVideoTask
      tags:
      - Generation
      summary: Create a video generation task
      description: Validates the request, charges credits, and submits the job before responding; the video renders asynchronously. Poll GET /api/v1/tasks/{taskId}. Omitted duration, resolution and aspect_ratio take `modes..defaults` from GET /api/v1/models before pricing.
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVideoRequest'
      responses:
        '200':
          $ref: '#/components/responses/Task'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ContentSafetyUnavailable'
  /api/v1/images:
    post:
      operationId: createImageTask
      tags:
      - Generation
      summary: Create an image generation task
      description: 'Validates the request, charges credits, and submits the job before responding; most models render asynchronously. Poll GET /api/v1/tasks/{taskId}. On Pro and Ultra, flagship image models can be covered by the daily plan allowance (`costCredits: 0`).'
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateImageRequest'
      responses:
        '200':
          $ref: '#/components/responses/Task'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ContentSafetyUnavailable'
  /api/v1/music:
    post:
      operationId: createMusicTask
      tags:
      - Generation
      summary: Create a music generation task
      description: 'Renders synchronously: the response usually already has `status: "success"` and the track in `taskUrls`. Costs `max(60, ceil(duration_seconds))` credits (default 60 s).'
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMusicRequest'
      responses:
        '200':
          $ref: '#/components/responses/Task'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ContentSafetyUnavailable'
  /api/v1/speech:
    post:
      operationId: createSpeechTask
      tags:
      - Generation
      summary: Convert text to speech
      description: Renders synchronously with a `voice_id` from GET /api/v1/voices. Costs `max(1, ceil(characters / 20))` credits.
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSpeechRequest'
      responses:
        '200':
          $ref: '#/components/responses/Task'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/sound-effects:
    post:
      operationId: createSoundEffectTask
      tags:
      - Generation
      summary: Create a sound effect
      description: Renders synchronously from a text prompt. Costs 5 credits.
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSoundEffectRequest'
      responses:
        '200':
          $ref: '#/components/responses/Task'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ContentSafetyUnavailable'
components:
  responses:
    Task:
      description: Task created, or the existing task for a repeated `Idempotency-Key`.
      content:
        application/json:
          schema:
            type: object
            required:
            - code
            - message
            - data
            properties:
              code:
                type: integer
                enum:
                - 0
              message:
                type: string
                enum:
                - ok
              data:
                $ref: '#/components/schemas/Task'
    Unauthorized:
      description: 'Missing or invalid API key (`code: -1001`).'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: 'Provider or server failure. With `error.task_id` the task failed and was refunded: retry once. When the hint says the outcome is unknown, the task stays `pending` with the charge kept: poll it instead of retrying.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    BadRequest:
      description: '`invalid_request`: fix the request using `message` before retrying (includes disabled or offline models). `content_rejected`: change the prompt or media. When the provider rejected an accepted task, `error.task_id` is set and the task is failed and refunded.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ContentSafetyUnavailable:
      description: External content-safety check temporarily unavailable. Retry after a short delay.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InsufficientCredits:
      description: 'Balance below the task cost (`code: -1002`). No task was created; do not retry until credits are added.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    CreateImageRequest:
      type: object
      required:
      - model
      - prompt
      properties:
        model:
          type: string
          description: Model id from GET /api/v1/models?type=image.
        prompt:
          type: string
          minLength: 1
        scene:
          type: string
          enum:
          - text-to-image
          - image-to-image
          description: 'Default: `image-to-image` when `image_urls` is non-empty, else `text-to-image`.'
        image_urls:
          type: array
          items:
            type: string
            pattern: ^https?://
          description: Required (at least one) for `image-to-image`. ViewMax sets no count limit; the model provider may.
        options:
          type: object
          additionalProperties: true
          properties:
            aspect_ratio:
              type: string
            quality:
              type: string
              description: One of the scene's `qualities`, e.g. `1K`/`2K`/`4K`, `Basic`/`High`, or `Low`/`Medium`/`High`/`XHigh`/`Max` (GPT Image 2.5).
            resolution:
              type: string
              enum:
              - 1K
              - 2K
              - 4K
              description: GPT Image 2.5 (default `1K`). Other models read it as `quality` when `quality` is omitted.
            size:
              type: string
              pattern: ^[0-9]+x[0-9]+$
              description: 'GPT Image 2.5 exact pixels, e.g. `1536x1024`: multiples of 16, longest side ≤ 3840, ratio ≤ 3:1, 655,360–8,294,400 pixels. Overrides `aspect_ratio` and `resolution`.'
    Task:
      type: object
      description: Generation task. Returned by every create endpoint and by GET /api/v1/tasks/{taskId}.
      required:
      - id
      - status
      - mediaType
      - costCredits
      - taskUrls
      properties:
        id:
          type: string
          description: Task id. Poll GET /api/v1/tasks/{taskId} with it.
        status:
          type: string
          enum:
          - pending
          - processing
          - success
          - failed
          - canceled
          description: '`pending`/`processing`: keep polling. `success`: read `taskUrls`. `failed`/`canceled`: terminal, credits refunded.'
        mediaType:
          type: string
          enum:
          - video
          - image
          - music
          - audio
        scene:
          type: string
          description: Mode or scene, e.g. `text-to-video`, `text-to-image`, `text-to-music`, `text-to-speech`, `text-to-sound-effects`.
        model:
          type: string
          description: Model identifier used for the job. May differ from the catalog id sent in the request.
        prompt:
          type: string
        options:
          type:
          - string
          - 'null'
          description: JSON-encoded options as priced and submitted, including filled-in defaults and `mode` for video.
        taskUrls:
          type: array
          items:
            type: string
            format: uri
          description: Result URLs. Empty until the task succeeds.
        costCredits:
          type: integer
          description: Credits charged. `0` when a plan allowance covered it.
        waivedCredits:
          type: integer
          description: Normal price waived by a plan allowance; otherwise `0`.
        fairUseKey:
          type:
          - string
          - 'null'
          description: Plan allowance slot used by this task, or `null`.
        taskInfo:
          type:
          - string
          - 'null'
          description: JSON string. While pending/processing/success it holds job diagnostics whose shape is not stable. On `failed`/`canceled` it is `{"errorCode","error","errorMessage"}`; `errorCode` is one of `insufficient_credits`, `auth_required`, `rate_limited`, `request_cancelled`, `provider_unavailable`, `invalid_input`, `content_rejected`, `busy`, `duplicate_request`, `generic`. `errorMessage` carries the provider's reason only for `invalid_input`.
        taskResult:
          type:
          - string
          - 'null'
          description: JSON string. Same failure payload as `taskInfo` on `failed`/`canceled`; otherwise job diagnostics with no stable shape.
        taskId:
          type:
          - string
          - 'null'
          description: Upstream job id (diagnostic only).
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        userId:
          type: string
        creditId:
          type:
          - string
          - 'null'
        visibility:
          type: string
        deletedAt:
          type:
          - string
          - 'null'
          format: date-time
    CreateMusicRequest:
      type: object
      required:
      - prompt
      properties:
        prompt:
          type: string
          minLength: 1
          description: Track description. When `options.style` or `options.title` is set, the prompt is treated as lyrics.
        options:
          type: object
          additionalProperties: true
          description: '`options.duration` and `options.music_length_ms` are rejected (400); use `duration_seconds`.'
          properties:
            duration_seconds:
              type: number
              minimum: 3
              maximum: 300
              default: 60
              description: 'JSON number. Cost: `max(60, ceil(duration_seconds))` credits.'
            instrumental:
              type: boolean
              description: '`true` for no vocals.'
            style:
              type: string
              description: Genre or mood. Makes the prompt be treated as lyrics; do not also send `lyrics`.
            title:
              type: string
              description: Song title. Also makes the prompt be treated as lyrics.
            lyrics:
              type: string
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
      - code
      - message
      - error
      properties:
        code:
          type: integer
          description: '`-1` for most errors, `-1001` unauthorized, `-1002` insufficient credits.'
        message:
          type: string
        error:
          type: object
          additionalProperties: false
          required:
          - type
          - hint
          - docs
          properties:
            type:
              type: string
              enum:
              - unauthorized
              - invalid_request
              - insufficient_credits
              - not_found
              - content_rejected
              - internal_error
            hint:
              type: string
              description: What to do next, including whether retrying the same request can help.
            docs:
              type: string
              format: uri
            task_id:
              type: string
              description: Present when the request created a task before failing. The task is `failed` and refunded, or still `pending` when the provider outcome is unknown (poll it instead of retrying).
    CreateVideoRequest:
      type: object
      required:
      - model
      - prompt
      properties:
        model:
          type: string
          description: 'Model id from GET /api/v1/models. Offline models return 400 `video model temporarily unavailable: <id>. ...`.'
        prompt:
          type: string
          minLength: 1
          description: 'Trimmed. At most the model''s `max_prompt_length` characters when the catalog lists one (`minimax-h3`: 7000).'
        mode:
          type: string
          enum:
          - text-to-video
          - image-to-video
          - video-to-video
          - frames-to-video
          - reference-to-video
          description: 'Must be a key of the model''s `modes`. Default: `image-to-video` when `image_urls` is non-empty, else `video-to-video` when `video_urls` is non-empty, else `text-to-video`.'
        image_urls:
          type: array
          items:
            type: string
            pattern: ^https?://
          description: 'http(s) URLs the provider can fetch without authentication. image-to-video: 1 (some models 2); frames-to-video: 2 (start, end); reference-to-video: 1 or more. Per-model maximums are in the docs.'
        video_urls:
          type: array
          maxItems: 1
          items:
            type: string
            pattern: ^https?://
          description: One source video. Required for `video-to-video`; optional for `reference-to-video` on Seedance 2.0, 2.0 Fast, 2 Mini and MiniMax H3.
        options:
          $ref: '#/components/schemas/VideoOptions'
    CreateSoundEffectRequest:
      type: object
      required:
      - prompt
      properties:
        prompt:
          type: string
          minLength: 1
        options:
          type: object
          additionalProperties: true
          description: JSON numbers; out-of-range values return 400 `options.<key> must be a number from <min> to <max>`.
          properties:
            duration_seconds:
              type: number
              minimum: 0.5
              maximum: 22
            prompt_influence:
              type: number
              minimum: 0
              maximum: 1
    VideoOptions:
      type: object
      additionalProperties: true
      description: Values must come from the model's `modes.<mode>` in GET /api/v1/models. Omitted `duration`, `resolution` and `aspect_ratio` take `modes.<mode>.defaults` before pricing. Other keys are forwarded unvalidated.
      properties:
        duration:
          oneOf:
          - type: string
            pattern: ^[0-9]+[sS]?$
          - type: integer
            minimum: 1
          description: '`"8s"`, `"8"` and `8` are equivalent.'
        resolution:
          type: string
          description: Case-insensitive; send the catalog spelling, e.g. `720p`, `4k`, `768P`, `2K`.
        aspect_ratio:
          type: string
          description: Exact case, e.g. `16:9`, `Auto`.
        audio:
          type: boolean
          description: '`true` only when `audio_toggle` is true; `false` is always accepted.'
        source_video_duration_seconds:
          type: number
          exclusiveMinimum: 0
          description: Source video length. Required with `video_urls` when the mode lists `credits_per_second` (Seedance 2.x, Seedance 2.5, MiniMax H3).
    CreateSpeechRequest:
      type: object
      required:
      - text
      - voice_id
      properties:
        text:
          type: string
          minLength: 1
          description: 'Trimmed text to speak. Cost: `max(1, ceil(characters / 20))` credits.'
        voice_id:
          type: string
          description: Voice `id` from GET /api/v1/voices.
        options:
          type: object
          additionalProperties: true
          description: Out-of-range numbers are clamped, not rejected.
          properties:
            model_id:
              type: string
              description: 'Default: the voice''s `recommended_model`.'
            speed:
              type: number
              minimum: 0.25
              maximum: 4
            stability:
              type: number
              minimum: 0
              maximum: 1
            similarity_boost:
              type: number
              minimum: 0
              maximum: 1
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: Optional. 1–200 visible ASCII characters, no spaces (otherwise 400). A repeated key for the same account, on any create endpoint, returns the task the first request created with its original `costCredits` and charges nothing; the body is not compared. Without it, every request creates and charges a new task.
      schema:
        type: string
        minLength: 1
        maxLength: 200
        pattern: ^[\x21-\x7E]+$
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'ViewMax API key from Settings → API Keys (`sk-` followed by 32 letters and digits). Send `Authorization: Bearer sk-...`. Every key has full access to its account; REST does not check scopes and has no per-key rate limit.'
    oauth2:
      type: oauth2
      description: 'OAuth 2.0 for the ViewMax MCP server (`/api/mcp`) only. REST endpoints accept API keys, not OAuth tokens. Discovery: `/.well-known/oauth-protected-resource/api/mcp` and `/.well-known/oauth-authorization-server/api/auth`.'
      flows:
        authorizationCode:
          authorizationUrl: https://viewmax.studio/api/auth/oauth2/authorize
          tokenUrl: https://viewmax.studio/api/auth/oauth2/token
          refreshUrl: https://viewmax.studio/api/auth/oauth2/token
          scopes:
            models:read: Read the public model and voice catalogs without creating generation tasks.
            tasks:read: Read generation task status and output URLs for the authenticated account.
            tasks:write: Create credit-consuming video, image, music, speech, and sound-effect tasks.
            credits:read: Read the remaining credit balance for the authenticated account.
externalDocs:
  description: ViewMax API documentation
  url: https://viewmax.studio/docs/api
x-viewmax-mcp:
  url: https://viewmax.studio/api/mcp
  transport: streamable-http
  serverCard: https://viewmax.studio/server-card