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

# Animate a single image into a video

> Bring one image to life: fast, affordable, audio included. The output video is rendered at the reference image's aspect ratio. Returns a `video.generate` job; poll `GET /videos/{id}` (optionally `?wait=true`).



## OpenAPI

````yaml /openapi.json post /videos/image-to-video
openapi: 3.0.3
info:
  title: Dafty API
  version: v1
  description: >-
    Generate on-brand graphics from a simple, opinionated API. Authenticate with
    an API key via the `x-api-key` header (or `Authorization: Bearer`).
    Generation endpoints return `202` with a job; poll `GET /jobs/{id}`
    (optionally `?wait=true`) for the result.
servers:
  - url: https://app.dafty.ai/api/v1
    description: Base URL for all v1 endpoints.
security:
  - apiKey: []
  - bearerAuth: []
tags:
  - name: Account
    description: Who an API key belongs to.
  - name: Images
    description: Generate, edit, resize, and upscale images.
  - name: Videos
    description: >-
      Generate video: animate a single image, or transition between a start and
      end frame. One clip per request.
  - name: Jobs
    description: Poll, list, and cancel asynchronous jobs.
  - name: Styles
    description: Extract brand styles and search their assets.
  - name: Uploads
    description: Bring your own reference images via direct-to-storage upload.
paths:
  /videos/image-to-video:
    post:
      tags:
        - Videos
      summary: Animate a single image into a video
      description: >-
        Bring one image to life: fast, affordable, audio included. The output
        video is rendered at the reference image's aspect ratio. Returns a
        `video.generate` job; poll `GET /videos/{id}` (optionally `?wait=true`).
      operationId: generateImageToVideo
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Optional unique key (≤255 chars) that makes this create idempotent:
            a retry with the same key returns the original job rather than
            starting a new one. Scoped to your API key; retained ~24h.
          schema:
            type: string
            maxLength: 255
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoImageToVideo'
            example:
              image: 5c1e8b34-2a9f-4d61-8e07-3b2c1a0f9d4e
              prompt: Slow push-in as the logo shimmers, soft ambient hum
              duration: 6
              resolution: 720p
      responses:
        '202':
          description: Accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Job'
                required:
                  - data
              example:
                data:
                  id: 3f9a4c2e-7b1d-4e8a-9c3f-2a1b0c9d8e7f
                  type: image.generate
                  status: pending
                  createdAt: '2026-06-16T10:00:00.000Z'
        '400':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Too many requests. A per-key rate limit was hit; back off and retry.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Requests allowed in the current window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Seconds until the current window resets.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    VideoImageToVideo:
      type: object
      properties:
        image:
          type: string
          minLength: 1
          maxLength: 2048
          description: >-
            The reference image to animate; becomes the first frame and sets the
            output aspect ratio. An https URL we ingest or the id/url of one of
            your uploads or prior generations.
        prompt:
          type: string
          minLength: 1
          maxLength: 2000
          description: >-
            Describe the motion or what should happen in the clip. Up to 2000
            characters.
        duration:
          default: 6
          description: Clip length in seconds (1-15).
          type: integer
          minimum: 1
          maximum: 15
        resolution:
          default: 720p
          type: string
          enum:
            - 480p
            - 720p
          description: Output resolution. 720p costs more credits than 480p.
        audio:
          default: true
          description: Generate audio for the clip.
          type: boolean
        negativePrompt:
          description: Describe what to avoid in the generation.
          type: string
          maxLength: 1000
      required:
        - image
        - prompt
      additionalProperties: false
    Job:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
          enum:
            - image.generate
            - image.edit
            - image.resize
            - image.upscale
            - video.generate
            - style.extract
          description: Job kind, matching the endpoint that created it.
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
        result:
          type: object
          properties:
            images:
              description: >-
                Set for image jobs (generate / edit / resize / upscale). Plain
                output URLs.
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    description: >-
                      Id of this image. Pass as `imageId` to edit/resize/upscale
                      just this variation.
                  url:
                    type: string
                  width:
                    nullable: true
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                  height:
                    nullable: true
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                required:
                  - id
                  - url
                  - width
                  - height
                additionalProperties: false
            video:
              description: Set for video jobs (image-to-video / frames).
              type: object
              properties:
                id:
                  type: string
                  description: Id of this video (the job id).
                url:
                  type: string
                  description: Output video URL (mp4).
                durationSeconds:
                  nullable: true
                  description: Clip length in seconds.
                  type: integer
                  minimum: -9007199254740991
                  maximum: 9007199254740991
                thumbnailUrl:
                  nullable: true
                  description: >-
                    Poster image URL. May be null briefly until the thumbnail
                    finishes processing just after the video completes.
                  type: string
                width:
                  nullable: true
                  type: integer
                  minimum: -9007199254740991
                  maximum: 9007199254740991
                height:
                  nullable: true
                  type: integer
                  minimum: -9007199254740991
                  maximum: 9007199254740991
              required:
                - id
                - url
                - durationSeconds
                - thumbnailUrl
                - width
                - height
              additionalProperties: false
            style:
              description: 'Set for style.extract jobs: the id of the created style.'
              type: object
              properties:
                id:
                  type: string
              required:
                - id
              additionalProperties: false
          additionalProperties: false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - GENERATION_FAILED
                - EXTRACTION_FAILED
            message:
              type: string
          required:
            - code
            - message
          additionalProperties: false
      required:
        - id
        - type
        - status
        - createdAt
      additionalProperties: false
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Stable, machine-readable error code. Common values:
                `VALIDATION_ERROR` (400), `NOT_FOUND` (404),
                `INSUFFICIENT_CREDITS` / `SUBSCRIPTION_REQUIRED` (402),
                `RATE_LIMIT_ERROR` / `USAGE_LIMIT_EXCEEDED` /
                `CONCURRENT_LIMIT_REACHED` (429), `INTERNAL_ERROR` (500).
            message:
              type: string
            details:
              type: object
              additionalProperties: true
              nullable: true
              description: >-
                Present on validation errors: the offending fields and why they
                failed.
          required:
            - message
      required:
        - error
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
    bearerAuth:
      type: http
      scheme: bearer

````