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

# Confirm an upload, and start making the media's copies

> Checks the file's hash, its size and that it's the kind of file you said it was, then answers at once with the media `processing` while Patch makes its smaller copies (`levels`): a few seconds for a picture and, for a clip, about as long as it plays. It becomes `ready`, public and served as what its bytes say it is, once they're made, and shows on the project's page from then on, so there's no need to wait for it. If its copies can't be made, it becomes `failed` with why in `error`: complete it again to try again. If it isn't that kind of file, or can't be read at all, answers `media_invalid` and removes the media, since those bytes would never pass. If Patch can't start its copies, answers 503 `copies_unavailable` and the media is `failed`: complete it again.



## OpenAPI

````yaml /api-reference/openapi.json post /projects/{owner}/{slug}/media/{id}/complete
openapi: 3.1.0
info:
  title: Patch API
  version: 1.0.0
  description: >-
    The public API behind patch.gg, the desktop app and pch. Changes within v1
    are additive only. Errors are { error: { code, message, details } }; branch
    on code.
servers:
  - url: https://patch.gg/api/v1
security: []
paths:
  /projects/{owner}/{slug}/media/{id}/complete:
    post:
      tags:
        - Media
      summary: Confirm an upload, and start making the media's copies
      description: >-
        Checks the file's hash, its size and that it's the kind of file you said
        it was, then answers at once with the media `processing` while Patch
        makes its smaller copies (`levels`): a few seconds for a picture and,
        for a clip, about as long as it plays. It becomes `ready`, public and
        served as what its bytes say it is, once they're made, and shows on the
        project's page from then on, so there's no need to wait for it. If its
        copies can't be made, it becomes `failed` with why in `error`: complete
        it again to try again. If it isn't that kind of file, or can't be read
        at all, answers `media_invalid` and removes the media, since those bytes
        would never pass. If Patch can't start its copies, answers 503
        `copies_unavailable` and the media is `failed`: complete it again.
      parameters:
        - schema:
            type: string
            example: patch
          required: true
          name: owner
          in: path
        - schema:
            type: string
            example: demo-mod
          required: true
          name: slug
          in: path
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        '200':
          description: The media, making its copies or ready
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Media'
        '308':
          description: Renamed; follow the Location header
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not signed in
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Not allowed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearer: []
components:
  schemas:
    Media:
      type: object
      properties:
        id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - cover
            - screenshot
            - clip
            - tall_cover
            - hover_clip
          description: >-
            cover: the wide 16:9 key art every card shows (one). screenshot: up
            to 20. clip: up to 5, for the game page. tall_cover: the tall 2:3
            key art for where games stand as tall tiles (one). hover_clip: 4 to
            8 seconds of play, no UI, that cards fade into while pointed at
            (one, at most 20 MB). A new cover, tall cover or hover clip replaces
            the old once it's ready.
        status:
          type: string
          enum:
            - pending
            - processing
            - ready
            - failed
          description: >-
            pending until its upload is completed. processing while its smaller
            copies are made: a few seconds for a picture and, for a clip, about
            as long as it plays. ready once they and the file are public, which
            is when it shows. failed when they couldn't be made, with why in
            `error`: complete it again to try again. Only its managers see it
            before it's ready.
        url:
          type: string
          description: Where it's served from, once it's ready
        levels:
          $ref: '#/components/schemas/MediaLevels'
        content_type:
          type: string
        sha256:
          type: string
        size:
          type: integer
        width:
          type:
            - integer
            - 'null'
        height:
          type:
            - integer
            - 'null'
        alt:
          type:
            - string
            - 'null'
        error:
          type:
            - string
            - 'null'
          description: Why its copies couldn't be made, when it's failed
        position:
          type: integer
          description: Order among media of the same kind
        generated:
          type: boolean
          description: >-
            Made by an image model: a cover or tall cover that's key art built
            from the game's real frames
        job_id:
          type:
            - string
            - 'null'
          format: uuid
          description: The covers job whose take it is, when Patch's free covers made it
        created_at:
          type: string
      required:
        - id
        - kind
        - status
        - url
        - levels
        - content_type
        - sha256
        - size
        - width
        - height
        - alt
        - error
        - position
        - generated
        - job_id
        - created_at
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: version_exists
            message:
              type: string
            details: {}
          required:
            - code
            - message
      required:
        - error
    MediaLevels:
      type: array
      items:
        type: object
        properties:
          width:
            type: integer
          url:
            type: string
        required:
          - width
          - url
      description: >-
        Smaller copies of a picture (WebP) or a clip (MP4, H.264, without
        sound), smallest first, each at its own address that never changes. Show
        the smallest that's sharp where it goes. Empty for animated pictures,
        for flat art and short clips with no smaller copy, and for media from
        before Patch made copies until theirs are made: then use the file
        itself.
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: An API key (pch_...) or the token from pch login.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.