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

# Generate Asset Upload Urls API Reference - Magic Hour Docs

> Generates a list of pre-signed upload URLs for the assets required. This API is only necessary if you want to upload to Magic Hour's storage. Refer to the [Input Files Guide](/integration/input-files) for more details.

The response array will match the order of items in the request body.

**Valid file extensions per asset type**:
- video: mp4, m4v, mov, webm
- audio: mp3, wav, aac, flac, webm, m4a
- image: png, jpg, jpeg, heic, heif, webp, avif, jp2, tiff, bmp
- gif: gif, webp, webm

> Note: `gif` is only supported for face swap API `video_file_path` field.

Once you receive an upload URL, send a `PUT` request to upload the file directly.

Example:

```
curl -X PUT --data '@/path/to/file/video.mp4' \
  https://videos.magichour.ai/api-assets/id/video.mp4?<auth params from the API response>
```




## OpenAPI

````yaml post /v1/files/upload-urls
openapi: 3.0.2
info:
  title: Magic Hour API
  version: beta
  description: >

    Magic Hour provides an API (beta) that can be integrated into your own
    application to generate videos and images using AI. 


    Webhook documentation can be found
    [here](https://magichour.ai/docs/webhook).


    If you have any questions, please reach out to us via
    [discord](https://discord.gg/JX5rgsZaJp).


    # Authentication


    Every request requires an API key.


    To get started, first generate your API key
    [here](https://magichour.ai/settings/developer).


    Then, add the `Authorization` header to the request.


    | Key | Value |

    |-|-|

    | Authorization | Bearer mhk_live_apikey |


    > **Warning**: any API call that renders a video will utilize credits in
    your account.
  termsOfService: https://magichour.ai/terms-of-service
servers:
  - url: https://api.magichour.ai
security: []
tags:
  - name: Files
    description: API related to uploading assets used for video generation
  - name: Image Projects
    description: API related to image projects
  - name: Video Projects
    description: API related to video projects
  - name: Audio Projects
    description: API related to audio projects
paths:
  /v1/files/upload-urls:
    post:
      tags:
        - Files
      summary: Generate asset upload urls
      description: >
        Generates a list of pre-signed upload URLs for the assets required. This
        API is only necessary if you want to upload to Magic Hour's storage.
        Refer to the [Input Files Guide](/integration/input-files) for more
        details.


        The response array will match the order of items in the request body.


        **Valid file extensions per asset type**:

        - video: mp4, m4v, mov, webm

        - audio: mp3, wav, aac, flac, webm, m4a

        - image: png, jpg, jpeg, heic, heif, webp, avif, jp2, tiff, bmp

        - gif: gif, webp, webm


        > Note: `gif` is only supported for face swap API `video_file_path`
        field.


        Once you receive an upload URL, send a `PUT` request to upload the file
        directly.


        Example:


        ```

        curl -X PUT --data '@/path/to/file/video.mp4' \
          https://videos.magichour.ai/api-assets/id/video.mp4?<auth params from the API response>
        ```
      operationId: videoAssets.generatePresignedUrl
      parameters: []
      requestBody:
        required: true
        description: Body
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  type: array
                  items:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - video
                          - audio
                          - image
                        description: >-
                          The type of asset to upload. Possible types are video,
                          audio, image
                        example: video
                      extension:
                        type: string
                        pattern: ^[a-z0-9]+$
                        description: >-
                          The extension of the file to upload. Do not include
                          the dot (.) before the extension. Possible extensions
                          are
                          mp4,m4v,mov,webm,mp3,wav,aac,flac,webm,m4a,png,jpg,jpeg,heic,heif,webp,avif,jp2,tiff,bmp,gif,webp,webm
                        example: mp4
                    required:
                      - type
                      - extension
                  minItems: 1
                  description: >-
                    The list of assets to upload. The response array will match
                    the order of items in the request body.
                  example:
                    - type: video
                      extension: mp4
                    - type: audio
                      extension: mp3
              required:
                - items
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        upload_url:
                          type: string
                          format: uri
                          description: >-
                            Used to upload the file to storage, send a PUT
                            request with the file as data to upload.
                          example: >-
                            https://videos.magichour.ai/id/video.mp4?auth-value=1234567890
                        expires_at:
                          type: string
                          format: date-time
                          description: >-
                            when the upload url expires, and will need to
                            request a new one.
                          example: '2024-07-21T17:32:28Z'
                        file_path:
                          type: string
                          description: >-
                            this value is used in APIs that needs assets, such
                            as image_file_path, video_file_path, and
                            audio_file_path
                          example: video/id/1234.mp4
                      required:
                        - upload_url
                        - expires_at
                        - file_path
                    description: >-
                      The list of upload URLs and file paths for the assets. The
                      response array will match the order of items in the
                      request body. Refer to the [Input Files
                      Guide](/integration/input-files) for more details.
                    example:
                      - upload_url: >-
                          https://videos.magichour.ai/api-assets/id/video.mp4?auth-value=1234567890
                        expires_at: '2024-07-25T16:56:21.932Z'
                        file_path: api-assets/id/video.mp4
                      - upload_url: >-
                          https://videos.magichour.ai/api-assets/id/audio.mp3?auth-value=1234567890
                        expires_at: '2024-07-25T16:56:21.932Z'
                        file_path: api-assets/id/audio.mp3
                required:
                  - items
                description: Success
        '400':
          description: Invalid Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                required:
                  - message
                description: The request is invalid
                example:
                  message: Missing request body
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    enum:
                      - Unauthorized
                required:
                  - message
                description: The request is not properly authenticated
                example:
                  message: Unauthorized
        '402':
          description: Payment Required
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                required:
                  - message
                description: The request requires payment
                example:
                  message: Payment required
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    enum:
                      - Not Found
                required:
                  - message
                description: Requested resource is not found
                example:
                  message: Not Found
        '422':
          description: Unprocessable Entity
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: >-
                      'mp4' is an invalid audio extension. Possible extensions
                      are 'mp3, wav, aac, flac, webm, m4a'
                required:
                  - message
                description: Unprocessable Entity
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: python
          source: |-
            from magic_hour import Client
            from os import getenv

            client = Client(token=getenv("API_TOKEN"))
            res = client.v1.files.upload_urls.create(
                items=[
                    {"extension": "mp4", "type_": "video"},
                    {"extension": "mp3", "type_": "audio"},
                ]
            )
        - lang: javascript
          source: |-
            import { Client } from "magic-hour";

            const client = new Client({ token: process.env["API_TOKEN"]!! });
            const res = await client.v1.files.uploadUrls.create({
              items: [
                { extension: "mp4", type: "video" },
                { extension: "mp3", type: "audio" },
              ],
            });
        - lang: go
          source: "package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tupload_urls \"github.com/magichourhq/magic-hour-go/resources/v1/files/upload_urls\"\n\ttypes \"github.com/magichourhq/magic-hour-go/types\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\tres, err := client.V1.Files.UploadUrls.Create(upload_urls.CreateRequest{\n\t\tItems: []types.V1FilesUploadUrlsCreateBodyItemsItem{\n\t\t\ttypes.V1FilesUploadUrlsCreateBodyItemsItem{\n\t\t\t\tExtension: \"mp4\",\n\t\t\t\tType:      types.V1FilesUploadUrlsCreateBodyItemsItemTypeEnumVideo,\n\t\t\t},\n\t\t\ttypes.V1FilesUploadUrlsCreateBodyItemsItem{\n\t\t\t\tExtension: \"mp3\",\n\t\t\t\tType:      types.V1FilesUploadUrlsCreateBodyItemsItemTypeEnumAudio,\n\t\t\t},\n\t\t},\n\t})\n}"
        - lang: rust
          source: |-
            let client = magic_hour::Client::default()
                .with_bearer_auth(&std::env::var("API_TOKEN").unwrap());
            let res = client
                .v1()
                .files()
                .upload_urls()
                .create(magic_hour::resources::v1::files::upload_urls::CreateRequest {
                    items: vec![
                        magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItem { extension :
                        "mp4".to_string(), type_ :
                        magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItemTypeEnum::Video
                        }, magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItem { extension :
                        "mp3".to_string(), type_ :
                        magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItemTypeEnum::Audio }
                    ],
                })
                .await;
        - lang: curl
          source: |-
            curl --request POST \
                 --url https://api.magichour.ai/v1/files/upload-urls \
                 --header 'accept: application/json' \
                 --header 'authorization: Bearer <token>' \
                 --header 'content-type: application/json' \
                 --data '
            {
              "items": [
                {
                  "type": "video",
                  "extension": "mp4"
                },
                {
                  "type": "audio",
                  "extension": "mp3"
                }
              ]
            }
            '
        - lang: php
          source: |-
            <?php

            $curl = curl_init();

            curl_setopt_array($curl, [
              CURLOPT_URL => "https://api.magichour.ai/v1/files/upload-urls",
              CURLOPT_RETURNTRANSFER => true,
              CURLOPT_ENCODING => "",
              CURLOPT_MAXREDIRS => 10,
              CURLOPT_TIMEOUT => 30,
              CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
              CURLOPT_CUSTOMREQUEST => "POST",
              CURLOPT_POSTFIELDS => json_encode([
                'items' => [
                    [
                            'type' => 'video',
                            'extension' => 'mp4'
                    ],
                    [
                            'type' => 'audio',
                            'extension' => 'mp3'
                    ]
                ]
              ]),
              CURLOPT_HTTPHEADER => [
                "accept: application/json",
                "authorization: Bearer <token>",
                "content-type: application/json"
              ],
            ]);

            $response = curl_exec($curl);
            $err = curl_error($curl);

            curl_close($curl);

            if ($err) {
              echo "cURL Error #:" . $err;
            } else {
              echo $response;
            }
        - lang: java
          source: >-
            HttpResponse<String> response =
            Unirest.post("https://api.magichour.ai/v1/files/upload-urls")
              .header("accept", "application/json")
              .header("content-type", "application/json")
              .header("authorization", "Bearer <token>")
              .body("{\"items\":[{\"type\":\"video\",\"extension\":\"mp4\"},{\"type\":\"audio\",\"extension\":\"mp3\"}]}")
              .asString();
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer authentication header of the form `Bearer <api_key>`, where
        `<api_key>` is your API key. To get your API key, go to [Developer
        Hub](https://magichour.ai/developer?tab=api-keys) and click "Create new
        API Key".

````