{"openapi":"3.0.2","paths":{"/v1/files/upload-urls":{"post":{"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.\n\nThe response array will match the order of items in the request body.\n\n**Valid file extensions per asset type**:\n- video: mp4, m4v, mov, webm\n- audio: mp3, wav, aac, flac, webm, m4a\n- image: png, jpg, jpeg, heic, webp, avif, jp2, tiff, bmp\n- gif: gif, webp, webm\n\n> Note: `gif` is only supported for face swap API `video_file_path` field.\n\nOnce you receive an upload URL, send a `PUT` request to upload the file directly.\n\nExample:\n\n```\ncurl -X PUT --data '@/path/to/file/video.mp4' \\\n  https://videos.magichour.ai/api-assets/id/video.mp4?<auth params from the API response>\n```\n","summary":"Generate asset upload urls","tags":["Files"],"parameters":[],"operationId":"videoAssets.generatePresignedUrl","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,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\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.files.upload_urls.create(\n    items=[\n        {\"extension\": \"mp4\", \"type_\": \"video\"},\n        {\"extension\": \"mp3\", \"type_\": \"audio\"},\n    ]\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.files.uploadUrls.create({\n  items: [\n    { extension: \"mp4\", type: \"video\" },\n    { extension: \"mp3\", type: \"audio\" },\n  ],\n});"},{"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()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .files()\n    .upload_urls()\n    .create(magic_hour::resources::v1::files::upload_urls::CreateRequest {\n        items: vec![\n            magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItem { extension :\n            \"mp4\".to_string(), type_ :\n            magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItemTypeEnum::Video\n            }, magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItem { extension :\n            \"mp3\".to_string(), type_ :\n            magic_hour::models::V1FilesUploadUrlsCreateBodyItemsItemTypeEnum::Audio }\n        ],\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/files/upload-urls \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"items\": [\n    {\n      \"type\": \"video\",\n      \"extension\": \"mp4\"\n    },\n    {\n      \"type\": \"audio\",\n      \"extension\": \"mp3\"\n    }\n  ]\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/files/upload-urls\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'items' => [\n        [\n                'type' => 'video',\n                'extension' => 'mp4'\n        ],\n        [\n                'type' => 'audio',\n                'extension' => 'mp3'\n        ]\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/files/upload-urls\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"items\\\":[{\\\"type\\\":\\\"video\\\",\\\"extension\\\":\\\"mp4\\\"},{\\\"type\\\":\\\"audio\\\",\\\"extension\\\":\\\"mp3\\\"}]}\")\n  .asString();"}]}},"/v1/face-detection/{id}":{"get":{"description":"Get the details of a face detection task. \n\nUse this API to get the list of faces detected in the image or video to use in the [face swap photo](https://docs.magichour.ai/api-reference/image-projects/face-swap-photo) or [face swap video](https://docs.magichour.ai/api-reference/video-projects/face-swap-video) API calls for multi-face swaps.","summary":"Get face detection details","tags":["Files"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"uuid-example"},"description":"The id of the task. This value is returned by the [face detection API](https://docs.magichour.ai/api-reference/files/face-detection#response-id)."}],"operationId":"faceDetection.getDetails","responses":{"200":{"description":"200","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The id of the task. This value is returned by the [face detection API](https://docs.magichour.ai/api-reference/files/face-detection#response-id).","example":"uuid-example"},"credits_charged":{"type":"integer","description":"The credits charged for the task.","example":0},"status":{"type":"string","enum":["queued","rendering","complete","error"],"description":"The status of the detection.","example":"complete"},"faces":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The path to the face image. This should be used in face swap photo/video API calls as `.assets.face_mappings.original_face`","example":"api-assets/id/0-0.png"},"url":{"type":"string","description":"The url to the face image. This is used to render the image in your applications.","example":"https://videos.magichour.ai/api-assets/id/0-0.png"}},"required":["path","url"]},"description":"The faces detected in the image or video. The list is populated as faces are detected.","example":[{"path":"api-assets/id/0-0.png","url":"https://videos.magichour.ai/api-assets/id/0-0.png"}]}},"required":["id","credits_charged","status","faces"]}}}},"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":"Unable to get face detection details"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.face_detection.get(id=\"uuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.faceDetection.get({ id: \"uuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tface_detection \"github.com/magichourhq/magic-hour-go/resources/v1/face_detection\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\tres, err := client.V1.FaceDetection.Get(face_detection.GetRequest{\n\t\tId: \"uuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .face_detection()\n    .get(magic_hour::resources::v1::face_detection::GetRequest {\n        id: \"uuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request GET \\\n     --url https://api.magichour.ai/v1/face-detection/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/face-detection/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"GET\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.get(\"https://api.magichour.ai/v1/face-detection/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]}},"/v1/face-detection":{"post":{"description":"Detect faces in an image or video. \n      \nUse this API to get the list of faces detected in the image or video to use in the [face swap photo](https://docs.magichour.ai/api-reference/image-projects/face-swap-photo) or [face swap video](https://docs.magichour.ai/api-reference/video-projects/face-swap-video) API calls for multi-face swaps.\n\nNote: Face detection is free to use for the near future. Pricing may change in the future.","summary":"Face Detection","tags":["Files"],"parameters":[],"operationId":"faceDetection.detectFaces","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"confidence_score":{"default":0.5,"type":"number","minimum":0,"maximum":1,"multipleOf":0.05,"description":"Confidence threshold for filtering detected faces. \n* Higher values (e.g., 0.9) include only faces detected with high certainty, reducing false positives. \n* Lower values (e.g., 0.3) include more faces, but may increase the chance of incorrect detections.","example":0.5},"assets":{"type":"object","properties":{"target_file_path":{"type":"string","description":"This is the image or video where the face will be detected. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["target_file_path"],"description":"Provide the assets for face detection"}},"required":["assets"]}}}},"responses":{"200":{"description":"200","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The id of the task. Use this value in the [get face detection details API](https://docs.magichour.ai/api-reference/files/get-face-detection-details) to get the details of the face detection task.","example":"uuid-example"},"credits_charged":{"type":"integer","description":"The credits charged for the task."}},"required":["id","credits_charged"]}}}},"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":"Unable to trigger face detection"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.face_detection.generate(\n    assets={\"target_file_path\": \"/path/to/1234.png\"}, confidence_score=0.5\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.faceDetection.generate(\n  {\n    assets: { targetFilePath: \"/path/to/1234.png\" },\n    confidenceScore: 0.5,\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n});"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tface_detection \"github.com/magichourhq/magic-hour-go/resources/v1/face_detection\"\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.FaceDetection.Create(face_detection.CreateRequest{\n\t\tAssets: types.V1FaceDetectionCreateBodyAssets{\n\t\t\tTargetFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tConfidenceScore: nullable.NewValue(0.5),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .face_detection()\n    .create(magic_hour::resources::v1::face_detection::CreateRequest {\n        assets: magic_hour::models::V1FaceDetectionCreateBodyAssets {\n            target_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        confidence_score: Some(0.5),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/face-detection \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"confidence_score\": 0.5,\n  \"assets\": {\n    \"target_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/face-detection\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'confidence_score' => 0.5,\n    'assets' => [\n        'target_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/face-detection\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"confidence_score\\\":0.5,\\\"assets\\\":{\\\"target_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/video-projects/{id}":{"get":{"description":"Check the progress of a video project. The `downloads` field is populated after a successful render.\n  \n**Statuses**\n- `queued` — waiting to start\n- `rendering` — in progress\n- `complete` — ready; see `downloads`\n- `error` — a failure occurred (see `error`)\n- `canceled` — user canceled\n- `draft` — not used","summary":"Get video details","tags":["Video Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the video project. This value is returned by all of the POST APIs that create a video."}],"operationId":"videoProjects.getDetails","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"name":{"type":"string","nullable":true,"description":"The name of the video.","example":"Example Name"},"status":{"type":"string","enum":["draft","queued","rendering","complete","error","canceled"],"description":"The status of the video.","example":"complete"},"type":{"type":"string","description":"The type of the video project. Possible values are ANIMATION, AUTO_SUBTITLE, VIDEO_TO_VIDEO, FACE_SWAP, TEXT_TO_VIDEO, IMAGE_TO_VIDEO, LIP_SYNC, TALKING_PHOTO, VIDEO_UPSCALER, EXTEND, AUDIO_TO_VIDEO, UGC_AD","example":"FACE_SWAP"},"created_at":{"type":"string","format":"date-time"},"width":{"type":"integer","description":"The width of the final output video. A value of -1 indicates the width can be ignored.","example":512},"height":{"type":"integer","description":"The height of the final output video. A value of -1 indicates the height can be ignored.","example":960},"enabled":{"type":"boolean","description":"Whether this resource is active. If false, it is deleted."},"start_seconds":{"type":"number","minimum":0,"description":"Start time of your clip (seconds). Must be ≥ 0.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"End time of your clip (seconds). Must be greater than start_seconds.","format":"float","example":15},"total_frame_cost":{"type":"integer","example":450,"deprecated":true,"description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes."},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450},"fps":{"type":"number","description":"Frame rate of the video. If the status is not 'complete', the frame rate is an estimate and will be adjusted when the video completes.","example":30},"error":{"type":"object","properties":{"message":{"type":"string","description":"Details on the reason why a failure happened.","example":"Please use an image with a detectable face"},"code":{"type":"string","example":"no_source_face","description":"An error code to indicate why a failure happened."}},"required":["message","code"],"nullable":true,"description":"In the case of an error, this object will contain the error encountered during video render","example":null},"downloads":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://videos.magichour.ai/id/output.mp4"},"expires_at":{"type":"string","format":"date-time","example":"2024-10-19T05:16:19.027Z"}},"required":["url","expires_at"],"description":"The download url and expiration date of the image project"}},"download":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://videos.magichour.ai/id/output.mp4"},"expires_at":{"type":"string","format":"date-time","example":"2024-10-19T05:16:19.027Z"}},"required":["url","expires_at"],"nullable":true,"description":"Deprecated: Please use `.downloads` instead. The download url and expiration date of the video project","deprecated":true}},"required":["id","name","status","type","created_at","width","height","enabled","start_seconds","end_seconds","total_frame_cost","credits_charged","fps","error","downloads","download"],"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"}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.video_projects.get(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.videoProjects.get({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tvideo_projects \"github.com/magichourhq/magic-hour-go/resources/v1/video_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\tres, err := client.V1.VideoProjects.Get(video_projects.GetRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .video_projects()\n    .get(magic_hour::resources::v1::video_projects::GetRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request GET \\\n     --url https://api.magichour.ai/v1/video-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/video-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"GET\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.get(\"https://api.magichour.ai/v1/video-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]},"delete":{"description":"Permanently delete the rendered video. This action is not reversible, please be sure before deleting.","summary":"Delete video","tags":["Video Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the video project. This value is returned by all of the POST APIs that create a video."}],"operationId":"videoProjects.delete","responses":{"204":{"description":"204"},"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"}},"required":["message"],"description":"When a request fails validations","example":{"message":"video is a template and cannot be deleted. Please reach out to our support team."}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.video_projects.delete(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.videoProjects.delete({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tvideo_projects \"github.com/magichourhq/magic-hour-go/resources/v1/video_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\terr := client.V1.VideoProjects.Delete(video_projects.DeleteRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .video_projects()\n    .delete(magic_hour::resources::v1::video_projects::DeleteRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request DELETE \\\n     --url https://api.magichour.ai/v1/video-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/video-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"DELETE\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.delete(\"https://api.magichour.ai/v1/video-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]}},"/v1/ai-talking-photo":{"post":{"description":"Create a talking photo from an image and audio or text input.","summary":"AI Talking Photo","tags":["Video Projects"],"parameters":[],"operationId":"aiTalkingPhoto.createTalkingPhoto","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Talking Photo image","default":"Talking Photo - dateTime"},"start_seconds":{"type":"number","minimum":0,"description":"The start time of the input audio in seconds. The maximum duration allowed is 60 seconds.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"The end time of the input audio in seconds. The maximum duration allowed is 60 seconds.","format":"float","example":15},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"The source image to animate. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"audio_file_path":{"type":"string","minLength":1,"description":"The audio file to sync with the image. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp3"}},"required":["image_file_path","audio_file_path"],"description":"Provide the assets for creating a talking photo"},"style":{"type":"object","properties":{"generation_mode":{"default":"realistic","type":"string","enum":["realistic","prompted","pro","standard","stable","expressive"],"description":"Controls overall motion style.\n* `realistic` - Maintains likeness well, high quality, and reliable.\n* `prompted` - Slightly lower likeness; allows option to prompt scene.\n\n**Deprecated values (maintained for backward compatibility):**\n* `pro` - Deprecated: use `realistic`\n* `standard` - Deprecated: use `prompted`\n* `stable` - Deprecated: use `realistic`\n* `expressive` - Deprecated: use `prompted`","example":"realistic"},"intensity":{"default":1.5,"type":"number","minimum":0.1,"maximum":2,"multipleOf":0.01,"description":"Note: this value is only applicable when generation_mode is `expressive`. The value can include up to 2 decimal places.\n* Lower values yield more stability but can suppress mouth movement.\n* Higher values increase motion and expressiveness, with a higher risk of distortion.","deprecated":true},"prompt":{"type":"string","description":"A text prompt to guide the generation. Only applicable when generation_mode is `prompted`.\nThis field is ignored for other modes."}},"description":"Attributes used to dictate the style of the output"},"max_resolution":{"type":"integer","description":"Constrains the larger dimension (height or width) of the output video. Allows you to set a lower resolution than your plan's maximum if desired. The value is capped by your plan's max resolution.","example":1024}},"required":["start_seconds","end_seconds","assets"],"description":"Provide the assets for creating a talking photo"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create talking photo"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_talking_photo.generate(\n    assets={\n        \"audio_file_path\": \"/path/to/1234.mp3\",\n        \"image_file_path\": \"/path/to/1234.png\",\n    },\n    end_seconds=15.0,\n    start_seconds=0.0,\n    name=\"Talking Photo image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiTalkingPhoto.generate(\n  {\n    assets: {\n      audioFilePath: \"/path/to/1234.mp3\",\n      imageFilePath: \"/path/to/1234.png\",\n    },\n    endSeconds: 15.0,\n    name: \"Talking Photo image\",\n    startSeconds: 0.0,\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_talking_photo \"github.com/magichourhq/magic-hour-go/resources/v1/ai_talking_photo\"\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.AiTalkingPhoto.Create(ai_talking_photo.CreateRequest{\n\t\tAssets: types.V1AiTalkingPhotoCreateBodyAssets{\n\t\t\tAudioFilePath: \"api-assets/id/1234.mp3\",\n\t\t\tImageFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tEndSeconds:    15.0,\n\t\tMaxResolution: nullable.NewValue(1024),\n\t\tName:          nullable.NewValue(\"My Talking Photo image\"),\n\t\tStartSeconds:  0.0,\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_talking_photo()\n    .create(magic_hour::resources::v1::ai_talking_photo::CreateRequest {\n        assets: magic_hour::models::V1AiTalkingPhotoCreateBodyAssets {\n            audio_file_path: \"api-assets/id/1234.mp3\".to_string(),\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        end_seconds: 15.0,\n        max_resolution: Some(1024),\n        name: Some(\"My Talking Photo image\".to_string()),\n        start_seconds: 0.0,\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-talking-photo \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Talking Photo image\",\n  \"start_seconds\": 0,\n  \"end_seconds\": 15,\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\",\n    \"audio_file_path\": \"api-assets/id/1234.mp3\"\n  },\n  \"style\": {\n    \"generation_mode\": \"realistic\",\n    \"prompt\": \"string\"\n  },\n  \"max_resolution\": 1024\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-talking-photo\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Talking Photo image',\n    'start_seconds' => 0,\n    'end_seconds' => 15,\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png',\n        'audio_file_path' => 'api-assets/id/1234.mp3'\n    ],\n    'style' => [\n        'generation_mode' => 'realistic',\n        'prompt' => 'string'\n    ],\n    'max_resolution' => 1024\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-talking-photo\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Talking Photo image\\\",\\\"start_seconds\\\":0,\\\"end_seconds\\\":15,\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"audio_file_path\\\":\\\"api-assets/id/1234.mp3\\\"},\\\"style\\\":{\\\"generation_mode\\\":\\\"realistic\\\",\\\"prompt\\\":\\\"string\\\"},\\\"max_resolution\\\":1024}\")\n  .asString();"}]}},"/v1/animation":{"post":{"description":"Create a Animation video. The estimated frame cost is calculated based on the `fps` and `end_seconds` input.","summary":"Animation","tags":["Video Projects"],"parameters":[],"operationId":"animation.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Animation video","default":"Animation - dateTime"},"fps":{"type":"number","minimum":1,"description":"The desire output video frame rate","example":12},"end_seconds":{"type":"number","minimum":0.1,"description":"This value determines the duration of the output video.","format":"float","example":15},"height":{"type":"integer","minimum":64,"description":"The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details","example":960},"width":{"type":"integer","minimum":64,"description":"The width of the final output video. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details","example":512},"style":{"type":"object","properties":{"art_style":{"type":"string","enum":["Custom","Painterly Illustration","Vibrant Matte Illustration","Traditional Watercolor","Cyberpunk","Ink and Watercolor Portrait","Intricate Abstract Lines Portrait","3D Render","Old School Comic","Bold Colored Illustration","Synthwave","Minimal Cold Futurism","Futuristic Anime","Cinematic Miyazaki","Studio Ghibli Film Still","Soft Delicate Matte Portrait","Cinematic Landscape","Landscape Painting","Photograph","Jackson Pollock","Cubist","Abstract Minimalist","Impressionism","Van Gogh","Woodcut","Oil Painting","Vintage Japanese Anime","Pixar","Cosmic","Pixel Art","Fantasy","Arcane","Sin City","Double Exposure","Painted Cityscape","90s Streets","Overgrown","Postapocalyptic","Spooky","Miniatures","Low Poly","Art Deco","Inkpunk","Dark Graphic Illustration","Dark Watercolor","Faded Illustration","Directed by AI"],"description":"The art style used to create the output video","example":"Painterly Illustration"},"art_style_custom":{"type":"string","description":"Describe custom art style. This field is required if `art_style` is `Custom`"},"camera_effect":{"type":"string","enum":["Simple Zoom Out","Simple Zoom In","Bounce Out","Spin Bounce","Rolling Bounces","Rise and Climb","Dramatic Zoom In","Dramatic Zoom Out","Sway Out","Boost Zoom In","Boost Zoom Out","Heartbeat","Bounce in Place","Earthquake Bounce","Slice Bounce","Bounce In And Out","Jump","Road Trip","Traverse","Rubber Band","Rodeo","Accelerate","Speed of Light","Drift Spin","Vertigo","Cog in the Machine","Quadrant","Tron","Pusher","Roll In","Hesitate In","Zoom In - Audio Sync","Pulse - Audio Sync","Aggressive Zoom In - Audio Sync","Roll In - Audio Sync","Zoom Out - Audio Sync","Aggressive Zoom Out - Audio Sync","Sway Out - Audio Sync","Bounce and Spin - Audio Sync","Zoom In and Spin - Audio Sync","Vertigo - Audio Sync","Bounce Out - Audio Sync","Earthquake Bounce - Audio Sync","Pusher - Audio Sync","Evolve - Audio Sync","Devolve - Audio Sync","Slideshow","Pan Left","Pan Right","Tilt Up","Tilt Down","Directed by AI"],"description":"The camera effect used to create the output video","example":"Simple Zoom In"},"prompt_type":{"type":"string","enum":["custom","use_lyrics","ai_choose"],"example":"custom","description":"\n* `custom` - Use your own prompt for the video.\n* `use_lyrics` - Use the lyrics of the audio to create the prompt. If this option is selected, then `assets.audio_source` must be `file` or `youtube`.\n* `ai_choose` - Let AI write the prompt. If this option is selected, then `assets.audio_source` must be `file` or `youtube`."},"prompt":{"type":"string","description":"The prompt used for the video. Prompt is required if `prompt_type` is `custom`. Otherwise this value is ignored","example":"Cyberpunk city"},"transition_speed":{"type":"integer","minimum":1,"maximum":10,"description":"Change determines how quickly the video's content changes across frames. \n* Higher = more rapid transitions.\n* Lower = more stable visual experience.","example":5}},"required":["art_style","camera_effect","prompt_type","transition_speed"],"description":"Defines the style of the output video"},"assets":{"type":"object","properties":{"audio_source":{"type":"string","enum":["none","file","youtube"],"description":"Optionally add an audio source if you'd like to incorporate audio into your video","example":"file"},"audio_file_path":{"type":"string","minLength":1,"description":"The path of the input audio. This field is required if `audio_source` is `file`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp3"},"youtube_url":{"type":"string","format":"uri","minLength":1,"description":"Using a youtube video as the input source. This field is required if `audio_source` is `youtube`"},"image_file_path":{"type":"string","minLength":1,"description":"An initial image to use a the first frame of the video. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["audio_source"],"description":"Provide the assets for animation."}},"required":["fps","end_seconds","height","width","style","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.animation.generate(\n    assets={\n        \"audio_file_path\": \"/path/to/1234.mp3\",\n        \"audio_source\": \"file\",\n        \"image_file_path\": \"/path/to/1234.png\",\n    },\n    end_seconds=15.0,\n    fps=12.0,\n    height=960,\n    style={\n        \"art_style\": \"Painterly Illustration\",\n        \"camera_effect\": \"Simple Zoom In\",\n        \"prompt\": \"Cyberpunk city\",\n        \"prompt_type\": \"custom\",\n        \"transition_speed\": 5,\n    },\n    width=512,\n    name=\"Animation video\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.animation.generate(\n  {\n    assets: {\n      audioFilePath: \"/path/to/1234.mp3\",\n      audioSource: \"file\",\n      imageFilePath: \"/path/to/1234.png\",\n    },\n    endSeconds: 15.0,\n    fps: 12.0,\n    height: 960,\n    name: \"Animation video\",\n    style: {\n      artStyle: \"Painterly Illustration\",\n      cameraEffect: \"Simple Zoom In\",\n      prompt: \"Cyberpunk city\",\n      promptType: \"custom\",\n      transitionSpeed: 5,\n    },\n    width: 512,\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tanimation \"github.com/magichourhq/magic-hour-go/resources/v1/animation\"\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.Animation.Create(animation.CreateRequest{\n\t\tAssets: types.V1AnimationCreateBodyAssets{\n\t\t\tAudioFilePath: nullable.NewValue(\"api-assets/id/1234.mp3\"),\n\t\t\tAudioSource:   types.V1AnimationCreateBodyAssetsAudioSourceEnumFile,\n\t\t\tImageFilePath: nullable.NewValue(\"api-assets/id/1234.png\"),\n\t\t},\n\t\tEndSeconds: 15.0,\n\t\tFps:        12.0,\n\t\tHeight:     960,\n\t\tName:       nullable.NewValue(\"My Animation video\"),\n\t\tStyle: types.V1AnimationCreateBodyStyle{\n\t\t\tArtStyle:        types.V1AnimationCreateBodyStyleArtStyleEnumPainterlyIllustration,\n\t\t\tCameraEffect:    types.V1AnimationCreateBodyStyleCameraEffectEnumSimpleZoomIn,\n\t\t\tPrompt:          nullable.NewValue(\"Cyberpunk city\"),\n\t\t\tPromptType:      types.V1AnimationCreateBodyStylePromptTypeEnumCustom,\n\t\t\tTransitionSpeed: 5,\n\t\t},\n\t\tWidth: 512,\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .animation()\n    .create(magic_hour::resources::v1::animation::CreateRequest {\n        assets: magic_hour::models::V1AnimationCreateBodyAssets {\n            audio_file_path: Some(\"api-assets/id/1234.mp3\".to_string()),\n            audio_source: magic_hour::models::V1AnimationCreateBodyAssetsAudioSourceEnum::File,\n            image_file_path: Some(\"api-assets/id/1234.png\".to_string()),\n            ..Default::default()\n        },\n        end_seconds: 15.0,\n        fps: 12.0,\n        height: 960,\n        name: Some(\"My Animation video\".to_string()),\n        style: magic_hour::models::V1AnimationCreateBodyStyle {\n            art_style: magic_hour::models::V1AnimationCreateBodyStyleArtStyleEnum::PainterlyIllustration,\n            camera_effect: magic_hour::models::V1AnimationCreateBodyStyleCameraEffectEnum::SimpleZoomIn,\n            prompt: Some(\"Cyberpunk city\".to_string()),\n            prompt_type: magic_hour::models::V1AnimationCreateBodyStylePromptTypeEnum::Custom,\n            transition_speed: 5,\n            ..Default::default()\n        },\n        width: 512,\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/animation \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Animation video\",\n  \"fps\": 12,\n  \"end_seconds\": 15,\n  \"height\": 960,\n  \"width\": 512,\n  \"style\": {\n    \"art_style\": \"Painterly Illustration\",\n    \"art_style_custom\": \"string\",\n    \"camera_effect\": \"Simple Zoom In\",\n    \"prompt_type\": \"custom\",\n    \"prompt\": \"Cyberpunk city\",\n    \"transition_speed\": 5\n  },\n  \"assets\": {\n    \"audio_source\": \"file\",\n    \"audio_file_path\": \"api-assets/id/1234.mp3\",\n    \"youtube_url\": \"string\",\n    \"image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/animation\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Animation video',\n    'fps' => 12,\n    'end_seconds' => 15,\n    'height' => 960,\n    'width' => 512,\n    'style' => [\n        'art_style' => 'Painterly Illustration',\n        'art_style_custom' => 'string',\n        'camera_effect' => 'Simple Zoom In',\n        'prompt_type' => 'custom',\n        'prompt' => 'Cyberpunk city',\n        'transition_speed' => 5\n    ],\n    'assets' => [\n        'audio_source' => 'file',\n        'audio_file_path' => 'api-assets/id/1234.mp3',\n        'youtube_url' => 'string',\n        'image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/animation\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Animation video\\\",\\\"fps\\\":12,\\\"end_seconds\\\":15,\\\"height\\\":960,\\\"width\\\":512,\\\"style\\\":{\\\"art_style\\\":\\\"Painterly Illustration\\\",\\\"art_style_custom\\\":\\\"string\\\",\\\"camera_effect\\\":\\\"Simple Zoom In\\\",\\\"prompt_type\\\":\\\"custom\\\",\\\"prompt\\\":\\\"Cyberpunk city\\\",\\\"transition_speed\\\":5},\\\"assets\\\":{\\\"audio_source\\\":\\\"file\\\",\\\"audio_file_path\\\":\\\"api-assets/id/1234.mp3\\\",\\\"youtube_url\\\":\\\"string\\\",\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/auto-subtitle-generator":{"post":{"description":"Automatically generate subtitles for your video in multiple languages.","summary":"Auto Subtitle Generator","tags":["Video Projects"],"parameters":[],"operationId":"autoSubtitleGenerator.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Auto Subtitle video","default":"Auto Subtitle - dateTime"},"start_seconds":{"type":"number","minimum":0,"description":"Start time of your clip (seconds). Must be ≥ 0.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"End time of your clip (seconds). Must be greater than start_seconds.","format":"float","example":15},"assets":{"type":"object","properties":{"video_file_path":{"type":"string","minLength":1,"description":"This is the video used to add subtitles. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp4"}},"required":["video_file_path"],"description":"Provide the assets for auto subtitle generator"},"style":{"type":"object","properties":{"template":{"type":"string","enum":["karaoke","cinematic","minimalist","highlight"],"description":"Preset subtitle templates. Please visit https://magichour.ai/create/auto-subtitle-generator to see the style of the existing templates."},"custom_config":{"type":"object","properties":{"font":{"type":"string","description":"Font name from Google Fonts. Not all fonts support all languages or character sets. \nWe recommend verifying language support and appearance directly on https://fonts.google.com before use.","example":"Noto Sans"},"font_size":{"type":"number","description":"Font size in pixels. If not provided, the font size is automatically calculated based on the video resolution.","example":24},"font_style":{"type":"string","description":"Font style (e.g., normal, italic, bold)","example":"normal"},"text_color":{"type":"string","description":"Primary text color in hex format","example":"#FFFFFF"},"highlighted_text_color":{"type":"string","description":"Color used to highlight the current spoken text","example":"#FFD700"},"stroke_color":{"type":"string","description":"Stroke (outline) color of the text","example":"#000000"},"stroke_width":{"type":"number","description":"Width of the text stroke in pixels. If `stroke_color` is provided, but `stroke_width` is not, the `stroke_width` will be calculated automatically based on the font size.","example":1},"vertical_position":{"type":"string","description":"Vertical alignment of the text (e.g., top, center, bottom)","example":"bottom"},"horizontal_position":{"type":"string","description":"Horizontal alignment of the text (e.g., left, center, right)","example":"center"}},"description":"Custom subtitle configuration."}},"description":"Style of the subtitle. At least one of `.style.template` or `.style.custom_config` must be provided. \n* If only `.style.template` is provided, default values for the template will be used.\n* If both are provided, the fields in `.style.custom_config` will be used to overwrite the fields in `.style.template`.\n* If only `.style.custom_config` is provided, then all fields in `.style.custom_config` will be used.\n\nTo use custom config only, the following `custom_config` params are required:\n* `.style.custom_config.font`\n* `.style.custom_config.text_color`\n* `.style.custom_config.vertical_position`\n* `.style.custom_config.horizontal_position`\n"}},"required":["start_seconds","end_seconds","assets","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.auto_subtitle_generator.generate(\n    assets={\"video_file_path\": \"/path/to/1234.mp4\"},\n    end_seconds=15.0,\n    start_seconds=0.0,\n    style={},\n    name=\"Auto Subtitle video\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.autoSubtitleGenerator.generate(\n  {\n    assets: { videoFilePath: \"/path/to/1234.mp4\" },\n    endSeconds: 15.0,\n    name: \"Auto Subtitle video\",\n    startSeconds: 0.0,\n    style: {},\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tauto_subtitle_generator \"github.com/magichourhq/magic-hour-go/resources/v1/auto_subtitle_generator\"\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.AutoSubtitleGenerator.Create(auto_subtitle_generator.CreateRequest{\n\t\tAssets: types.V1AutoSubtitleGeneratorCreateBodyAssets{\n\t\t\tVideoFilePath: \"api-assets/id/1234.mp4\",\n\t\t},\n\t\tEndSeconds:   15.0,\n\t\tName:         nullable.NewValue(\"My Auto Subtitle video\"),\n\t\tStartSeconds: 0.0,\n\t\tStyle:        types.V1AutoSubtitleGeneratorCreateBodyStyle{},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .auto_subtitle_generator()\n    .create(magic_hour::resources::v1::auto_subtitle_generator::CreateRequest {\n        assets: magic_hour::models::V1AutoSubtitleGeneratorCreateBodyAssets {\n            video_file_path: \"api-assets/id/1234.mp4\".to_string(),\n        },\n        end_seconds: 15.0,\n        name: Some(\"My Auto Subtitle video\".to_string()),\n        start_seconds: 0.0,\n        style: magic_hour::models::V1AutoSubtitleGeneratorCreateBodyStyle {\n            ..Default::default()\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/auto-subtitle-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Auto Subtitle video\",\n  \"start_seconds\": 0,\n  \"end_seconds\": 15,\n  \"assets\": {\n    \"video_file_path\": \"api-assets/id/1234.mp4\"\n  },\n  \"style\": {\n    \"template\": \"karaoke\",\n    \"custom_config\": {\n      \"font\": \"Noto Sans\",\n      \"font_size\": 24,\n      \"font_style\": \"normal\",\n      \"text_color\": \"#FFFFFF\",\n      \"highlighted_text_color\": \"#FFD700\",\n      \"stroke_color\": \"#000000\",\n      \"stroke_width\": 1,\n      \"vertical_position\": \"bottom\",\n      \"horizontal_position\": \"center\"\n    }\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/auto-subtitle-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Auto Subtitle video',\n    'start_seconds' => 0,\n    'end_seconds' => 15,\n    'assets' => [\n        'video_file_path' => 'api-assets/id/1234.mp4'\n    ],\n    'style' => [\n        'template' => 'karaoke',\n        'custom_config' => [\n                'font' => 'Noto Sans',\n                'font_size' => 24,\n                'font_style' => 'normal',\n                'text_color' => '#FFFFFF',\n                'highlighted_text_color' => '#FFD700',\n                'stroke_color' => '#000000',\n                'stroke_width' => 1,\n                'vertical_position' => 'bottom',\n                'horizontal_position' => 'center'\n        ]\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/auto-subtitle-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Auto Subtitle video\\\",\\\"start_seconds\\\":0,\\\"end_seconds\\\":15,\\\"assets\\\":{\\\"video_file_path\\\":\\\"api-assets/id/1234.mp4\\\"},\\\"style\\\":{\\\"template\\\":\\\"karaoke\\\",\\\"custom_config\\\":{\\\"font\\\":\\\"Noto Sans\\\",\\\"font_size\\\":24,\\\"font_style\\\":\\\"normal\\\",\\\"text_color\\\":\\\"#FFFFFF\\\",\\\"highlighted_text_color\\\":\\\"#FFD700\\\",\\\"stroke_color\\\":\\\"#000000\\\",\\\"stroke_width\\\":1,\\\"vertical_position\\\":\\\"bottom\\\",\\\"horizontal_position\\\":\\\"center\\\"}}}\")\n  .asString();"}]}},"/v1/face-swap":{"post":{"description":"**What this API does**\n\nCreate the same Face Swap you can make in the browser, but programmatically, so you can automate it, run it at scale, or connect it to your own app or workflow.\n    \n**Good for**\n- Automation and batch processing  \n- Adding face swap into apps, pipelines, or tools  \n\n**How it works (3 steps)**\n1) Upload your inputs (video, image, or audio) with [Generate Upload URLs](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls) and copy the `file_path`.  \n2) Send a request to create a face swap job with the basic fields.  \n3) Check the job status until it's `complete`, then download the result from `downloads`.\n\n**Key options**\n- Inputs: usually a file, sometimes a YouTube link, depending on project type  \n- Resolution: free users are limited to 576px; higher plans unlock HD and larger sizes  \n- Extra fields: e.g. `face_swap_mode`, `start_seconds`/`end_seconds`, or a text prompt  \n\n**Cost**  \nCredits are only charged for the frames that actually render. You'll see an estimate when the job is queued, and the final total after it's done.\n\nFor detailed examples, see the [product page](https://magichour.ai/products/face-swap).","summary":"Face Swap Video","tags":["Video Projects"],"parameters":[],"operationId":"faceSwap.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Face Swap video","default":"Face Swap - dateTime"},"height":{"nullable":true,"description":"`height` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"width":{"nullable":true,"description":"`width` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"start_seconds":{"type":"number","minimum":0,"description":"Start time of your clip (seconds). Must be ≥ 0.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"End time of your clip (seconds). Must be greater than start_seconds.","format":"float","example":15},"style":{"type":"object","properties":{"version":{"type":"string","enum":["v1","v2","default"],"example":"default","description":"* `v1` - May preserve skin detail and texture better, but weaker identity preservation.\n* `v2` - Faster, sharper, better handling of hair and glasses. stronger identity preservation.\n* `default` - Use the version we recommend, which will change over time. This is recommended unless you need a specific earlier version. This is the default behavior."}},"description":"Style of the face swap video.","example":{"version":"default"}},"assets":{"type":"object","properties":{"face_swap_mode":{"default":"all-faces","type":"string","enum":["all-faces","individual-faces"],"description":"Choose how to swap faces:\n**all-faces** (recommended) — swap all detected faces using one source image (`source_file_path` required)\n+- **individual-faces** — specify exact mappings using `face_mappings`","example":"all-faces"},"image_file_path":{"type":"string","description":"The path of the input image with the face to be swapped.  The value is required if `face_swap_mode` is `all-faces`.\n\nThis value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"image/id/1234.png"},"face_mappings":{"type":"array","items":{"type":"object","properties":{"original_face":{"type":"string","description":"The face detected from the image in `target_file_path`. The file name is in the format of `<face_frame>-<face_index>.png`. This value is corresponds to the response in the [face detection API](https://docs.magichour.ai/api-reference/files/get-face-detection-details).\n\n* The face_frame is the frame number of the face in the target image. For images, the frame number is always 0.\n* The face_index is the index of the face in the target image, starting from 0 going left to right.","example":"api-assets/id/0-0.png"},"new_face":{"type":"string","description":"The face image that will be used to replace the face in the `original_face`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["original_face","new_face"]},"maxItems":5,"description":"This is the array of face mappings used for multiple face swap. The value is required if `face_swap_mode` is `individual-faces`.","example":[{"original_face":"api-assets/id/0-0.png","new_face":"api-assets/id/1234.png"}]},"video_source":{"type":"string","enum":["file","youtube"],"description":"Choose your video source.","example":"file"},"video_file_path":{"type":"string","description":"Your video file. Required if `video_source` is `file`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp4"},"youtube_url":{"type":"string","format":"uri","description":"YouTube URL (required if `video_source` is `youtube`)."}},"required":["video_source"],"description":"Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used"}},"required":["start_seconds","end_seconds","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.face_swap.generate(\n    assets={\n        \"face_mappings\": [\n            {\n                \"new_face\": \"/path/to/1234.png\",\n                \"original_face\": \"api-assets/id/0-0.png\",\n            }\n        ],\n        \"face_swap_mode\": \"all-faces\",\n        \"image_file_path\": \"image/id/1234.png\",\n        \"video_file_path\": \"/path/to/1234.mp4\",\n        \"video_source\": \"file\",\n    },\n    end_seconds=15.0,\n    start_seconds=0.0,\n    name=\"Face Swap video\",\n    style={\"version\": \"default\"},\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.faceSwap.generate(\n  {\n    assets: {\n      faceMappings: [\n        {\n          newFace: \"api-assets/id/1234.png\",\n          originalFace: \"api-assets/id/0-0.png\",\n        },\n      ],\n      faceSwapMode: \"all-faces\",\n      imageFilePath: \"image/id/1234.png\",\n      videoFilePath: \"/path/to/1234.mp4\",\n      videoSource: \"file\",\n    },\n    endSeconds: 15.0,\n    name: \"Face Swap video\",\n    startSeconds: 0.0,\n    style: { version: \"default\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tface_swap \"github.com/magichourhq/magic-hour-go/resources/v1/face_swap\"\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.FaceSwap.Create(face_swap.CreateRequest{\n\t\tAssets: types.V1FaceSwapCreateBodyAssets{\n\t\t\tFaceMappings: nullable.NewValue([]types.V1FaceSwapCreateBodyAssetsFaceMappingsItem{\n\t\t\t\ttypes.V1FaceSwapCreateBodyAssetsFaceMappingsItem{\n\t\t\t\t\tNewFace:      \"api-assets/id/1234.png\",\n\t\t\t\t\tOriginalFace: \"api-assets/id/0-0.png\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tFaceSwapMode:  nullable.NewValue(types.V1FaceSwapCreateBodyAssetsFaceSwapModeEnumAllFaces),\n\t\t\tImageFilePath: nullable.NewValue(\"image/id/1234.png\"),\n\t\t\tVideoFilePath: nullable.NewValue(\"api-assets/id/1234.mp4\"),\n\t\t\tVideoSource:   types.V1FaceSwapCreateBodyAssetsVideoSourceEnumFile,\n\t\t},\n\t\tEndSeconds:   15.0,\n\t\tName:         nullable.NewValue(\"My Face Swap video\"),\n\t\tStartSeconds: 0.0,\n\t\tStyle: nullable.NewValue(types.V1FaceSwapCreateBodyStyle{\n\t\t\tVersion: nullable.NewValue(types.V1FaceSwapCreateBodyStyleVersionEnumDefault),\n\t\t}),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .face_swap()\n    .create(magic_hour::resources::v1::face_swap::CreateRequest {\n        assets: magic_hour::models::V1FaceSwapCreateBodyAssets {\n            face_mappings: Some(\n                vec![\n                    magic_hour::models::V1FaceSwapCreateBodyAssetsFaceMappingsItem {\n                    new_face : \"api-assets/id/1234.png\".to_string(), original_face :\n                    \"api-assets/id/0-0.png\".to_string() }\n                ],\n            ),\n            face_swap_mode: Some(\n                magic_hour::models::V1FaceSwapCreateBodyAssetsFaceSwapModeEnum::AllFaces,\n            ),\n            image_file_path: Some(\"image/id/1234.png\".to_string()),\n            video_file_path: Some(\"api-assets/id/1234.mp4\".to_string()),\n            video_source: magic_hour::models::V1FaceSwapCreateBodyAssetsVideoSourceEnum::File,\n            ..Default::default()\n        },\n        end_seconds: 15.0,\n        name: Some(\"My Face Swap video\".to_string()),\n        start_seconds: 0.0,\n        style: Some(magic_hour::models::V1FaceSwapCreateBodyStyle {\n            version: Some(\n                magic_hour::models::V1FaceSwapCreateBodyStyleVersionEnum::Default,\n            ),\n        }),\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/face-swap \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Face Swap video\",\n  \"start_seconds\": 0,\n  \"end_seconds\": 15,\n  \"style\": {\n    \"version\": \"default\"\n  },\n  \"assets\": {\n    \"face_swap_mode\": \"all-faces\",\n    \"image_file_path\": \"image/id/1234.png\",\n    \"face_mappings\": [\n      {\n        \"original_face\": \"api-assets/id/0-0.png\",\n        \"new_face\": \"api-assets/id/1234.png\"\n      }\n    ],\n    \"video_source\": \"file\",\n    \"video_file_path\": \"api-assets/id/1234.mp4\",\n    \"youtube_url\": \"string\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/face-swap\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Face Swap video',\n    'start_seconds' => 0,\n    'end_seconds' => 15,\n    'style' => [\n        'version' => 'default'\n    ],\n    'assets' => [\n        'face_swap_mode' => 'all-faces',\n        'image_file_path' => 'image/id/1234.png',\n        'face_mappings' => [\n                [\n                                'original_face' => 'api-assets/id/0-0.png',\n                                'new_face' => 'api-assets/id/1234.png'\n                ]\n        ],\n        'video_source' => 'file',\n        'video_file_path' => 'api-assets/id/1234.mp4',\n        'youtube_url' => 'string'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/face-swap\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Face Swap video\\\",\\\"start_seconds\\\":0,\\\"end_seconds\\\":15,\\\"style\\\":{\\\"version\\\":\\\"default\\\"},\\\"assets\\\":{\\\"face_swap_mode\\\":\\\"all-faces\\\",\\\"image_file_path\\\":\\\"image/id/1234.png\\\",\\\"face_mappings\\\":[{\\\"original_face\\\":\\\"api-assets/id/0-0.png\\\",\\\"new_face\\\":\\\"api-assets/id/1234.png\\\"}],\\\"video_source\\\":\\\"file\\\",\\\"video_file_path\\\":\\\"api-assets/id/1234.mp4\\\",\\\"youtube_url\\\":\\\"string\\\"}}\")\n  .asString();"}]}},"/v1/image-to-video":{"post":{"description":"**What this API does**\n\nCreate the same Image To Video you can make in the browser, but programmatically, so you can automate it, run it at scale, or connect it to your own app or workflow.\n    \n**Good for**\n- Automation and batch processing  \n- Adding image to video into apps, pipelines, or tools  \n\n**How it works (3 steps)**\n1) Upload your inputs (video, image, or audio) with [Generate Upload URLs](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls) and copy the `file_path`.  \n2) Send a request to create a image to video job with the basic fields.  \n3) Check the job status until it's `complete`, then download the result from `downloads`.\n\n**Key options**\n- Inputs: usually a file, sometimes a YouTube link, depending on project type  \n- Resolution: free users are limited to 576px; higher plans unlock HD and larger sizes  \n- Extra fields: e.g. `face_swap_mode`, `start_seconds`/`end_seconds`, or a text prompt  \n\n**Cost**  \nCredits are only charged for the frames that actually render. You'll see an estimate when the job is queued, and the final total after it's done.\n\nFor detailed examples, see the [product page](https://magichour.ai/products/image-to-video).","summary":"Image-to-Video","tags":["Video Projects"],"parameters":[],"operationId":"imageToVideo.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Image To Video video","default":"Image To Video - dateTime"},"end_seconds":{"type":"number","minimum":1,"maximum":60,"description":"The total duration of the output video in seconds. Supported durations depend on the chosen model:\n\n* **`ltx-2`**: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30\n* **`wan-2.2`**: 3, 4, 5, 6, 7, 8, 9, 10, 15\n* **`seedance`**: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12\n* **`seedance-2.0`**: 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n* **`kling-2.5`**: 5, 10\n* **`kling-3.0`**: 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n* **`sora-2`**: 4, 8, 12, 24, 36, 48, 60\n* **`veo3.1`**: 4, 6, 8, 16, 24, 32, 40, 48, 56\n* **`veo3.1-lite`**: 8, 16, 24, 32, 40, 48, 56\n\nLegacy models:\n* **`kling-1.6`**: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60","format":"float","example":5},"height":{"nullable":true,"description":"`height` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"width":{"nullable":true,"description":"`width` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"model":{"default":"default","type":"string","enum":["default","ltx-2","wan-2.2","seedance","seedance-2.0","kling-2.5","kling-3.0","veo3.1","veo3.1-lite","sora-2","kling-1.6","kling-2.5-audio","veo3.1-audio"],"description":"The AI model to use for video generation.\n\n* `default`: uses our currently recommended model for general use. For paid tiers, defaults to `kling-3.0`. For free tiers, it defaults to `ltx-2`.\n* `ltx-2`: Fast iteration with audio and lip-sync\n* `wan-2.2`: Fast, strong visuals with effects\n* `seedance`: Fast iteration and start/end frames\n* `seedance-2.0`: State-of-the-art quality and consistency\n* `kling-2.5`: Motion, action, and camera control\n* `kling-3.0`: Cinematic, multi-scene storytelling\n* `sora-2`: Story-first concepts and creativity\n* `veo3.1`: Realistic visuals and prompt adherence\n* `veo3.1-lite`: Good for fast, affordable, high-quality daily generation.\n\nLegacy models:\n* `kling-1.6`: Reliable baseline with smooth motion\n\nIf you specify the deprecated model value that includes the `-audio` suffix, this will be the same as included `audio` as `true`.","example":"kling-3.0"},"resolution":{"type":"string","enum":["480p","720p","1080p"],"example":"720p","description":"Controls the output video resolution. Defaults to `720p` on paid tiers and `480p` on free tiers.\n\n* **`ltx-2`**: Supports 480p, 720p, 1080p.\n* **`wan-2.2`**: Supports 480p, 720p, 1080p.\n* **`seedance`**: Supports 480p, 720p, 1080p.\n* **`seedance-2.0`**: Supports 480p, 720p.\n* **`kling-2.5`**: Supports 720p, 1080p.\n* **`kling-3.0`**: Supports 720p, 1080p.\n* **`sora-2`**: Supports 720p.\n* **`veo3.1`**: Supports 720p, 1080p.\n* **`veo3.1-lite`**: Supports 720p, 1080p.\n\nLegacy models:\n* **`kling-1.6`**: Supports 720p, 1080p."},"audio":{"type":"boolean","description":"Whether to include audio in the video. Defaults to `false` if not specified.\n\nAudio support varies by model:\n* **`ltx-2`**: Toggle-able: no additional credits for audio\n* **`wan-2.2`**: Not supported\n* **`seedance`**: Not supported\n* **`seedance-2.0`**: Toggle-able: no additional credits for audio\n* **`kling-2.5`**: Toggle-able: no additional credits for audio\n* **`kling-3.0`**: Toggle-able: audio adds extra credits when enabled\n* **`sora-2`**: Toggle-able: no additional credits for audio\n* **`veo3.1`**: Toggle-able: audio adds extra credits when enabled\n* **`veo3.1-lite`**: Toggle-able: audio adds extra credits when enabled\n\nLegacy models:\n* **`kling-1.6`**: Not supported","example":true},"style":{"type":"object","properties":{"prompt":{"type":"string","example":"a dog running","description":"The prompt used for the video."},"high_quality":{"type":"boolean","description":"Deprecated: Please use `resolution` instead. For backward compatibility, \n* `false` maps to 720p resolution\n* `true` maps to 1080p resolution\n\nThis field will be removed in a future version. Use the `resolution` field to directly specify the resolution.","deprecated":true},"quality_mode":{"type":"string","enum":["quick","studio"],"deprecated":true,"description":"DEPRECATED: Please use `resolution` field instead. For backward compatibility:\n* `quick` maps to 720p resolution\n* `studio` maps to 1080p resolution\n\nThis field will be removed in a future version. Use the `resolution` field to directly to specify the resolution."}},"description":"Attributed used to dictate the style of the output"},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"The path of the image file. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"end_image_file_path":{"type":"string","minLength":1,"description":"The image to use as the last frame of the video.\n\n* **`ltx-2`**: Not supported\n* **`wan-2.2`**: Not supported\n* **`seedance`**: Supports 480p, 720p, 1080p.\n* **`seedance-2.0`**: Supports 480p, 720p.\n* **`kling-2.5`**: Supports 1080p.\n* **`kling-3.0`**: Supports 1080p.\n* **`sora-2`**: Not supported\n* **`veo3.1`**: Not supported\n* **`veo3.1-lite`**: Not supported\n\nLegacy models:\n* **`kling-1.6`**: Not supported","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for image-to-video. Sora 2 only supports images with an aspect ratio of `9:16` or `16:9`."}},"required":["end_seconds","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.image_to_video.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"},\n    end_seconds=5.0,\n    name=\"Image To Video video\",\n    resolution=\"720p\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.imageToVideo.generate(\n  {\n    assets: { imageFilePath: \"/path/to/1234.png\" },\n    endSeconds: 5.0,\n    name: \"Image To Video video\",\n    resolution: \"720p\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\timage_to_video \"github.com/magichourhq/magic-hour-go/resources/v1/image_to_video\"\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.ImageToVideo.Create(image_to_video.CreateRequest{\n\t\tAssets: types.V1ImageToVideoCreateBodyAssets{\n\t\t\tEndImageFilePath: nullable.NewValue(\"api-assets/id/1234.png\"),\n\t\t\tImageFilePath:    \"api-assets/id/1234.png\",\n\t\t},\n\t\tAudio:      nullable.NewValue(true),\n\t\tEndSeconds: 5.0,\n\t\tModel:      nullable.NewValue(types.V1ImageToVideoCreateBodyModelEnumKling30),\n\t\tName:       nullable.NewValue(\"My Image To Video video\"),\n\t\tResolution: nullable.NewValue(types.V1ImageToVideoCreateBodyResolutionEnum720p),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .image_to_video()\n    .create(magic_hour::resources::v1::image_to_video::CreateRequest {\n        assets: magic_hour::models::V1ImageToVideoCreateBodyAssets {\n            end_image_file_path: Some(\"api-assets/id/1234.png\".to_string()),\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        audio: Some(true),\n        end_seconds: 5.0,\n        model: Some(magic_hour::models::V1ImageToVideoCreateBodyModelEnum::Kling30),\n        name: Some(\"My Image To Video video\".to_string()),\n        resolution: Some(\n            magic_hour::models::V1ImageToVideoCreateBodyResolutionEnum::Enum720p,\n        ),\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/image-to-video \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Image To Video video\",\n  \"end_seconds\": 5,\n  \"model\": \"kling-3.0\",\n  \"resolution\": \"720p\",\n  \"audio\": true,\n  \"style\": {\n    \"prompt\": \"a dog running\"\n  },\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\",\n    \"end_image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/image-to-video\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Image To Video video',\n    'end_seconds' => 5,\n    'model' => 'kling-3.0',\n    'resolution' => '720p',\n    'audio' => true,\n    'style' => [\n        'prompt' => 'a dog running'\n    ],\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png',\n        'end_image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/image-to-video\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Image To Video video\\\",\\\"end_seconds\\\":5,\\\"model\\\":\\\"kling-3.0\\\",\\\"resolution\\\":\\\"720p\\\",\\\"audio\\\":true,\\\"style\\\":{\\\"prompt\\\":\\\"a dog running\\\"},\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"end_image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/lip-sync":{"post":{"description":"**What this API does**\n\nCreate the same Lip Sync you can make in the browser, but programmatically, so you can automate it, run it at scale, or connect it to your own app or workflow.\n    \n**Good for**\n- Automation and batch processing  \n- Adding lip sync into apps, pipelines, or tools  \n\n**How it works (3 steps)**\n1) Upload your inputs (video, image, or audio) with [Generate Upload URLs](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls) and copy the `file_path`.  \n2) Send a request to create a lip sync job with the basic fields.  \n3) Check the job status until it's `complete`, then download the result from `downloads`.\n\n**Key options**\n- Inputs: usually a file, sometimes a YouTube link, depending on project type  \n- Resolution: free users are limited to 576px; higher plans unlock HD and larger sizes  \n- Extra fields: e.g. `face_swap_mode`, `start_seconds`/`end_seconds`, or a text prompt  \n\n**Cost**  \nCredits are only charged for the frames that actually render. You'll see an estimate when the job is queued, and the final total after it's done.\n\nFor detailed examples, see the [product page](https://magichour.ai/products/lip-sync).","summary":"Lip Sync","tags":["Video Projects"],"parameters":[],"operationId":"lipSync.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Lip Sync video","default":"Lip Sync - dateTime"},"height":{"nullable":true,"description":"`height` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"width":{"nullable":true,"description":"`width` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"start_seconds":{"type":"number","minimum":0,"description":"Start time of your clip (seconds). Must be ≥ 0.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"End time of your clip (seconds). Must be greater than start_seconds.","format":"float","example":15},"max_fps_limit":{"type":"number","minimum":1,"description":"Defines the maximum FPS (frames per second) for the output video. If the input video's FPS is lower than this limit, the output video will retain the input FPS. This is useful for reducing unnecessary frame usage in scenarios where high FPS is not required.","example":12},"assets":{"type":"object","properties":{"audio_file_path":{"type":"string","minLength":1,"description":"The path of the audio file. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp3"},"video_source":{"type":"string","enum":["file","youtube"],"description":"Choose your video source.","example":"file"},"video_file_path":{"type":"string","description":"Your video file. Required if `video_source` is `file`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp4"},"youtube_url":{"type":"string","format":"uri","description":"YouTube URL (required if `video_source` is `youtube`)."}},"required":["audio_file_path","video_source"],"description":"Provide the assets for lip-sync. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used"},"style":{"type":"object","properties":{"generation_mode":{"default":"lite","type":"string","enum":["lite","standard","pro"],"description":"A specific version of our lip sync system, optimized for different needs.\n* `lite` -  Fast and affordable lip sync - best for simple videos. Costs 1 credit per frame of video.\n* `standard` -  Natural, accurate lip sync - best for most creators. Costs 1 credit per frame of video.\n* `pro` -  Premium fidelity with enhanced detail - best for professionals. Costs 2 credits per frame of video.\n\nNote: `standard` and `pro` are only available for users on Creator, Pro, and Business tiers.\n              ","example":"lite"}},"description":"Attributes used to dictate the style of the output"}},"required":["start_seconds","end_seconds","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.lip_sync.generate(\n    assets={\n        \"audio_file_path\": \"/path/to/1234.mp3\",\n        \"video_file_path\": \"/path/to/1234.mp4\",\n        \"video_source\": \"file\",\n    },\n    style={\n        \"generation_mode\": \"lite\",\n    },\n    end_seconds=15.0,\n    start_seconds=0.0,\n    max_fps_limit=12.0,\n    name=\"Lip Sync video\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.lipSync.generate(\n  {\n    assets: {\n      audioFilePath: \"/path/to/1234.mp3\",\n      videoFilePath: \"/path/to/1234.mp4\",\n      videoSource: \"file\",\n    },\n    endSeconds: 15.0,\n    maxFpsLimit: 12.0,\n    name: \"Lip Sync video\",\n    startSeconds: 0.0,\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tlip_sync \"github.com/magichourhq/magic-hour-go/resources/v1/lip_sync\"\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.LipSync.Create(lip_sync.CreateRequest{\n\t\tAssets: types.V1LipSyncCreateBodyAssets{\n\t\t\tAudioFilePath: \"api-assets/id/1234.mp3\",\n\t\t\tVideoFilePath: nullable.NewValue(\"api-assets/id/1234.mp4\"),\n\t\t\tVideoSource:   types.V1LipSyncCreateBodyAssetsVideoSourceEnumFile,\n\t\t},\n\t\tEndSeconds:   15.0,\n\t\tMaxFpsLimit:  nullable.NewValue(12.0),\n\t\tName:         nullable.NewValue(\"My Lip Sync video\"),\n\t\tStartSeconds: 0.0,\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .lip_sync()\n    .create(magic_hour::resources::v1::lip_sync::CreateRequest {\n        assets: magic_hour::models::V1LipSyncCreateBodyAssets {\n            audio_file_path: \"api-assets/id/1234.mp3\".to_string(),\n            video_file_path: Some(\"api-assets/id/1234.mp4\".to_string()),\n            video_source: magic_hour::models::V1LipSyncCreateBodyAssetsVideoSourceEnum::File,\n            ..Default::default()\n        },\n        end_seconds: 15.0,\n        max_fps_limit: Some(12.0),\n        name: Some(\"My Lip Sync video\".to_string()),\n        start_seconds: 0.0,\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/lip-sync \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Lip Sync video\",\n  \"start_seconds\": 0,\n  \"end_seconds\": 15,\n  \"max_fps_limit\": 12,\n  \"assets\": {\n    \"audio_file_path\": \"api-assets/id/1234.mp3\",\n    \"video_source\": \"file\",\n    \"video_file_path\": \"api-assets/id/1234.mp4\",\n    \"youtube_url\": \"string\"\n  },\n  \"style\": {\n    \"generation_mode\": \"lite\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/lip-sync\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Lip Sync video',\n    'start_seconds' => 0,\n    'end_seconds' => 15,\n    'max_fps_limit' => 12,\n    'assets' => [\n        'audio_file_path' => 'api-assets/id/1234.mp3',\n        'video_source' => 'file',\n        'video_file_path' => 'api-assets/id/1234.mp4',\n        'youtube_url' => 'string'\n    ],\n    'style' => [\n        'generation_mode' => 'lite'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/lip-sync\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Lip Sync video\\\",\\\"start_seconds\\\":0,\\\"end_seconds\\\":15,\\\"max_fps_limit\\\":12,\\\"assets\\\":{\\\"audio_file_path\\\":\\\"api-assets/id/1234.mp3\\\",\\\"video_source\\\":\\\"file\\\",\\\"video_file_path\\\":\\\"api-assets/id/1234.mp4\\\",\\\"youtube_url\\\":\\\"string\\\"},\\\"style\\\":{\\\"generation_mode\\\":\\\"lite\\\"}}\")\n  .asString();"}]}},"/v1/video-to-video":{"post":{"description":"**What this API does**\n\nCreate the same Video To Video you can make in the browser, but programmatically, so you can automate it, run it at scale, or connect it to your own app or workflow.\n    \n**Good for**\n- Automation and batch processing  \n- Adding video to video into apps, pipelines, or tools  \n\n**How it works (3 steps)**\n1) Upload your inputs (video, image, or audio) with [Generate Upload URLs](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls) and copy the `file_path`.  \n2) Send a request to create a video to video job with the basic fields.  \n3) Check the job status until it's `complete`, then download the result from `downloads`.\n\n**Key options**\n- Inputs: usually a file, sometimes a YouTube link, depending on project type  \n- Resolution: free users are limited to 576px; higher plans unlock HD and larger sizes  \n- Extra fields: e.g. `face_swap_mode`, `start_seconds`/`end_seconds`, or a text prompt  \n\n**Cost**  \nCredits are only charged for the frames that actually render. You'll see an estimate when the job is queued, and the final total after it's done.\n\nFor detailed examples, see the [product page](https://magichour.ai/products/video-to-video).","summary":"Video-to-Video","tags":["Video Projects"],"parameters":[],"operationId":"videoToVideo.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Video To Video video","default":"Video To Video - dateTime"},"start_seconds":{"type":"number","minimum":0,"description":"Start time of your clip (seconds). Must be ≥ 0.","format":"float","example":0},"end_seconds":{"type":"number","minimum":0.1,"description":"End time of your clip (seconds). Must be greater than start_seconds.","format":"float","example":15},"height":{"nullable":true,"description":"`height` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"width":{"nullable":true,"description":"`width` is deprecated and no longer influences the output video's resolution.\n\nThis field is retained only for backward compatibility and will be removed in a future release.","deprecated":true,"type":"integer"},"fps_resolution":{"default":"HALF","type":"string","enum":["FULL","HALF"],"description":"Determines whether the resulting video will have the same frame per second as the original video, or half.\n* `FULL` - the result video will have the same FPS as the input video\n* `HALF` - the result video will have half the FPS as the input video","example":"HALF"},"style":{"type":"object","properties":{"art_style":{"type":"string","enum":["Minecraft","Watercolor","Pixel","Retro Sci-Fi","Lego","Origami","Ghost","Sub-Zero","Studio Ghibli","Comic","Impressionism","Master Chief","Solid Snake","Street Fighter","Hologram","GTA","Clay","Mystique","Dragonball Z","Mario","Samurai","Spartan","Boba Fett","3D Render","Airbender","Android","Anime Warrior","Armored Knight","Assassin's Creed","Avatar","Black Spiderman","Bold Anime","Celestial Skin","Chinese Swordsmen","Cyberpunk","Cypher","Dark Fantasy","Future Bot","Futuristic Fantasy","Ghibli Anime","Gundam","Illustration","Ink","Ink Poster","Jinx","Knight","Link","Marble","Mech","Naruto","Neon Dream","No Art Style","Oil Painting","On Fire","Painterly Anime","Pixar","Power Armor","Power Ranger","Radiant Anime","Realistic Anime","Realistic Pixar","Retro Anime","Samurai Bot","Sharp Anime","Soft Anime","Starfield","The Void","Tomb Raider","Underwater","Van Gogh","Viking","Western Anime","Wu Kong","Wuxia Anime","Zelda"]},"version":{"default":"default","type":"string","enum":["v1","v2","default"],"example":"default","description":"* `v1` - more detail, closer prompt adherence, and frame-by-frame previews.\n* `v2` - faster, more consistent, and less noisy.\n* `default` - use the default version for the selected art style."},"prompt_type":{"default":"default","type":"string","enum":["default","custom","append_default"],"example":"default","description":"* `default` - Use the default recommended prompt for the art style.\n* `custom` - Only use the prompt passed in the API. Note: for v1, lora prompt will still be auto added to apply the art style properly.\n* `append_default` - Add the default recommended prompt to the end of the prompt passed in the API."},"prompt":{"type":"string","nullable":true,"description":"The prompt used for the video. Prompt is required if `prompt_type` is `custom` or `append_default`. If `prompt_type` is `default`, then the `prompt` value passed will be ignored."},"model":{"default":"default","type":"string","enum":["Dreamshaper","Absolute Reality","Flat 2D Anime","Soft Anime","Kaywaii","Western Anime","3D Anime","default"],"example":"default","description":"* `Dreamshaper` - a good all-around model that works for both animations as well as realism.\n* `Absolute Reality` - better at realism, but you'll often get similar results with Dreamshaper as well.\n* `Flat 2D Anime` - best for a flat illustration style that's common in most anime.\n* `default` - use the default recommended model for the selected art style."}},"required":["art_style"]},"assets":{"type":"object","properties":{"video_source":{"type":"string","enum":["file","youtube"],"description":"Choose your video source.","example":"file"},"video_file_path":{"type":"string","description":"Your video file. Required if `video_source` is `file`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp4"},"youtube_url":{"type":"string","format":"uri","description":"YouTube URL (required if `video_source` is `youtube`)."}},"required":["video_source"],"description":"Provide the assets for video-to-video. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used"}},"required":["start_seconds","end_seconds","style","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.video_to_video.generate(\n    assets={\"video_file_path\": \"/path/to/1234.mp4\", \"video_source\": \"file\"},\n    end_seconds=15.0,\n    start_seconds=0.0,\n    style={\n        \"art_style\": \"3D Render\",\n        \"model\": \"default\",\n        \"prompt\": \"string\",\n        \"prompt_type\": \"default\",\n        \"version\": \"default\",\n    },\n    fps_resolution=\"HALF\",\n    name=\"Video To Video video\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.videoToVideo.generate(\n  {\n    assets: { videoFilePath: \"/path/to/1234.mp4\", videoSource: \"file\" },\n    endSeconds: 15.0,\n    fpsResolution: \"HALF\",\n    name: \"Video To Video video\",\n    startSeconds: 0.0,\n    style: {\n      artStyle: \"3D Render\",\n      model: \"default\",\n      prompt: \"string\",\n      promptType: \"default\",\n      version: \"default\",\n    },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tvideo_to_video \"github.com/magichourhq/magic-hour-go/resources/v1/video_to_video\"\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.VideoToVideo.Create(video_to_video.CreateRequest{\n\t\tAssets: types.V1VideoToVideoCreateBodyAssets{\n\t\t\tVideoFilePath: nullable.NewValue(\"api-assets/id/1234.mp4\"),\n\t\t\tVideoSource:   types.V1VideoToVideoCreateBodyAssetsVideoSourceEnumFile,\n\t\t},\n\t\tEndSeconds:    15.0,\n\t\tFpsResolution: nullable.NewValue(types.V1VideoToVideoCreateBodyFpsResolutionEnumHalf),\n\t\tName:          nullable.NewValue(\"My Video To Video video\"),\n\t\tStartSeconds:  0.0,\n\t\tStyle: types.V1VideoToVideoCreateBodyStyle{\n\t\t\tArtStyle:   types.V1VideoToVideoCreateBodyStyleArtStyleEnum3dRender,\n\t\t\tModel:      nullable.NewValue(types.V1VideoToVideoCreateBodyStyleModelEnumDefault),\n\t\t\tPromptType: nullable.NewValue(types.V1VideoToVideoCreateBodyStylePromptTypeEnumDefault),\n\t\t\tVersion:    nullable.NewValue(types.V1VideoToVideoCreateBodyStyleVersionEnumDefault),\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .video_to_video()\n    .create(magic_hour::resources::v1::video_to_video::CreateRequest {\n        assets: magic_hour::models::V1VideoToVideoCreateBodyAssets {\n            video_file_path: Some(\"api-assets/id/1234.mp4\".to_string()),\n            video_source: magic_hour::models::V1VideoToVideoCreateBodyAssetsVideoSourceEnum::File,\n            ..Default::default()\n        },\n        end_seconds: 15.0,\n        fps_resolution: Some(\n            magic_hour::models::V1VideoToVideoCreateBodyFpsResolutionEnum::Half,\n        ),\n        name: Some(\"My Video To Video video\".to_string()),\n        start_seconds: 0.0,\n        style: magic_hour::models::V1VideoToVideoCreateBodyStyle {\n            art_style: magic_hour::models::V1VideoToVideoCreateBodyStyleArtStyleEnum::Enum3dRender,\n            model: Some(\n                magic_hour::models::V1VideoToVideoCreateBodyStyleModelEnum::Default,\n            ),\n            prompt_type: Some(\n                magic_hour::models::V1VideoToVideoCreateBodyStylePromptTypeEnum::Default,\n            ),\n            version: Some(\n                magic_hour::models::V1VideoToVideoCreateBodyStyleVersionEnum::Default,\n            ),\n            ..Default::default()\n        },\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/video-to-video \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Video To Video video\",\n  \"start_seconds\": 0,\n  \"end_seconds\": 15,\n  \"fps_resolution\": \"HALF\",\n  \"style\": {\n    \"art_style\": \"Minecraft\",\n    \"version\": \"default\",\n    \"prompt_type\": \"default\",\n    \"prompt\": \"string\",\n    \"model\": \"default\"\n  },\n  \"assets\": {\n    \"video_source\": \"file\",\n    \"video_file_path\": \"api-assets/id/1234.mp4\",\n    \"youtube_url\": \"string\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/video-to-video\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Video To Video video',\n    'start_seconds' => 0,\n    'end_seconds' => 15,\n    'fps_resolution' => 'HALF',\n    'style' => [\n        'art_style' => 'Minecraft',\n        'version' => 'default',\n        'prompt_type' => 'default',\n        'prompt' => 'string',\n        'model' => 'default'\n    ],\n    'assets' => [\n        'video_source' => 'file',\n        'video_file_path' => 'api-assets/id/1234.mp4',\n        'youtube_url' => 'string'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/video-to-video\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Video To Video video\\\",\\\"start_seconds\\\":0,\\\"end_seconds\\\":15,\\\"fps_resolution\\\":\\\"HALF\\\",\\\"style\\\":{\\\"art_style\\\":\\\"Minecraft\\\",\\\"version\\\":\\\"default\\\",\\\"prompt_type\\\":\\\"default\\\",\\\"prompt\\\":\\\"string\\\",\\\"model\\\":\\\"default\\\"},\\\"assets\\\":{\\\"video_source\\\":\\\"file\\\",\\\"video_file_path\\\":\\\"api-assets/id/1234.mp4\\\",\\\"youtube_url\\\":\\\"string\\\"}}\")\n  .asString();"}]}},"/v1/text-to-video":{"post":{"description":"**What this API does**\n\nCreate the same Text To Video you can make in the browser, but programmatically, so you can automate it, run it at scale, or connect it to your own app or workflow.\n    \n**Good for**\n- Automation and batch processing  \n- Adding text to video into apps, pipelines, or tools  \n\n**How it works (3 steps)**\n1) Upload your inputs (video, image, or audio) with [Generate Upload URLs](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls) and copy the `file_path`.  \n2) Send a request to create a text to video job with the basic fields.  \n3) Check the job status until it's `complete`, then download the result from `downloads`.\n\n**Key options**\n- Inputs: usually a file, sometimes a YouTube link, depending on project type  \n- Resolution: free users are limited to 576px; higher plans unlock HD and larger sizes  \n- Extra fields: e.g. `face_swap_mode`, `start_seconds`/`end_seconds`, or a text prompt  \n\n**Cost**  \nCredits are only charged for the frames that actually render. You'll see an estimate when the job is queued, and the final total after it's done.\n\nFor detailed examples, see the [product page](https://magichour.ai/products/text-to-video).","summary":"Text-to-Video","tags":["Video Projects"],"parameters":[],"operationId":"textToVideo.createVideo","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your video a custom name for easy identification.","example":"My Text To Video video","default":"Text To Video - dateTime"},"end_seconds":{"type":"number","minimum":1,"maximum":60,"description":"The total duration of the output video in seconds. Supported durations depend on the chosen model:\n\n* **`ltx-2`**: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30\n* **`wan-2.2`**: 3, 4, 5, 6, 7, 8, 9, 10, 15\n* **`seedance`**: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12\n* **`seedance-2.0`**: 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n* **`kling-2.5`**: 5, 10\n* **`kling-3.0`**: 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n* **`sora-2`**: 4, 8, 12, 24, 36, 48, 60\n* **`veo3.1`**: 4, 6, 8, 16, 24, 32, 40, 48, 56\n* **`veo3.1-lite`**: 8, 16, 24, 32, 40, 48, 56\n\nLegacy models:\n* **`kling-1.6`**: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60","format":"float","example":5},"aspect_ratio":{"type":"string","enum":["16:9","9:16","1:1"],"description":"Determines the aspect ratio of the output video.\n\n* **`ltx-2`**: Supports 9:16, 16:9, 1:1.\n* **`wan-2.2`**: Supports 9:16, 16:9, 1:1.\n* **`seedance`**: Supports 9:16, 16:9, 1:1.\n* **`seedance-2.0`**: Supports 9:16, 16:9, 1:1.\n* **`kling-2.5`**: Supports 9:16, 16:9, 1:1.\n* **`kling-3.0`**: Supports 9:16, 16:9, 1:1.\n* **`sora-2`**: Supports 9:16, 16:9.\n* **`veo3.1`**: Supports 9:16, 16:9.\n* **`veo3.1-lite`**: Supports 9:16, 16:9.\n\nLegacy models:\n* **`kling-1.6`**: Supports 9:16, 16:9, 1:1.","example":"16:9"},"orientation":{"type":"string","enum":["portrait","landscape","square"],"description":"Deprecated. Use `aspect_ratio` instead.","deprecated":true,"example":"landscape"},"resolution":{"type":"string","enum":["480p","720p","1080p"],"example":"720p","description":"Controls the output video resolution. Defaults to `720p` on paid tiers and `480p` on free tiers.\n\n* **`ltx-2`**: Supports 480p, 720p, 1080p.\n* **`wan-2.2`**: Supports 480p, 720p, 1080p.\n* **`seedance`**: Supports 480p, 720p, 1080p.\n* **`seedance-2.0`**: Supports 480p, 720p.\n* **`kling-2.5`**: Supports 720p, 1080p.\n* **`kling-3.0`**: Supports 720p, 1080p.\n* **`sora-2`**: Supports 720p.\n* **`veo3.1`**: Supports 720p, 1080p.\n* **`veo3.1-lite`**: Supports 720p, 1080p.\n\nLegacy models:\n* **`kling-1.6`**: Supports 720p, 1080p."},"model":{"default":"default","type":"string","enum":["default","ltx-2","wan-2.2","seedance","seedance-2.0","kling-2.5","kling-3.0","veo3.1","veo3.1-lite","sora-2","kling-1.6","kling-2.5-audio","veo3.1-audio"],"description":"The AI model to use for video generation.\n\n* `default`: uses our currently recommended model for general use. For paid tiers, defaults to `kling-3.0`. For free tiers, it defaults to `ltx-2`.\n* `ltx-2`: Fast iteration with audio and lip-sync\n* `wan-2.2`: Fast, strong visuals with effects\n* `seedance`: Fast iteration and start/end frames\n* `seedance-2.0`: State-of-the-art quality and consistency\n* `kling-2.5`: Motion, action, and camera control\n* `kling-3.0`: Cinematic, multi-scene storytelling\n* `sora-2`: Story-first concepts and creativity\n* `veo3.1`: Realistic visuals and prompt adherence\n* `veo3.1-lite`: Good for fast, affordable, high-quality daily generation.\n\nLegacy models:\n* `kling-1.6`: Reliable baseline with smooth motion\n\nIf you specify the deprecated model value that includes the `-audio` suffix, this will be the same as included `audio` as `true`.","example":"kling-3.0"},"audio":{"type":"boolean","description":"Whether to include audio in the video. Defaults to `false` if not specified.\n\nAudio support varies by model:\n* **`ltx-2`**: Toggle-able: no additional credits for audio\n* **`wan-2.2`**: Not supported\n* **`seedance`**: Not supported\n* **`seedance-2.0`**: Toggle-able: no additional credits for audio\n* **`kling-2.5`**: Toggle-able: no additional credits for audio\n* **`kling-3.0`**: Toggle-able: audio adds extra credits when enabled\n* **`sora-2`**: Toggle-able: no additional credits for audio\n* **`veo3.1`**: Toggle-able: audio adds extra credits when enabled\n* **`veo3.1-lite`**: Toggle-able: audio adds extra credits when enabled\n\nLegacy models:\n* **`kling-1.6`**: Not supported","example":true},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000,"example":"a dog running","description":"The prompt used for the video."},"quality_mode":{"type":"string","enum":["quick","studio"],"deprecated":true,"description":"DEPRECATED: Please use `resolution` field instead. For backward compatibility:\n* `quick` maps to 720p resolution\n* `studio` maps to 1080p resolution\n\nThis field will be removed in a future version. Use the `resolution` field to directly to specify the resolution."}},"required":["prompt"]}},"required":["end_seconds","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the video. Use it with the [Get video Project API](https://docs.magichour.ai/api-reference/video-projects/get-video-details) to fetch status and downloads."},"estimated_frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for video generation. Use 'credits_charged' instead.\n\nThe amount of frames used to generate the video. If the status is not 'complete', the cost is an estimate and will be adjusted when the video completes.","example":450,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the video. If the status is not 'complete', this value is an estimate and may be adjusted upon completion based on the actual FPS of the output video. \n\nIf video generation fails, credits will be refunded, and this field will be updated to include the refund.","example":450}},"required":["id","estimated_frame_cost","credits_charged"],"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":"Unable to create video"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.text_to_video.generate(\n    end_seconds=5.0,\n    orientation=\"landscape\",\n    style={\"prompt\": \"a dog running\"},\n    name=\"Text To Video video\",\n    resolution=\"720p\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.textToVideo.generate(\n  {\n    endSeconds: 5.0,\n    name: \"Text To Video video\",\n    orientation: \"landscape\",\n    resolution: \"720p\",\n    style: { prompt: \"a dog running\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\ttext_to_video \"github.com/magichourhq/magic-hour-go/resources/v1/text_to_video\"\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.TextToVideo.Create(text_to_video.CreateRequest{\n\t\tAspectRatio: nullable.NewValue(types.V1TextToVideoCreateBodyAspectRatioEnum169),\n\t\tAudio:       nullable.NewValue(true),\n\t\tEndSeconds:  5.0,\n\t\tModel:       nullable.NewValue(types.V1TextToVideoCreateBodyModelEnumKling30),\n\t\tName:        nullable.NewValue(\"My Text To Video video\"),\n\t\tOrientation: nullable.NewValue(types.V1TextToVideoCreateBodyOrientationEnumLandscape),\n\t\tResolution:  nullable.NewValue(types.V1TextToVideoCreateBodyResolutionEnum720p),\n\t\tStyle: types.V1TextToVideoCreateBodyStyle{\n\t\t\tPrompt: \"a dog running\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .text_to_video()\n    .create(magic_hour::resources::v1::text_to_video::CreateRequest {\n        aspect_ratio: Some(\n            magic_hour::models::V1TextToVideoCreateBodyAspectRatioEnum::Enum169,\n        ),\n        audio: Some(true),\n        end_seconds: 5.0,\n        model: Some(magic_hour::models::V1TextToVideoCreateBodyModelEnum::Kling30),\n        name: Some(\"My Text To Video video\".to_string()),\n        orientation: Some(\n            magic_hour::models::V1TextToVideoCreateBodyOrientationEnum::Landscape,\n        ),\n        resolution: Some(\n            magic_hour::models::V1TextToVideoCreateBodyResolutionEnum::Enum720p,\n        ),\n        style: magic_hour::models::V1TextToVideoCreateBodyStyle {\n            prompt: \"a dog running\".to_string(),\n            ..Default::default()\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/text-to-video \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Text To Video video\",\n  \"end_seconds\": 5,\n  \"aspect_ratio\": \"16:9\",\n  \"resolution\": \"720p\",\n  \"model\": \"kling-3.0\",\n  \"audio\": true,\n  \"style\": {\n    \"prompt\": \"a dog running\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/text-to-video\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Text To Video video',\n    'end_seconds' => 5,\n    'aspect_ratio' => '16:9',\n    'resolution' => '720p',\n    'model' => 'kling-3.0',\n    'audio' => true,\n    'style' => [\n        'prompt' => 'a dog running'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/text-to-video\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Text To Video video\\\",\\\"end_seconds\\\":5,\\\"aspect_ratio\\\":\\\"16:9\\\",\\\"resolution\\\":\\\"720p\\\",\\\"model\\\":\\\"kling-3.0\\\",\\\"audio\\\":true,\\\"style\\\":{\\\"prompt\\\":\\\"a dog running\\\"}}\")\n  .asString();"}]}},"/v1/image-projects/{id}":{"get":{"description":"Check the progress of a image project. The `downloads` field is populated after a successful render.\n  \n**Statuses**\n- `queued` — waiting to start\n- `rendering` — in progress\n- `complete` — ready; see `downloads`\n- `error` — a failure occurred (see `error`)\n- `canceled` — user canceled\n- `draft` — not used","summary":"Get image details","tags":["Image Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the image project. This value is returned by all of the POST APIs that create an image."}],"operationId":"imageProjects.getDetails","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"name":{"type":"string","nullable":true,"description":"The name of the image.","example":"Example Name"},"status":{"type":"string","enum":["draft","queued","rendering","complete","error","canceled"],"description":"The status of the image.","example":"complete"},"image_count":{"type":"integer","description":"Number of images generated","example":1},"type":{"type":"string","description":"The type of the image project. Possible values are FACE_EDITOR, AI_IMAGE_EDITOR, AI_SELFIE, AI_HEADSHOT, AI_IMAGE, AI_MEME, CLOTHES_CHANGER, BACKGROUND_REMOVER, FACE_SWAP, IMAGE_UPSCALER, AI_GIF, QR_CODE, PHOTO_EDITOR, PHOTO_COLORIZER, HEAD_SWAP, BODY_SWAP, STORYBOARD","example":"AI_IMAGE"},"created_at":{"type":"string","format":"date-time"},"enabled":{"type":"boolean","description":"Whether this resource is active. If false, it is deleted."},"total_frame_cost":{"type":"integer","example":5,"description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","deprecated":true},"credits_charged":{"type":"integer","example":5,"description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund."},"downloads":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://videos.magichour.ai/id/output.png"},"expires_at":{"type":"string","format":"date-time","example":"2024-10-19T05:16:19.027Z"}},"required":["url","expires_at"],"description":"The download url and expiration date of the image project"}},"error":{"type":"object","properties":{"message":{"type":"string","description":"Details on the reason why a failure happened.","example":"Please use an image with a detectable face"},"code":{"type":"string","example":"no_source_face","description":"An error code to indicate why a failure happened."}},"required":["message","code"],"nullable":true,"description":"In the case of an error, this object will contain the error encountered during video render","example":null}},"required":["id","name","status","image_count","type","created_at","enabled","total_frame_cost","credits_charged","downloads","error"],"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"}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.image_projects.get(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.imageProjects.get({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\timage_projects \"github.com/magichourhq/magic-hour-go/resources/v1/image_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\tres, err := client.V1.ImageProjects.Get(image_projects.GetRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .image_projects()\n    .get(magic_hour::resources::v1::image_projects::GetRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request GET \\\n     --url https://api.magichour.ai/v1/image-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/image-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"GET\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.get(\"https://api.magichour.ai/v1/image-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]},"delete":{"description":"Permanently delete the rendered image(s). This action is not reversible, please be sure before deleting.","summary":"Delete image","tags":["Image Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the image project. This value is returned by all of the POST APIs that create an image."}],"operationId":"imageProjects.delete","responses":{"204":{"description":"204"},"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"}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.image_projects.delete(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.imageProjects.delete({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\timage_projects \"github.com/magichourhq/magic-hour-go/resources/v1/image_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\terr := client.V1.ImageProjects.Delete(image_projects.DeleteRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .image_projects()\n    .delete(magic_hour::resources::v1::image_projects::DeleteRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request DELETE \\\n     --url https://api.magichour.ai/v1/image-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/image-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"DELETE\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.delete(\"https://api.magichour.ai/v1/image-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]}},"/v1/ai-clothes-changer":{"post":{"description":"Change outfits in photos in seconds with just a photo reference. Each photo costs 25 credits.","summary":"AI Clothes Changer","tags":["Image Projects"],"parameters":[],"operationId":"aiClothesChanger.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Clothes Changer image","default":"Clothes Changer - dateTime"},"assets":{"type":"object","properties":{"person_file_path":{"type":"string","minLength":1,"description":"The image with the person. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/model.png"},"garment_file_path":{"type":"string","minLength":1,"description":"The image of the outfit. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/outfit.png"},"garment_type":{"type":"string","enum":["entire_outfit","upper_body","lower_body","dresses"],"description":"Type of garment to swap. If not provided, swaps the entire outfit. \n* `upper_body` - for shirts/jackets \n* `lower_body` - for pants/skirts \n* `dresses` - for entire outfit (deprecated, use `entire_outfit` instead) \n* `entire_outfit` - for entire outfit","example":"entire_outfit"}},"required":["person_file_path","garment_file_path"],"description":"Provide the assets for clothes changer"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":25,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":25}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_clothes_changer.generate(\n    assets={\n        \"garment_file_path\": \"/path/to/outfit.png\",\n        \"garment_type\": \"upper_body\",\n        \"person_file_path\": \"/path/to/model.png\",\n    },\n    name=\"Clothes Changer image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\",\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiClothesChanger.generate(\n  {\n    assets: {\n      garmentFilePath: \"/path/to/outfit.png\",\n      garmentType: \"upper_body\",\n      personFilePath: \"/path/to/model.png\",\n    },\n    name: \"Clothes Changer image\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_clothes_changer \"github.com/magichourhq/magic-hour-go/resources/v1/ai_clothes_changer\"\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.AiClothesChanger.Create(ai_clothes_changer.CreateRequest{\n\t\tAssets: types.V1AiClothesChangerCreateBodyAssets{\n\t\t\tGarmentFilePath: \"api-assets/id/outfit.png\",\n\t\t\tGarmentType:     nullable.NewValue(types.V1AiClothesChangerCreateBodyAssetsGarmentTypeEnumEntireOutfit),\n\t\t\tPersonFilePath:  \"api-assets/id/model.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Clothes Changer image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_clothes_changer()\n    .create(magic_hour::resources::v1::ai_clothes_changer::CreateRequest {\n        assets: magic_hour::models::V1AiClothesChangerCreateBodyAssets {\n            garment_file_path: \"api-assets/id/outfit.png\".to_string(),\n            garment_type: Some(\n                magic_hour::models::V1AiClothesChangerCreateBodyAssetsGarmentTypeEnum::EntireOutfit,\n            ),\n            person_file_path: \"api-assets/id/model.png\".to_string(),\n        },\n        name: Some(\"My Clothes Changer image\".to_string()),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-clothes-changer \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Clothes Changer image\",\n  \"assets\": {\n    \"person_file_path\": \"api-assets/id/model.png\",\n    \"garment_file_path\": \"api-assets/id/outfit.png\",\n    \"garment_type\": \"entire_outfit\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-clothes-changer\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Clothes Changer image',\n    'assets' => [\n        'person_file_path' => 'api-assets/id/model.png',\n        'garment_file_path' => 'api-assets/id/outfit.png',\n        'garment_type' => 'entire_outfit'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-clothes-changer\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Clothes Changer image\\\",\\\"assets\\\":{\\\"person_file_path\\\":\\\"api-assets/id/model.png\\\",\\\"garment_file_path\\\":\\\"api-assets/id/outfit.png\\\",\\\"garment_type\\\":\\\"entire_outfit\\\"}}\")\n  .asString();"}]}},"/v1/ai-face-editor":{"post":{"description":"Edit facial features of an image using AI. Each edit costs 1 frame. The height/width of the output image depends on your subscription. Please refer to our [pricing](https://magichour.ai/pricing) page for more details","summary":"AI Face Editor","tags":["Image Projects"],"parameters":[],"operationId":"aiFaceEditor.editImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Face Editor image","default":"Face Editor - dateTime"},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"This is the image whose face will be edited. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for face editor"},"style":{"type":"object","properties":{"enhance_face":{"default":false,"type":"boolean","description":"Enhance face features","example":false},"eyebrow_direction":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Eyebrow direction (-100 to 100), in increments of 5","example":0},"eye_gaze_horizontal":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Horizontal eye gaze (-100 to 100), in increments of 5","example":0},"eye_gaze_vertical":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Vertical eye gaze (-100 to 100), in increments of 5","example":0},"eye_open_ratio":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Eye open ratio (-100 to 100), in increments of 5","example":0},"lip_open_ratio":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Lip open ratio (-100 to 100), in increments of 5","example":0},"head_roll":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Head roll (-100 to 100), in increments of 5","example":0},"mouth_grim":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Mouth grim (-100 to 100), in increments of 5","example":0},"mouth_pout":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Mouth pout (-100 to 100), in increments of 5","example":0},"mouth_purse":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Mouth purse (-100 to 100), in increments of 5","example":0},"mouth_smile":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Mouth smile (-100 to 100), in increments of 5","example":0},"mouth_position_horizontal":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Horizontal mouth position (-100 to 100), in increments of 5","example":0},"mouth_position_vertical":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Vertical mouth position (-100 to 100), in increments of 5","example":0},"head_pitch":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Head pitch (-100 to 100), in increments of 5","example":0},"head_yaw":{"default":0,"type":"number","minimum":-100,"maximum":100,"multipleOf":5,"description":"Head yaw (-100 to 100), in increments of 5","example":0}},"description":"Face editing parameters"}},"required":["assets","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":1,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":1}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_face_editor.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"},\n    style={\n        \"enhance_face\": False,\n        \"eye_gaze_horizontal\": 0.0,\n        \"eye_gaze_vertical\": 0.0,\n        \"eye_open_ratio\": 0.0,\n        \"eyebrow_direction\": 0.0,\n        \"head_pitch\": 0.0,\n        \"head_roll\": 0.0,\n        \"head_yaw\": 0.0,\n        \"lip_open_ratio\": 0.0,\n        \"mouth_grim\": 0.0,\n        \"mouth_position_horizontal\": 0.0,\n        \"mouth_position_vertical\": 0.0,\n        \"mouth_pout\": 0.0,\n        \"mouth_purse\": 0.0,\n        \"mouth_smile\": 0.0,\n    },\n    name=\"Face Editor image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiFaceEditor.generate(\n  {\n    assets: { imageFilePath: \"/path/to/1234.png\" },\n    name: \"Face Editor image\",\n    style: {\n      enhanceFace: false,\n      eyeGazeHorizontal: 0.0,\n      eyeGazeVertical: 0.0,\n      eyeOpenRatio: 0.0,\n      eyebrowDirection: 0.0,\n      headPitch: 0.0,\n      headRoll: 0.0,\n      headYaw: 0.0,\n      lipOpenRatio: 0.0,\n      mouthGrim: 0.0,\n      mouthPositionHorizontal: 0.0,\n      mouthPositionVertical: 0.0,\n      mouthPout: 0.0,\n      mouthPurse: 0.0,\n      mouthSmile: 0.0,\n    },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_face_editor \"github.com/magichourhq/magic-hour-go/resources/v1/ai_face_editor\"\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.AiFaceEditor.Create(ai_face_editor.CreateRequest{\n\t\tAssets: types.V1AiFaceEditorCreateBodyAssets{\n\t\t\tImageFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Face Editor image\"),\n\t\tStyle: types.V1AiFaceEditorCreateBodyStyle{\n\t\t\tEnhanceFace:             nullable.NewValue(false),\n\t\t\tEyeGazeHorizontal:       nullable.NewValue(0.0),\n\t\t\tEyeGazeVertical:         nullable.NewValue(0.0),\n\t\t\tEyeOpenRatio:            nullable.NewValue(0.0),\n\t\t\tEyebrowDirection:        nullable.NewValue(0.0),\n\t\t\tHeadPitch:               nullable.NewValue(0.0),\n\t\t\tHeadRoll:                nullable.NewValue(0.0),\n\t\t\tHeadYaw:                 nullable.NewValue(0.0),\n\t\t\tLipOpenRatio:            nullable.NewValue(0.0),\n\t\t\tMouthGrim:               nullable.NewValue(0.0),\n\t\t\tMouthPositionHorizontal: nullable.NewValue(0.0),\n\t\t\tMouthPositionVertical:   nullable.NewValue(0.0),\n\t\t\tMouthPout:               nullable.NewValue(0.0),\n\t\t\tMouthPurse:              nullable.NewValue(0.0),\n\t\t\tMouthSmile:              nullable.NewValue(0.0),\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_face_editor()\n    .create(magic_hour::resources::v1::ai_face_editor::CreateRequest {\n        assets: magic_hour::models::V1AiFaceEditorCreateBodyAssets {\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Face Editor image\".to_string()),\n        style: magic_hour::models::V1AiFaceEditorCreateBodyStyle {\n            enhance_face: Some(false),\n            eye_gaze_horizontal: Some(0.0),\n            eye_gaze_vertical: Some(0.0),\n            eye_open_ratio: Some(0.0),\n            eyebrow_direction: Some(0.0),\n            head_pitch: Some(0.0),\n            head_roll: Some(0.0),\n            head_yaw: Some(0.0),\n            lip_open_ratio: Some(0.0),\n            mouth_grim: Some(0.0),\n            mouth_position_horizontal: Some(0.0),\n            mouth_position_vertical: Some(0.0),\n            mouth_pout: Some(0.0),\n            mouth_purse: Some(0.0),\n            mouth_smile: Some(0.0),\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-face-editor \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Face Editor image\",\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\"\n  },\n  \"style\": {\n    \"enhance_face\": false,\n    \"eyebrow_direction\": 0,\n    \"eye_gaze_horizontal\": 0,\n    \"eye_gaze_vertical\": 0,\n    \"eye_open_ratio\": 0,\n    \"lip_open_ratio\": 0,\n    \"head_roll\": 0,\n    \"mouth_grim\": 0,\n    \"mouth_pout\": 0,\n    \"mouth_purse\": 0,\n    \"mouth_smile\": 0,\n    \"mouth_position_horizontal\": 0,\n    \"mouth_position_vertical\": 0,\n    \"head_pitch\": 0,\n    \"head_yaw\": 0\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-face-editor\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Face Editor image',\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png'\n    ],\n    'style' => [\n        'enhance_face' => false,\n        'eyebrow_direction' => 0,\n        'eye_gaze_horizontal' => 0,\n        'eye_gaze_vertical' => 0,\n        'eye_open_ratio' => 0,\n        'lip_open_ratio' => 0,\n        'head_roll' => 0,\n        'mouth_grim' => 0,\n        'mouth_pout' => 0,\n        'mouth_purse' => 0,\n        'mouth_smile' => 0,\n        'mouth_position_horizontal' => 0,\n        'mouth_position_vertical' => 0,\n        'head_pitch' => 0,\n        'head_yaw' => 0\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-face-editor\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Face Editor image\\\",\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\"},\\\"style\\\":{\\\"enhance_face\\\":false,\\\"eyebrow_direction\\\":0,\\\"eye_gaze_horizontal\\\":0,\\\"eye_gaze_vertical\\\":0,\\\"eye_open_ratio\\\":0,\\\"lip_open_ratio\\\":0,\\\"head_roll\\\":0,\\\"mouth_grim\\\":0,\\\"mouth_pout\\\":0,\\\"mouth_purse\\\":0,\\\"mouth_smile\\\":0,\\\"mouth_position_horizontal\\\":0,\\\"mouth_position_vertical\\\":0,\\\"head_pitch\\\":0,\\\"head_yaw\\\":0}}\")\n  .asString();"}]}},"/v1/ai-gif-generator":{"post":{"description":"Create an AI GIF. Each GIF costs 50 credits.","summary":"AI GIF Generator","tags":["Image Projects"],"parameters":[],"operationId":"aiGifGenerator.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your gif a custom name for easy identification.","example":"My Ai Gif gif","default":"Ai Gif - dateTime"},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":500,"description":"The prompt used for the GIF.","example":"Cute dancing cat, pixel art"}},"required":["prompt"]},"output_format":{"default":"gif","type":"string","enum":["gif","mp4","webm"],"description":"The output file format for the generated animation.","example":"gif"}},"required":["style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":50,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":50}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create GIF"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_gif_generator.generate(\n    style={\"prompt\": \"Cute dancing cat, pixel art\"},\n    name=\"Ai Gif gif\",\n    output_format=\"gif\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiGifGenerator.generate(\n  {\n    name: \"Ai Gif gif\",\n    style: { prompt: \"Cute dancing cat, pixel art\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_gif_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_gif_generator\"\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.AiGifGenerator.Create(ai_gif_generator.CreateRequest{\n\t\tName:         nullable.NewValue(\"My Ai Gif gif\"),\n\t\tOutputFormat: nullable.NewValue(types.V1AiGifGeneratorCreateBodyOutputFormatEnumGif),\n\t\tStyle: types.V1AiGifGeneratorCreateBodyStyle{\n\t\t\tPrompt: \"Cute dancing cat, pixel art\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_gif_generator()\n    .create(magic_hour::resources::v1::ai_gif_generator::CreateRequest {\n        name: Some(\"My Ai Gif gif\".to_string()),\n        output_format: Some(\n            magic_hour::models::V1AiGifGeneratorCreateBodyOutputFormatEnum::Gif,\n        ),\n        style: magic_hour::models::V1AiGifGeneratorCreateBodyStyle {\n            prompt: \"Cute dancing cat, pixel art\".to_string(),\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-gif-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Ai Gif gif\",\n  \"style\": {\n    \"prompt\": \"Cute dancing cat, pixel art\"\n  },\n  \"output_format\": \"gif\"\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-gif-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Ai Gif gif',\n    'style' => [\n        'prompt' => 'Cute dancing cat, pixel art'\n    ],\n    'output_format' => 'gif'\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-gif-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Ai Gif gif\\\",\\\"style\\\":{\\\"prompt\\\":\\\"Cute dancing cat, pixel art\\\"},\\\"output_format\\\":\\\"gif\\\"}\")\n  .asString();"}]}},"/v1/ai-image-editor":{"post":{"description":"Edit images with AI.","summary":"AI Image Editor","tags":["Image Projects"],"parameters":[],"operationId":"aiImageEditor.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Ai Image Editor image","default":"Ai Image Editor - dateTime"},"image_count":{"type":"number","enum":[1,4,9,16],"description":"Number of images to generate. Maximum varies by model. Defaults to 1 if not specified.","example":1,"default":1},"model":{"type":"string","enum":["default","qwen-edit","nano-banana","nano-banana-2","seedream-v4","nano-banana-pro","seedream-v4.5"],"description":"The AI model to use for image editing. Each model has different capabilities and costs.\n\n**Models:**\n- `default` - Use the model we recommend, which will change over time. This is recommended unless you need a specific model. This is the default behavior.\n- `qwen-edit` - from 10 credits/image\n  - Supported resolutions: 640px, 1k, 2k\n  - Available for tiers: free, creator, pro, business\n  - Max additional input images: 2\n- `nano-banana` - from 50 credits/image\n  - Supported resolutions: 640px, 1k\n  - Available for tiers: free, creator, pro, business\n  - Max additional input images: 9\n- `nano-banana-2` - from 100 credits/image\n  - Supported resolutions: 640px, 1k, 2k, 4k\n  - Available for tiers: free, creator, pro, business\n  - Max additional input images: 9\n- `seedream-v4` - from 40 credits/image\n  - Supported resolutions: 640px, 1k, 2k, 4k\n  - Available for tiers: free, creator, pro, business\n  - Max additional input images: 9\n- `nano-banana-pro` - from 150 credits/image\n  - Supported resolutions: 1k, 2k, 4k\n  - Available for tiers: creator, pro, business\n  - Max additional input images: 9\n- `seedream-v4.5` - from 50 credits/image\n  - Supported resolutions: 640px, 1k, 2k, 4k\n  - Available for tiers: creator, pro, business\n  - Max additional input images: 9\n","example":"default"},"aspect_ratio":{"type":"string","enum":["auto","16:9","9:16","4:3","3:2","1:1","4:5","2:3"],"description":"The aspect ratio of the output image(s). If not specified, defaults to `auto`.","example":"1:1"},"resolution":{"type":"string","enum":["auto","640px","1k","2k","4k"],"description":"Maximum resolution (longest edge) for the output image.\n\n**Options:**\n- `640px` — up to 640px\n- `1k` — up to 1024px\n- `2k` — up to 2048px\n- `4k` — up to 4096px\n- `auto` — **Deprecated.** Mapped server-side from your subscription tier to the best matching resolution the model supports\n\n**Per-model support:**\n- `qwen-edit` - 640px, 1k, 2k\n- `nano-banana` - 640px, 1k\n- `nano-banana-2` - 640px, 1k, 2k, 4k\n- `seedream-v4` - 640px, 1k, 2k, 4k\n- `nano-banana-pro` - 1k, 2k, 4k\n- `seedream-v4.5` - 640px, 1k, 2k, 4k\n\nNote: Resolution availability depends on the model and your subscription tier.","example":"1k"},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":15000,"description":"The prompt used to edit the image.","example":"Give me sunglasses"},"model":{"type":"string","enum":["Nano Banana","Seedream","default"],"description":"Deprecated: Please use `model` instead. The AI model to use for image editing.\n* `Nano Banana` - Precise, realistic edits with consistent results\n* `Seedream` - Creative, imaginative images with artistic freedom\n* `default` - Use the model we recommend, which will change over time. This is recommended unless you need a specific model. This is the default behavior.","deprecated":true}},"required":["prompt"]},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"Deprecated: Please use `image_file_paths` instead as edits with multiple images are now supported. The image used in the edit. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","deprecated":true},"image_file_paths":{"type":"array","items":{"type":"string","minLength":1},"maxItems":10,"description":"The image(s) used in the edit, maximum of 10 images. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":["api-assets/id/1234.png","api-assets/id/1235.png"]}},"description":"Provide the assets for image edit"}},"required":["style","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":50,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":50}},"required":["id","frame_cost","credits_charged"],"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":"Unable to edit image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_image_editor.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"},\n    style={\"prompt\": \"Give me sunglasses\"},\n    name=\"Ai Image Editor image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiImageEditor.generate(\n  {\n    assets: { imageFilePaths: [\"/path/to/1234.png\", \"/path/to/1235.png\"] },\n    name: \"Ai Image Editor image\",\n    style: { prompt: \"Give me sunglasses\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_image_editor \"github.com/magichourhq/magic-hour-go/resources/v1/ai_image_editor\"\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.AiImageEditor.Create(ai_image_editor.CreateRequest{\n\t\tAspectRatio: nullable.NewValue(types.V1AiImageEditorCreateBodyAspectRatioEnum11),\n\t\tAssets: types.V1AiImageEditorCreateBodyAssets{\n\t\t\tImageFilePaths: nullable.NewValue([]string{\n\t\t\t\t\"api-assets/id/1234.png\",\n\t\t\t\t\"api-assets/id/1235.png\",\n\t\t\t}),\n\t\t},\n\t\tImageCount: nullable.NewValue(1.0),\n\t\tModel:      nullable.NewValue(types.V1AiImageEditorCreateBodyModelEnumDefault),\n\t\tName:       nullable.NewValue(\"My Ai Image Editor image\"),\n\t\tResolution: nullable.NewValue(types.V1AiImageEditorCreateBodyResolutionEnum1k),\n\t\tStyle: types.V1AiImageEditorCreateBodyStyle{\n\t\t\tPrompt: \"Give me sunglasses\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_image_editor()\n    .create(magic_hour::resources::v1::ai_image_editor::CreateRequest {\n        aspect_ratio: Some(\n            magic_hour::models::V1AiImageEditorCreateBodyAspectRatioEnum::Enum11,\n        ),\n        assets: magic_hour::models::V1AiImageEditorCreateBodyAssets {\n            image_file_paths: Some(\n                vec![\n                    \"api-assets/id/1234.png\".to_string(), \"api-assets/id/1235.png\"\n                    .to_string()\n                ],\n            ),\n            ..Default::default()\n        },\n        image_count: Some(1.0),\n        model: Some(magic_hour::models::V1AiImageEditorCreateBodyModelEnum::Default),\n        name: Some(\"My Ai Image Editor image\".to_string()),\n        resolution: Some(\n            magic_hour::models::V1AiImageEditorCreateBodyResolutionEnum::Enum1k,\n        ),\n        style: magic_hour::models::V1AiImageEditorCreateBodyStyle {\n            prompt: \"Give me sunglasses\".to_string(),\n            ..Default::default()\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-image-editor \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Ai Image Editor image\",\n  \"image_count\": 1,\n  \"model\": \"default\",\n  \"aspect_ratio\": \"1:1\",\n  \"resolution\": \"1k\",\n  \"style\": {\n    \"prompt\": \"Give me sunglasses\"\n  },\n  \"assets\": {\n    \"image_file_paths\": [\n      \"api-assets/id/1234.png\",\n      \"api-assets/id/1235.png\"\n    ]\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-image-editor\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Ai Image Editor image',\n    'image_count' => 1,\n    'model' => 'default',\n    'aspect_ratio' => '1:1',\n    'resolution' => '1k',\n    'style' => [\n        'prompt' => 'Give me sunglasses'\n    ],\n    'assets' => [\n        'image_file_paths' => [\n                'api-assets/id/1234.png',\n                'api-assets/id/1235.png'\n        ]\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-image-editor\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Ai Image Editor image\\\",\\\"image_count\\\":1,\\\"model\\\":\\\"default\\\",\\\"aspect_ratio\\\":\\\"1:1\\\",\\\"resolution\\\":\\\"1k\\\",\\\"style\\\":{\\\"prompt\\\":\\\"Give me sunglasses\\\"},\\\"assets\\\":{\\\"image_file_paths\\\":[\\\"api-assets/id/1234.png\\\",\\\"api-assets/id/1235.png\\\"]}}\")\n  .asString();"}]}},"/v1/ai-headshot-generator":{"post":{"description":"Create an AI headshot. Each headshot costs 50 credits.","summary":"AI Headshot Generator","tags":["Image Projects"],"parameters":[],"operationId":"aiHeadshotGenerator.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Ai Headshot image","default":"Ai Headshot - dateTime"},"style":{"type":"object","properties":{"prompt":{"type":"string","description":"Prompt used to guide the style of your headshot. We recommend omitting the prompt unless you want to customize your headshot. You can visit [AI headshot generator](https://magichour.ai/create/ai-headshot-generator) to view an example of a good prompt used for our 'Professional' style."}}},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"The image used to generate the headshot. This image must contain one detectable face. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for headshot photo"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":50,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":50}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_headshot_generator.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"}, name=\"Ai Headshot image\"\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiHeadshotGenerator.generate(\n  {\n    assets: { imageFilePath: \"/path/to/1234.png\" },\n    name: \"Ai Headshot image\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_headshot_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_headshot_generator\"\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.AiHeadshotGenerator.Create(ai_headshot_generator.CreateRequest{\n\t\tAssets: types.V1AiHeadshotGeneratorCreateBodyAssets{\n\t\t\tImageFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Ai Headshot image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_headshot_generator()\n    .create(magic_hour::resources::v1::ai_headshot_generator::CreateRequest {\n        assets: magic_hour::models::V1AiHeadshotGeneratorCreateBodyAssets {\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Ai Headshot image\".to_string()),\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-headshot-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Ai Headshot image\",\n  \"style\": {\n    \"prompt\": \"string\"\n  },\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-headshot-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Ai Headshot image',\n    'style' => [\n        'prompt' => 'string'\n    ],\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-headshot-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Ai Headshot image\\\",\\\"style\\\":{\\\"prompt\\\":\\\"string\\\"},\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/ai-image-generator":{"post":{"description":"Create an AI image with advanced model selection and quality controls.","summary":"AI Image Generator","tags":["Image Projects"],"parameters":[],"operationId":"aiImageGenerator.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Ai Image image","default":"Ai Image - dateTime"},"image_count":{"type":"integer","minimum":1,"maximum":16,"description":"Number of images to generate. Maximum varies by model.","example":1},"model":{"type":"string","enum":["default","flux-schnell","z-image-turbo","seedream-v4","nano-banana","nano-banana-2","nano-banana-pro","seedream"],"description":"The AI model to use for image generation. Each model has different capabilities and costs.\n\n**Models:**\n- `default` - Use the model we recommend, which will change over time. This is recommended unless you need a specific model. This is the default behavior.\n- `flux-schnell` - from 5 credits/image\n  - Supported resolutions: 640px, 1k, 2k\n  - Available for tiers: free, creator, pro, business\n  - Image count allowed: 1, 2, 3, 4\n- `z-image-turbo` - from 5 credits/image\n  - Supported resolutions: 640px, 1k, 2k\n  - Available for tiers: free, creator, pro, business\n  - Image count allowed: 1, 2, 3, 4\n- `seedream-v4` - from 40 credits/image\n  - Supported resolutions: 640px, 1k, 2k, 4k\n  - Available for tiers: free, creator, pro, business\n  - Image count allowed: 1, 2, 3, 4\n- `nano-banana` - from 50 credits/image\n  - Supported resolutions: 640px, 1k\n  - Available for tiers: free, creator, pro, business\n  - Image count allowed: 1, 2, 3, 4\n- `nano-banana-2` - from 100 credits/image\n  - Supported resolutions: 640px, 1k, 2k, 4k\n  - Available for tiers: free, creator, pro, business\n  - Image count allowed: 1, 4, 9, 16\n- `nano-banana-pro` - from 150 credits/image\n  - Supported resolutions: 1k, 2k, 4k\n  - Available for tiers: creator, pro, business\n  - Image count allowed: 1, 4, 9, 16\n\n**Deprecated Enum Values:**\n- `seedream` - Use `seedream-v4` instead.\n","example":"default"},"aspect_ratio":{"type":"string","enum":["1:1","16:9","9:16"],"description":"The aspect ratio of the output image(s). If not specified, defaults to `1:1` (square).","example":"1:1"},"resolution":{"default":"auto","type":"string","enum":["auto","640px","1k","2k","4k"],"description":"Maximum resolution (longest edge) for the output image.\n\n**Options:**\n- `640px` — up to 640px\n- `1k` — up to 1024px\n- `2k` — up to 2048px\n- `4k` — up to 4096px\n- `auto` — **Deprecated.** Mapped server-side from your subscription tier to the best matching resolution the model supports\n\n**Per-model support:**\n- `flux-schnell` - 640px, 1k, 2k\n- `z-image-turbo` - 640px, 1k, 2k\n- `seedream-v4` - 640px, 1k, 2k, 4k\n- `nano-banana` - 640px, 1k\n- `nano-banana-2` - 640px, 1k, 2k, 4k\n- `nano-banana-pro` - 1k, 2k, 4k\n\nNote: Resolution availability depends on the model and your subscription tier.","example":"auto"},"orientation":{"type":"string","enum":["square","landscape","portrait"],"description":"DEPRECATED: Use `aspect_ratio` instead. \n          \nThe orientation of the output image(s). `aspect_ratio` takes precedence when `orientation` if both are provided.","deprecated":true},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"The prompt used for the image(s).","example":"Cool image"},"tool":{"default":"general","type":"string","enum":["ai-anime-generator","ai-art-generator","ai-background-generator","ai-character-generator","ai-face-generator","ai-fashion-generator","ai-icon-generator","ai-illustration-generator","ai-interior-design-generator","ai-landscape-generator","ai-logo-generator","ai-manga-generator","ai-outfit-generator","ai-pattern-generator","ai-photo-generator","ai-sketch-generator","ai-tattoo-generator","album-cover-generator","animated-characters-generator","architecture-generator","book-cover-generator","comic-book-generator","dark-fantasy-ai","disney-ai-generator","dnd-ai-art-generator","emoji-generator","fantasy-map-generator","graffiti-generator","movie-poster-generator","optical-illusion-generator","pokemon-generator","south-park-character-generator","superhero-generator","thumbnail-maker","general"],"description":"The art style to use for image generation. Defaults to 'general' if not provided.","example":"ai-anime-generator"},"quality_mode":{"type":"string","enum":["standard","pro"],"description":"DEPRECATED: Use `model` field instead for explicit model selection.\n\nLegacy quality mode mapping:\n- `standard` → `z-image-turbo` model\n- `pro` → `seedream-v4` model\n\nIf model is specified, it will take precedence over the legacy quality_mode field.","deprecated":true}},"required":["prompt"],"description":"The art style to use for image generation."}},"required":["image_count","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":5,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":5}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_image_generator.generate(\n    image_count=1,\n    style={\n        \"prompt\": \"Cool image\",\n        \"tool\": \"ai-anime-generator\",\n    },\n    aspect_ratio=\"1:1\",\n    model=\"default\",\n    name=\"My Ai Image image\",\n    resolution=\"auto\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiImageGenerator.generate(\n  {\n    aspectRatio: \"1:1\",\n    imageCount: 1,\n    model: \"default\",\n    name: \"My Ai Image image\",\n    resolution: \"auto\",\n    style: { prompt: \"Cool image\", tool: \"ai-anime-generator\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_image_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_image_generator\"\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.AiImageGenerator.Create(ai_image_generator.CreateRequest{\n\t\tAspectRatio: nullable.NewValue(types.V1AiImageGeneratorCreateBodyAspectRatioEnum11),\n\t\tImageCount:  1,\n\t\tModel:       nullable.NewValue(types.V1AiImageGeneratorCreateBodyModelEnumDefault),\n\t\tName:        nullable.NewValue(\"My Ai Image image\"),\n\t\tResolution:  nullable.NewValue(types.V1AiImageGeneratorCreateBodyResolutionEnumAuto),\n\t\tStyle: types.V1AiImageGeneratorCreateBodyStyle{\n\t\t\tPrompt: \"Cool image\",\n\t\t\tTool:   nullable.NewValue(types.V1AiImageGeneratorCreateBodyStyleToolEnumAiAnimeGenerator),\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_image_generator()\n    .create(magic_hour::resources::v1::ai_image_generator::CreateRequest {\n        aspect_ratio: Some(\n            magic_hour::models::V1AiImageGeneratorCreateBodyAspectRatioEnum::Enum11,\n        ),\n        image_count: 1,\n        model: Some(\n            magic_hour::models::V1AiImageGeneratorCreateBodyModelEnum::Default,\n        ),\n        name: Some(\"My Ai Image image\".to_string()),\n        resolution: Some(\n            magic_hour::models::V1AiImageGeneratorCreateBodyResolutionEnum::Auto,\n        ),\n        style: magic_hour::models::V1AiImageGeneratorCreateBodyStyle {\n            prompt: \"Cool image\".to_string(),\n            tool: Some(\n                magic_hour::models::V1AiImageGeneratorCreateBodyStyleToolEnum::AiAnimeGenerator,\n            ),\n            ..Default::default()\n        },\n        ..Default::default()\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-image-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Ai Image image\",\n  \"image_count\": 1,\n  \"model\": \"default\",\n  \"aspect_ratio\": \"1:1\",\n  \"resolution\": \"auto\",\n  \"style\": {\n    \"prompt\": \"Cool image\",\n    \"tool\": \"ai-anime-generator\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-image-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Ai Image image',\n    'image_count' => 1,\n    'model' => 'default',\n    'aspect_ratio' => '1:1',\n    'resolution' => 'auto',\n    'style' => [\n        'prompt' => 'Cool image',\n        'tool' => 'ai-anime-generator'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-image-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Ai Image image\\\",\\\"image_count\\\":1,\\\"model\\\":\\\"default\\\",\\\"aspect_ratio\\\":\\\"1:1\\\",\\\"resolution\\\":\\\"auto\\\",\\\"style\\\":{\\\"prompt\\\":\\\"Cool image\\\",\\\"tool\\\":\\\"ai-anime-generator\\\"}}\")\n  .asString();"}]}},"/v1/ai-image-upscaler":{"post":{"description":"Upscale your image using AI. Each 2x upscale costs 50 credits, and 4x upscale costs 200 credits.","summary":"AI Image Upscaler","tags":["Image Projects"],"parameters":[],"operationId":"aiImageUpscaler.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Image Upscaler image","default":"Image Upscaler - dateTime"},"scale_factor":{"type":"number","example":2,"description":"How much to scale the image. Must be either 2 or 4.\n            \nNote: 4x upscale is only available on Creator, Pro, or Business tier."},"style":{"type":"object","properties":{"enhancement":{"type":"string","enum":["Resemblance","Balanced","Creative"]},"prompt":{"type":"string","description":"A prompt to guide the final image. This value is ignored if `enhancement` is not Creative"}},"required":["enhancement"]},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"The image to upscale. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n. The maximum input image size is 4096x4096px.","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for upscaling"}},"required":["scale_factor","style","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":50,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":50}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_image_upscaler.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"},\n    scale_factor=2.0,\n    style={\"enhancement\": \"Balanced\"},\n    name=\"Image Upscaler image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiImageUpscaler.generate(\n  {\n    assets: { imageFilePath: \"/path/to/1234.png\" },\n    name: \"Image Upscaler image\",\n    scaleFactor: 2.0,\n    style: { enhancement: \"Balanced\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_image_upscaler \"github.com/magichourhq/magic-hour-go/resources/v1/ai_image_upscaler\"\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.AiImageUpscaler.Create(ai_image_upscaler.CreateRequest{\n\t\tAssets: types.V1AiImageUpscalerCreateBodyAssets{\n\t\t\tImageFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tName:        nullable.NewValue(\"My Image Upscaler image\"),\n\t\tScaleFactor: 2.0,\n\t\tStyle: types.V1AiImageUpscalerCreateBodyStyle{\n\t\t\tEnhancement: types.V1AiImageUpscalerCreateBodyStyleEnhancementEnumBalanced,\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_image_upscaler()\n    .create(magic_hour::resources::v1::ai_image_upscaler::CreateRequest {\n        assets: magic_hour::models::V1AiImageUpscalerCreateBodyAssets {\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Image Upscaler image\".to_string()),\n        scale_factor: 2.0,\n        style: magic_hour::models::V1AiImageUpscalerCreateBodyStyle {\n            enhancement: magic_hour::models::V1AiImageUpscalerCreateBodyStyleEnhancementEnum::Balanced,\n            ..Default::default()\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-image-upscaler \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Image Upscaler image\",\n  \"scale_factor\": 2,\n  \"style\": {\n    \"enhancement\": \"Resemblance\",\n    \"prompt\": \"string\"\n  },\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-image-upscaler\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Image Upscaler image',\n    'scale_factor' => 2,\n    'style' => [\n        'enhancement' => 'Resemblance',\n        'prompt' => 'string'\n    ],\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-image-upscaler\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Image Upscaler image\\\",\\\"scale_factor\\\":2,\\\"style\\\":{\\\"enhancement\\\":\\\"Resemblance\\\",\\\"prompt\\\":\\\"string\\\"},\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/ai-meme-generator":{"post":{"description":"Create an AI generated meme. Each meme costs 10 credits.","summary":"AI Meme Generator","tags":["Image Projects"],"parameters":[],"operationId":"aiMemeGenerator.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the meme.","example":"My Funny Meme"},"style":{"type":"object","properties":{"topic":{"type":"string","maxLength":200,"minLength":1,"description":"The topic of the meme.","example":"When the code finally works"},"template":{"type":"string","enum":["Random","Drake Hotline Bling","Galaxy Brain","Two Buttons","Gru's Plan","Tuxedo Winnie The Pooh","Is This a Pigeon","Panik Kalm Panik","Disappointed Guy","Waiting Skeleton","Bike Fall","Change My Mind","Side Eyeing Chloe"],"description":"To use our templates, pass in one of the enum values.","example":"Drake Hotline Bling"},"searchWeb":{"default":false,"type":"boolean","description":"Whether to search the web for meme content.","example":false}},"required":["topic","template"]}},"required":["style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":10,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":10}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create meme"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_meme_generator.generate(\n    style={\n        \"search_web\": False,\n        \"template\": \"Drake Hotline Bling\",\n        \"topic\": \"When the code finally works\",\n    },\n    name=\"My Funny Meme\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiMemeGenerator.generate(\n  {\n    name: \"My Funny Meme\",\n    style: {\n      searchWeb: false,\n      template: \"Drake Hotline Bling\",\n      topic: \"When the code finally works\",\n    },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_meme_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_meme_generator\"\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.AiMemeGenerator.Create(ai_meme_generator.CreateRequest{\n\t\tName: nullable.NewValue(\"My Funny Meme\"),\n\t\tStyle: types.V1AiMemeGeneratorCreateBodyStyle{\n\t\t\tSearchWeb: nullable.NewValue(false),\n\t\t\tTemplate:  types.V1AiMemeGeneratorCreateBodyStyleTemplateEnumDrakeHotlineBling,\n\t\t\tTopic:     \"When the code finally works\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_meme_generator()\n    .create(magic_hour::resources::v1::ai_meme_generator::CreateRequest {\n        name: Some(\"My Funny Meme\".to_string()),\n        style: magic_hour::models::V1AiMemeGeneratorCreateBodyStyle {\n            search_web: Some(false),\n            template: magic_hour::models::V1AiMemeGeneratorCreateBodyStyleTemplateEnum::DrakeHotlineBling,\n            topic: \"When the code finally works\".to_string(),\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-meme-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Funny Meme\",\n  \"style\": {\n    \"topic\": \"When the code finally works\",\n    \"template\": \"Drake Hotline Bling\",\n    \"searchWeb\": false\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-meme-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Funny Meme',\n    'style' => [\n        'topic' => 'When the code finally works',\n        'template' => 'Drake Hotline Bling',\n        'searchWeb' => false\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-meme-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Funny Meme\\\",\\\"style\\\":{\\\"topic\\\":\\\"When the code finally works\\\",\\\"template\\\":\\\"Drake Hotline Bling\\\",\\\"searchWeb\\\":false}}\")\n  .asString();"}]}},"/v1/ai-qr-code-generator":{"post":{"description":"Create an AI QR code. Each QR code costs 0 credits.","summary":"AI QR Code Generator","tags":["Image Projects"],"parameters":[],"operationId":"aiQrCodeGenerator.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Qr Code image","default":"Qr Code - dateTime"},"content":{"type":"string","description":"The content of the QR code.","example":"https://magichour.ai"},"style":{"type":"object","properties":{"art_style":{"type":"string","description":"To use our templates, pass in one of Watercolor, Cyberpunk City, Ink Landscape, Interior Painting, Japanese Street, Mech, Minecraft, Picasso Painting, Game Map, Spaceship, Chinese Painting, Winter Village, or pass any custom art style.","example":"Watercolor"}},"required":["art_style"]}},"required":["content","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":0,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":0}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_qr_code_generator.generate(\n    content=\"https://magichour.ai\",\n    style={\"art_style\": \"Watercolor\"},\n    name=\"Qr Code image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiQrCodeGenerator.generate(\n  {\n    content: \"https://magichour.ai\",\n    name: \"Qr Code image\",\n    style: { artStyle: \"Watercolor\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_qr_code_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_qr_code_generator\"\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.AiQrCodeGenerator.Create(ai_qr_code_generator.CreateRequest{\n\t\tContent: \"https://magichour.ai\",\n\t\tName:    nullable.NewValue(\"My Qr Code image\"),\n\t\tStyle: types.V1AiQrCodeGeneratorCreateBodyStyle{\n\t\t\tArtStyle: \"Watercolor\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_qr_code_generator()\n    .create(magic_hour::resources::v1::ai_qr_code_generator::CreateRequest {\n        content: \"https://magichour.ai\".to_string(),\n        name: Some(\"My Qr Code image\".to_string()),\n        style: magic_hour::models::V1AiQrCodeGeneratorCreateBodyStyle {\n            art_style: \"Watercolor\".to_string(),\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-qr-code-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Qr Code image\",\n  \"content\": \"https://magichour.ai\",\n  \"style\": {\n    \"art_style\": \"Watercolor\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-qr-code-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Qr Code image',\n    'content' => 'https://magichour.ai',\n    'style' => [\n        'art_style' => 'Watercolor'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-qr-code-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Qr Code image\\\",\\\"content\\\":\\\"https://magichour.ai\\\",\\\"style\\\":{\\\"art_style\\\":\\\"Watercolor\\\"}}\")\n  .asString();"}]}},"/v1/body-swap":{"post":{"description":"Swap a person into a scene image using Nano Banana 2. Credits depend on `resolution` (from 100 credits at 640px upward).","summary":"Body Swap","tags":["Image Projects"],"parameters":[],"operationId":"bodySwap.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Body Swap image","default":"Body Swap - dateTime"},"resolution":{"type":"string","enum":["640px","1k","2k","4k"],"description":"Output resolution. Determines credits charged for the run.","example":"1k"},"assets":{"type":"object","properties":{"person_file_path":{"type":"string","minLength":1,"description":"Image of the person to place into the scene. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"scene_file_path":{"type":"string","minLength":1,"description":"Target scene image (background). This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/5678.png"}},"required":["person_file_path","scene_file_path"],"description":"Person image and scene image for body swap"}},"required":["resolution","assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":100,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":100}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.body_swap.generate(\n    assets={\n        \"person_file_path\": \"/path/to/person.png\",\n        \"scene_file_path\": \"/path/to/scene.png\",\n    },\n    resolution=\"1k\",\n    name=\"My Body Swap image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\",\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.bodySwap.generate(\n  {\n    assets: {\n      personFilePath: \"/path/to/person.png\",\n      sceneFilePath: \"/path/to/scene.png\",\n    },\n    name: \"My Body Swap image\",\n    resolution: \"1k\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tbody_swap \"github.com/magichourhq/magic-hour-go/resources/v1/body_swap\"\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.BodySwap.Create(body_swap.CreateRequest{\n\t\tAssets: types.V1BodySwapCreateBodyAssets{\n\t\t\tPersonFilePath: \"api-assets/id/1234.png\",\n\t\t\tSceneFilePath:  \"api-assets/id/5678.png\",\n\t\t},\n\t\tName:       nullable.NewValue(\"My Body Swap image\"),\n\t\tResolution: types.V1BodySwapCreateBodyResolutionEnum1k,\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .body_swap()\n    .create(magic_hour::resources::v1::body_swap::CreateRequest {\n        assets: magic_hour::models::V1BodySwapCreateBodyAssets {\n            person_file_path: \"api-assets/id/1234.png\".to_string(),\n            scene_file_path: \"api-assets/id/5678.png\".to_string(),\n        },\n        name: Some(\"My Body Swap image\".to_string()),\n        resolution: magic_hour::models::V1BodySwapCreateBodyResolutionEnum::Enum1k,\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/body-swap \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Body Swap image\",\n  \"resolution\": \"1k\",\n  \"assets\": {\n    \"person_file_path\": \"api-assets/id/1234.png\",\n    \"scene_file_path\": \"api-assets/id/5678.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/body-swap\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Body Swap image',\n    'resolution' => '1k',\n    'assets' => [\n        'person_file_path' => 'api-assets/id/1234.png',\n        'scene_file_path' => 'api-assets/id/5678.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/body-swap\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Body Swap image\\\",\\\"resolution\\\":\\\"1k\\\",\\\"assets\\\":{\\\"person_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"scene_file_path\\\":\\\"api-assets/id/5678.png\\\"}}\")\n  .asString();"}]}},"/v1/face-swap-photo":{"post":{"description":"Create a face swap photo. Each photo costs 10 credits. The height/width of the output image depends on your subscription. Please refer to our [pricing](https://magichour.ai/pricing) page for more details","summary":"Face Swap Photo","tags":["Image Projects"],"parameters":[],"operationId":"faceSwapPhoto.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Face Swap image","default":"Face Swap - dateTime"},"assets":{"type":"object","properties":{"face_swap_mode":{"default":"all-faces","type":"string","enum":["all-faces","individual-faces"],"description":"Choose how to swap faces:\n**all-faces** (recommended) — swap all detected faces using one source image (`source_file_path` required)\n+- **individual-faces** — specify exact mappings using `face_mappings`","example":"all-faces"},"source_file_path":{"type":"string","minLength":1,"description":"This is the image from which the face is extracted. The value is required if `face_swap_mode` is `all-faces`.\n\nThis value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"face_mappings":{"type":"array","items":{"type":"object","properties":{"original_face":{"type":"string","description":"The face detected from the image in `target_file_path`. The file name is in the format of `<face_frame>-<face_index>.png`. This value is corresponds to the response in the [face detection API](https://docs.magichour.ai/api-reference/files/get-face-detection-details).\n\n* The face_frame is the frame number of the face in the target image. For images, the frame number is always 0.\n* The face_index is the index of the face in the target image, starting from 0 going left to right.","example":"api-assets/id/0-0.png"},"new_face":{"type":"string","description":"The face image that will be used to replace the face in the `original_face`. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["original_face","new_face"]},"maxItems":5,"description":"This is the array of face mappings used for multiple face swap. The value is required if `face_swap_mode` is `individual-faces`.","example":[{"original_face":"api-assets/id/0-0.png","new_face":"api-assets/id/1234.png"}]},"target_file_path":{"type":"string","minLength":1,"description":"This is the image where the face from the source image will be placed. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["target_file_path"],"description":"Provide the assets for face swap photo"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":10,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":10}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.face_swap_photo.generate(\n    assets={\n        \"face_mappings\": [\n            {\n                \"new_face\": \"/path/to/1234.png\",\n                \"original_face\": \"api-assets/id/0-0.png\",\n            }\n        ],\n        \"face_swap_mode\": \"all-faces\",\n        \"source_file_path\": \"/path/to/1234.png\",\n        \"target_file_path\": \"/path/to/1234.png\",\n    },\n    name=\"Face Swap image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.faceSwapPhoto.generate(\n  {\n    assets: {\n      faceMappings: [\n        {\n          newFace: \"api-assets/id/1234.png\",\n          originalFace: \"api-assets/id/0-0.png\",\n        },\n      ],\n      faceSwapMode: \"all-faces\",\n      sourceFilePath: \"/path/to/1234.png\",\n      targetFilePath: \"/path/to/1234.png\",\n    },\n    name: \"Face Swap image\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tface_swap_photo \"github.com/magichourhq/magic-hour-go/resources/v1/face_swap_photo\"\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.FaceSwapPhoto.Create(face_swap_photo.CreateRequest{\n\t\tAssets: types.V1FaceSwapPhotoCreateBodyAssets{\n\t\t\tFaceMappings: nullable.NewValue([]types.V1FaceSwapPhotoCreateBodyAssetsFaceMappingsItem{\n\t\t\t\ttypes.V1FaceSwapPhotoCreateBodyAssetsFaceMappingsItem{\n\t\t\t\t\tNewFace:      \"api-assets/id/1234.png\",\n\t\t\t\t\tOriginalFace: \"api-assets/id/0-0.png\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tFaceSwapMode:   nullable.NewValue(types.V1FaceSwapPhotoCreateBodyAssetsFaceSwapModeEnumAllFaces),\n\t\t\tSourceFilePath: nullable.NewValue(\"api-assets/id/1234.png\"),\n\t\t\tTargetFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Face Swap image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .face_swap_photo()\n    .create(magic_hour::resources::v1::face_swap_photo::CreateRequest {\n        assets: magic_hour::models::V1FaceSwapPhotoCreateBodyAssets {\n            face_mappings: Some(\n                vec![\n                    magic_hour::models::V1FaceSwapPhotoCreateBodyAssetsFaceMappingsItem\n                    { new_face : \"api-assets/id/1234.png\".to_string(), original_face\n                    : \"api-assets/id/0-0.png\".to_string() }\n                ],\n            ),\n            face_swap_mode: Some(\n                magic_hour::models::V1FaceSwapPhotoCreateBodyAssetsFaceSwapModeEnum::AllFaces,\n            ),\n            source_file_path: Some(\"api-assets/id/1234.png\".to_string()),\n            target_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Face Swap image\".to_string()),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/face-swap-photo \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Face Swap image\",\n  \"assets\": {\n    \"face_swap_mode\": \"all-faces\",\n    \"source_file_path\": \"api-assets/id/1234.png\",\n    \"face_mappings\": [\n      {\n        \"original_face\": \"api-assets/id/0-0.png\",\n        \"new_face\": \"api-assets/id/1234.png\"\n      }\n    ],\n    \"target_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/face-swap-photo\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Face Swap image',\n    'assets' => [\n        'face_swap_mode' => 'all-faces',\n        'source_file_path' => 'api-assets/id/1234.png',\n        'face_mappings' => [\n                [\n                                'original_face' => 'api-assets/id/0-0.png',\n                                'new_face' => 'api-assets/id/1234.png'\n                ]\n        ],\n        'target_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/face-swap-photo\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Face Swap image\\\",\\\"assets\\\":{\\\"face_swap_mode\\\":\\\"all-faces\\\",\\\"source_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"face_mappings\\\":[{\\\"original_face\\\":\\\"api-assets/id/0-0.png\\\",\\\"new_face\\\":\\\"api-assets/id/1234.png\\\"}],\\\"target_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/head-swap":{"post":{"description":"Swap a head onto a body image. Each image costs 10 credits. Output resolution depends on your subscription; you may set `max_resolution` lower than your plan maximum if desired.","summary":"Head Swap","tags":["Image Projects"],"parameters":[],"operationId":"headSwap.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Head Swap image","default":"Head Swap - dateTime"},"max_resolution":{"type":"integer","description":"Constrains the larger dimension (height or width) of the output. Omit to use the maximum allowed for your plan (capped at 2048px). Values above your plan maximum are clamped down to your plan's maximum.","example":1024},"assets":{"type":"object","properties":{"body_file_path":{"type":"string","minLength":1,"description":"Image that receives the swapped head. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"head_file_path":{"type":"string","minLength":1,"description":"Image of the head to place on the body. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/5678.png"}},"required":["body_file_path","head_file_path"],"description":"Provide the body and head images for head swap"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":10,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":10}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.head_swap.generate(\n    assets={\n        \"body_file_path\": \"/path/to/body.png\",\n        \"head_file_path\": \"/path/to/head.png\",\n    },\n    max_resolution=1024,\n    name=\"My Head Swap image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\",\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.headSwap.create({\n  assets: {\n    bodyFilePath: \"api-assets/id/1234.png\",\n    headFilePath: \"api-assets/id/5678.png\",\n  },\n  maxResolution: 1024,\n  name: \"My Head Swap image\",\n});"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\thead_swap \"github.com/magichourhq/magic-hour-go/resources/v1/head_swap\"\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.HeadSwap.Create(head_swap.CreateRequest{\n\t\tAssets: types.V1HeadSwapCreateBodyAssets{\n\t\t\tBodyFilePath: \"api-assets/id/1234.png\",\n\t\t\tHeadFilePath: \"api-assets/id/5678.png\",\n\t\t},\n\t\tMaxResolution: nullable.NewValue(1024),\n\t\tName:          nullable.NewValue(\"My Head Swap image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .head_swap()\n    .create(magic_hour::resources::v1::head_swap::CreateRequest {\n        assets: magic_hour::models::V1HeadSwapCreateBodyAssets {\n            body_file_path: \"api-assets/id/1234.png\".to_string(),\n            head_file_path: \"api-assets/id/5678.png\".to_string(),\n        },\n        max_resolution: Some(1024),\n        name: Some(\"My Head Swap image\".to_string()),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/head-swap \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Head Swap image\",\n  \"max_resolution\": 1024,\n  \"assets\": {\n    \"body_file_path\": \"api-assets/id/1234.png\",\n    \"head_file_path\": \"api-assets/id/5678.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/head-swap\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Head Swap image',\n    'max_resolution' => 1024,\n    'assets' => [\n        'body_file_path' => 'api-assets/id/1234.png',\n        'head_file_path' => 'api-assets/id/5678.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/head-swap\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Head Swap image\\\",\\\"max_resolution\\\":1024,\\\"assets\\\":{\\\"body_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"head_file_path\\\":\\\"api-assets/id/5678.png\\\"}}\")\n  .asString();"}]}},"/v1/image-background-remover":{"post":{"description":"Remove background from image. Each image costs 5 credits.","summary":"Image Background Remover","tags":["Image Projects"],"parameters":[],"operationId":"imageBackgroundRemover.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Background Remover image","default":"Background Remover - dateTime"},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","description":"The image to remove the background. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"},"background_image_file_path":{"type":"string","description":"The image used as the new background for the image_file_path. This image will be resized to match the image in image_file_path. Please make sure the resolution between the images are similar.\n\nThis value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for background removal"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":5,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":5}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.image_background_remover.generate(\n    assets={\n        \"background_image_file_path\": \"/path/to/1234.png\",\n        \"image_file_path\": \"/path/to/1234.png\",\n    },\n    name=\"Background Remover image\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.imageBackgroundRemover.generate(\n  {\n    assets: {\n      backgroundImageFilePath: \"/path/to/1234.png\",\n      imageFilePath: \"/path/to/1234.png\",\n    },\n    name: \"Background Remover image\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\timage_background_remover \"github.com/magichourhq/magic-hour-go/resources/v1/image_background_remover\"\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.ImageBackgroundRemover.Create(image_background_remover.CreateRequest{\n\t\tAssets: types.V1ImageBackgroundRemoverCreateBodyAssets{\n\t\t\tBackgroundImageFilePath: nullable.NewValue(\"api-assets/id/1234.png\"),\n\t\t\tImageFilePath:           \"api-assets/id/1234.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Background Remover image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .image_background_remover()\n    .create(magic_hour::resources::v1::image_background_remover::CreateRequest {\n        assets: magic_hour::models::V1ImageBackgroundRemoverCreateBodyAssets {\n            background_image_file_path: Some(\"api-assets/id/1234.png\".to_string()),\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Background Remover image\".to_string()),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/image-background-remover \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Background Remover image\",\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\",\n    \"background_image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/image-background-remover\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Background Remover image',\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png',\n        'background_image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/image-background-remover\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Background Remover image\\\",\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\",\\\"background_image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/photo-colorizer":{"post":{"description":"Colorize image. Each image costs 10 credits.","summary":"Photo Colorizer","tags":["Image Projects"],"parameters":[],"operationId":"photoColorizer.createImage","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your image a custom name for easy identification.","example":"My Photo Colorizer image","default":"Photo Colorizer - dateTime"},"assets":{"type":"object","properties":{"image_file_path":{"type":"string","minLength":1,"description":"The image used to generate the colorized image. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.png"}},"required":["image_file_path"],"description":"Provide the assets for photo colorization"}},"required":["assets"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the image. Use it with the [Get image Project API](https://docs.magichour.ai/api-reference/image-projects/get-image-details) to fetch status and downloads."},"frame_cost":{"type":"integer","description":"Deprecated: Previously represented the number of frames (original name of our credit system) used for image generation. Use 'credits_charged' instead.","example":10,"deprecated":true},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the image. We charge credits right when the request is made. \n\nIf an error occurred while generating the image(s), credits will be refunded and this field will be updated to include the refund.","example":10}},"required":["id","frame_cost","credits_charged"],"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":"Unable to create image"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.photo_colorizer.generate(\n    assets={\"image_file_path\": \"/path/to/1234.png\"}, name=\"Photo Colorizer image\"\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.photoColorizer.generate(\n  {\n    assets: { imageFilePath: \"/path/to/1234.png\" },\n    name: \"Photo Colorizer image\",\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tphoto_colorizer \"github.com/magichourhq/magic-hour-go/resources/v1/photo_colorizer\"\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.PhotoColorizer.Create(photo_colorizer.CreateRequest{\n\t\tAssets: types.V1PhotoColorizerCreateBodyAssets{\n\t\t\tImageFilePath: \"api-assets/id/1234.png\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Photo Colorizer image\"),\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .photo_colorizer()\n    .create(magic_hour::resources::v1::photo_colorizer::CreateRequest {\n        assets: magic_hour::models::V1PhotoColorizerCreateBodyAssets {\n            image_file_path: \"api-assets/id/1234.png\".to_string(),\n        },\n        name: Some(\"My Photo Colorizer image\".to_string()),\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/photo-colorizer \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Photo Colorizer image\",\n  \"assets\": {\n    \"image_file_path\": \"api-assets/id/1234.png\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/photo-colorizer\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Photo Colorizer image',\n    'assets' => [\n        'image_file_path' => 'api-assets/id/1234.png'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/photo-colorizer\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Photo Colorizer image\\\",\\\"assets\\\":{\\\"image_file_path\\\":\\\"api-assets/id/1234.png\\\"}}\")\n  .asString();"}]}},"/v1/audio-projects/{id}":{"get":{"description":"Check the progress of a audio project. The `downloads` field is populated after a successful render.\n  \n**Statuses**\n- `queued` — waiting to start\n- `rendering` — in progress\n- `complete` — ready; see `downloads`\n- `error` — a failure occurred (see `error`)\n- `canceled` — user canceled\n- `draft` — not used","summary":"Get audio details","tags":["Audio Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the audio project. This value is returned by all of the POST APIs that create an audio."}],"operationId":"audioProjects.getDetails","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the audio. Use it with the [Get audio Project API](https://docs.magichour.ai/api-reference/audio-projects/get-audio-details) to fetch status and downloads."},"name":{"type":"string","nullable":true,"description":"The name of the audio.","example":"Example Name"},"status":{"type":"string","enum":["draft","queued","rendering","complete","error","canceled"],"description":"The status of the audio.","example":"complete"},"type":{"type":"string","description":"The type of the audio project. Possible values are VOICE_GENERATOR, VOICE_CHANGER, VOICE_CLONER, VIDEO_TO_AUDIO","example":"VOICE_GENERATOR"},"created_at":{"type":"string","format":"date-time"},"enabled":{"type":"boolean","description":"Whether this resource is active. If false, it is deleted."},"credits_charged":{"type":"integer","example":2,"description":"The amount of credits deducted from your account to generate the audio. We charge credits right when the request is made. \n\nIf an error occurred while generating the audio, credits will be refunded and this field will be updated to include the refund."},"downloads":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://videos.magichour.ai/id/output.wav"},"expires_at":{"type":"string","format":"date-time","example":"2024-10-19T05:16:19.027Z"}},"required":["url","expires_at"],"description":"The download url and expiration date of the audio project"}},"error":{"type":"object","properties":{"message":{"type":"string","description":"Details on the reason why a failure happened.","example":"Please use an image with a detectable face"},"code":{"type":"string","example":"no_source_face","description":"An error code to indicate why a failure happened."}},"required":["message","code"],"nullable":true,"description":"In the case of an error, this object will contain the error encountered during video render","example":null}},"required":["id","name","status","type","created_at","enabled","credits_charged","downloads","error"],"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"}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.audio_projects.get(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.audioProjects.get({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\taudio_projects \"github.com/magichourhq/magic-hour-go/resources/v1/audio_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\tres, err := client.V1.AudioProjects.Get(audio_projects.GetRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .audio_projects()\n    .get(magic_hour::resources::v1::audio_projects::GetRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request GET \\\n     --url https://api.magichour.ai/v1/audio-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/audio-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"GET\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.get(\"https://api.magichour.ai/v1/audio-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]},"delete":{"description":"Permanently delete the rendered audio file(s). This action is not reversible, please be sure before deleting.","summary":"Delete audio","tags":["Audio Projects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cuid-example"},"description":"Unique ID of the audio project. This value is returned by all of the POST APIs that create an audio."}],"operationId":"audioProjects.delete","responses":{"204":{"description":"204"},"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"}}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.audio_projects.delete(id=\"cuid-example\")"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.audioProjects.delete({ id: \"cuid-example\" });"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\taudio_projects \"github.com/magichourhq/magic-hour-go/resources/v1/audio_projects\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\tsdk.WithBearerAuth(os.Getenv(\"API_TOKEN\")),\n\t)\n\terr := client.V1.AudioProjects.Delete(audio_projects.DeleteRequest{\n\t\tId: \"cuid-example\",\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .audio_projects()\n    .delete(magic_hour::resources::v1::audio_projects::DeleteRequest {\n        id: \"cuid-example\".to_string(),\n    })\n    .await;"},{"lang":"curl","source":"curl --request DELETE \\\n     --url https://api.magichour.ai/v1/audio-projects/id \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/audio-projects/id\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"DELETE\",\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.delete(\"https://api.magichour.ai/v1/audio-projects/id\")\n  .header(\"accept\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .asString();"}]}},"/v1/ai-voice-generator":{"post":{"description":"Generate speech from text. Each character costs 0.05 credits. The cost is rounded up to the nearest whole number.","summary":"AI Voice Generator","tags":["Audio Projects"],"parameters":[],"operationId":"aiVoiceGenerator.createAudio","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your audio a custom name for easy identification.","example":"My Voice Generator audio","default":"Voice Generator - dateTime"},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"Text used to generate speech. The character limit is 1000 characters.","example":"Hello, how are you?"},"voice_name":{"type":"string","enum":["Elon Musk","Mark Zuckerberg","Joe Rogan","Barack Obama","Morgan Freeman","Kanye West","Donald Trump","Joe Biden","Kim Kardashian","Taylor Swift","James Earl Jones","Samuel L. Jackson","Jeff Goldblum","David Attenborough","Sean Connery","Cillian Murphy","Anne Hathaway","Julia Roberts","Natalie Portman","Steve Carell","Amy Poehler","Stephen Colbert","Jimmy Fallon","David Letterman","Alex Trebek","Katy Perry","Prince","Kevin Bacon","Tom Hiddleston","Adam Driver","Alan Rickman","Alexz Johnson","Ana Gasteyer","Andrew Rannells","Arden Cho","Bear Grylls","Ben McKenzie","Ben Stiller","Ben Whishaw","Billie Joe Armstrong","Bingbing Li","Booboo Stewart","Bradley Steven Perry","Bruno Mars","Caity Lotz","Cameron Boyce","Candice Accola","Carrie Underwood","Casey Affleck","Caterina Scorsone","Cedric the Entertainer","Chace Crawford","Chadwick Boseman","Charlie Day","Chris Hemsworth","Chris Martin","Christopher Mintz-Plasse","Dan Fogler","Dan Stevens","Daniel Dae Kim","Danielle Panabaker","Dave Bautista","David Schwimmer","Denis Leary","Derek Mears","Diego Luna","Donald Glover","Donnie Yen","Doutzen Kroes","Dove Cameron","Dr. Dre","Drake Bell","Elle Fanning","Ernie Hudson","Fergie","Forest Whitaker","Francia Raisa","Freddie Highmore","Gillian Jacobs","Gina Carano","Ginnifer Goodwin","Gordon Ramsay","Guy Pearce","Gwendoline Christie","Hailee Steinfeld","Howie Mandel","Hugh Jackman","Hugh Laurie","J. K. Simmons","Jack Black","Jared Leto","Jennifer Carpenter","Kesha","Kris Jenner","Kristen Bell","Lorde","Matt Smith","Marilyn Monroe","Charlie Chaplin","Albert Einstein","Abraham Lincoln","John F. Kennedy","Lucille Ball","A.R. Rahman","Aamir Khan","Ajay Devgn","Akshay Kumar","Alain Delon","Alan Alda","Alan Cumming","Amitabh Bachchan","Ang Lee","Ansel Elgort","Anthony Anderson","Anthony Mackie","Armie Hammer","Asa Butterfield","B.J. Novak","Barbara Eden","Betty White","Bill Nighy","Bill Pullman","Blake Shelton","Bonnie Wright","Brad Paisley","Brendan Gleeson","Brian Cox","Bruno Ganz","Burt Reynolds","Carrie Fisher","Charles Dance","Chiwetel Ejiofor","Chris Pine","Christina Hendricks","Christina Ricci","Cyndi Lauper","Dakota Fanning","Damian Lewis","Dan Aykroyd","Daniel Craig","David Oyelowo","David Tennant","Diane Keaton","Diane Kruger","Dick Van Dyke","Domhnall Gleeson","Dominic Cooper","Donald Sutherland","Drew Carey","Eartha Kitt","Eddie Izzard","Edward Asner","Eli Roth","Elisabeth Moss","Ellen Burstyn","Emile Hirsch","Ezra Miller","Felicity Jones","Fiona Shaw","Florence Henderson","Freida Pinto","Geena Davis","Gemma Arterton","Geri Halliwell","Glenn Close","Gloria Steinem","Greta Gerwig","Gugu Mbatha-Raw","Hans Zimmer","Harry Connick Jr.","Harvey Keitel","Helena Bonham Carter","Henry Cavill","Hilary Swank","Hugh Bonneville","Idina Menzel","Imelda Staunton","Ingrid Bergman","Irrfan Khan","Isla Fisher","Iwan Rheon","Jack Lemmon","Janet Jackson","Jason Bateman","Jason Segel","Jennifer Coolidge","Johnny Galecki","Jon Favreau","Joseph Gordon-Levitt","Josh Brolin","Josh Gad","Josh Groban","Julia Louis-Dreyfus","Kristen Stewart","Kristen Wiig","Rooney Mara","Caitriona Balfe","J.J. Abrams","Zoe Saldana"],"description":"The voice to use for the speech. Available voices: Elon Musk, Mark Zuckerberg, Joe Rogan, Barack Obama, Morgan Freeman, Kanye West, Donald Trump, Joe Biden, Kim Kardashian, Taylor Swift, James Earl Jones, Samuel L. Jackson, Jeff Goldblum, David Attenborough, Sean Connery, Cillian Murphy, Anne Hathaway, Julia Roberts, Natalie Portman, Steve Carell, Amy Poehler, Stephen Colbert, Jimmy Fallon, David Letterman, Alex Trebek, Katy Perry, Prince, Kevin Bacon, Tom Hiddleston, Adam Driver, Alan Rickman, Alexz Johnson, Ana Gasteyer, Andrew Rannells, Arden Cho, Bear Grylls, Ben McKenzie, Ben Stiller, Ben Whishaw, Billie Joe Armstrong, Bingbing Li, Booboo Stewart, Bradley Steven Perry, Bruno Mars, Caity Lotz, Cameron Boyce, Candice Accola, Carrie Underwood, Casey Affleck, Caterina Scorsone, Cedric the Entertainer, Chace Crawford, Chadwick Boseman, Charlie Day, Chris Hemsworth, Chris Martin, Christopher Mintz-Plasse, Dan Fogler, Dan Stevens, Daniel Dae Kim, Danielle Panabaker, Dave Bautista, David Schwimmer, Denis Leary, Derek Mears, Diego Luna, Donald Glover, Donnie Yen, Doutzen Kroes, Dove Cameron, Dr. Dre, Drake Bell, Elle Fanning, Ernie Hudson, Fergie, Forest Whitaker, Francia Raisa, Freddie Highmore, Gillian Jacobs, Gina Carano, Ginnifer Goodwin, Gordon Ramsay, Guy Pearce, Gwendoline Christie, Hailee Steinfeld, Howie Mandel, Hugh Jackman, Hugh Laurie, J. K. Simmons, Jack Black, Jared Leto, Jennifer Carpenter, Kesha, Kris Jenner, Kristen Bell, Lorde, Matt Smith, Marilyn Monroe, Charlie Chaplin, Albert Einstein, Abraham Lincoln, John F. Kennedy, Lucille Ball, A.R. Rahman, Aamir Khan, Ajay Devgn, Akshay Kumar, Alain Delon, Alan Alda, Alan Cumming, Amitabh Bachchan, Ang Lee, Ansel Elgort, Anthony Anderson, Anthony Mackie, Armie Hammer, Asa Butterfield, B.J. Novak, Barbara Eden, Betty White, Bill Nighy, Bill Pullman, Blake Shelton, Bonnie Wright, Brad Paisley, Brendan Gleeson, Brian Cox, Bruno Ganz, Burt Reynolds, Carrie Fisher, Charles Dance, Chiwetel Ejiofor, Chris Pine, Christina Hendricks, Christina Ricci, Cyndi Lauper, Dakota Fanning, Damian Lewis, Dan Aykroyd, Daniel Craig, David Oyelowo, David Tennant, Diane Keaton, Diane Kruger, Dick Van Dyke, Domhnall Gleeson, Dominic Cooper, Donald Sutherland, Drew Carey, Eartha Kitt, Eddie Izzard, Edward Asner, Eli Roth, Elisabeth Moss, Ellen Burstyn, Emile Hirsch, Ezra Miller, Felicity Jones, Fiona Shaw, Florence Henderson, Freida Pinto, Geena Davis, Gemma Arterton, Geri Halliwell, Glenn Close, Gloria Steinem, Greta Gerwig, Gugu Mbatha-Raw, Hans Zimmer, Harry Connick Jr., Harvey Keitel, Helena Bonham Carter, Henry Cavill, Hilary Swank, Hugh Bonneville, Idina Menzel, Imelda Staunton, Ingrid Bergman, Irrfan Khan, Isla Fisher, Iwan Rheon, Jack Lemmon, Janet Jackson, Jason Bateman, Jason Segel, Jennifer Coolidge, Johnny Galecki, Jon Favreau, Joseph Gordon-Levitt, Josh Brolin, Josh Gad, Josh Groban, Julia Louis-Dreyfus, Kristen Stewart, Kristen Wiig, Rooney Mara, Caitriona Balfe, J.J. Abrams, Zoe Saldana","example":"Elon Musk"}},"required":["prompt","voice_name"],"description":"The content used to generate speech.","example":{"prompt":"Hello, how are you?","voice_name":"Elon Musk"}}},"required":["style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the audio. Use it with the [Get audio Project API](https://docs.magichour.ai/api-reference/audio-projects/get-audio-details) to fetch status and downloads."},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the audio. We charge credits right when the request is made. \n\nIf an error occurred while generating the audio, credits will be refunded and this field will be updated to include the refund.","example":1}},"required":["id","credits_charged"],"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":"Unable to generate speech"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_voice_generator.generate(\n    style={\"prompt\": \"Hello, how are you?\", \"voice_name\": \"Elon Musk\"},\n    name=\"Voice Generator audio\",\n    wait_for_completion=True,\n    download_outputs=True,\n    download_directory=\".\"\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiVoiceGenerator.generate(\n  {\n    name: \"Voice Generator audio\",\n    style: { prompt: \"Hello, how are you?\", voiceName: \"Elon Musk\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_voice_generator \"github.com/magichourhq/magic-hour-go/resources/v1/ai_voice_generator\"\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.AiVoiceGenerator.Create(ai_voice_generator.CreateRequest{\n\t\tName: nullable.NewValue(\"My Voice Generator audio\"),\n\t\tStyle: types.V1AiVoiceGeneratorCreateBodyStyle{\n\t\t\tPrompt:    \"Hello, how are you?\",\n\t\t\tVoiceName: types.V1AiVoiceGeneratorCreateBodyStyleVoiceNameEnumElonMusk,\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_voice_generator()\n    .create(magic_hour::resources::v1::ai_voice_generator::CreateRequest {\n        name: Some(\"My Voice Generator audio\".to_string()),\n        style: magic_hour::models::V1AiVoiceGeneratorCreateBodyStyle {\n            prompt: \"Hello, how are you?\".to_string(),\n            voice_name: magic_hour::models::V1AiVoiceGeneratorCreateBodyStyleVoiceNameEnum::ElonMusk,\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-voice-generator \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Voice Generator audio\",\n  \"style\": {\n    \"prompt\": \"Hello, how are you?\",\n    \"voice_name\": \"Elon Musk\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-voice-generator\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Voice Generator audio',\n    'style' => [\n        'prompt' => 'Hello, how are you?',\n        'voice_name' => 'Elon Musk'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-voice-generator\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Voice Generator audio\\\",\\\"style\\\":{\\\"prompt\\\":\\\"Hello, how are you?\\\",\\\"voice_name\\\":\\\"Elon Musk\\\"}}\")\n  .asString();"}]}},"/v1/ai-voice-cloner":{"post":{"description":"Clone a voice from an audio sample and generate speech. \n* Each character costs 0.05 credits. \n* The cost is rounded up to the nearest whole number","summary":"AI Voice Cloner","tags":["Audio Projects"],"parameters":[],"operationId":"aiVoiceCloner.createAudio","requestBody":{"required":true,"description":"Body","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Give your audio a custom name for easy identification.","example":"My Voice Cloner audio","default":"Voice Cloner - dateTime"},"assets":{"type":"object","properties":{"audio_file_path":{"type":"string","minLength":1,"description":"The audio used to clone the voice. This value is either\n- a direct URL to the video file\n- `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls).\n\nSee the [file upload guide](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) for details.\n","example":"api-assets/id/1234.mp3"}},"required":["audio_file_path"],"description":"Provide the assets for voice cloning."},"style":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":1000,"description":"Text used to generate speech from the cloned voice. The character limit is 1000 characters.","example":"Hello, this is my cloned voice."}},"required":["prompt"]}},"required":["assets","style"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cuid-example","description":"Unique ID of the audio. Use it with the [Get audio Project API](https://docs.magichour.ai/api-reference/audio-projects/get-audio-details) to fetch status and downloads."},"credits_charged":{"type":"integer","description":"The amount of credits deducted from your account to generate the audio. We charge credits right when the request is made. \n\nIf an error occurred while generating the audio, credits will be refunded and this field will be updated to include the refund.","example":1}},"required":["id","credits_charged"],"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":"Unable to clone voice"}},"required":["message"],"description":"Unprocessable Entity"}}}}},"security":[{"bearerAuth":[]}],"x-codeSamples":[{"lang":"python","source":"from magic_hour import Client\nfrom os import getenv\n\nclient = Client(token=getenv(\"API_TOKEN\"))\nres = client.v1.ai_voice_cloner.create(\n    assets={\"audio_file_path\": \"api-assets/id/1234.mp3\"},\n    style={\"prompt\": \"Hello, this is my cloned voice.\"},\n    name=\"My Voice Cloner audio\",\n)"},{"lang":"javascript","source":"import { Client } from \"magic-hour\";\n\nconst client = new Client({ token: process.env[\"API_TOKEN\"]!! });\nconst res = await client.v1.aiVoiceCloner.generate(\n  {\n    assets: { audioFilePath: \"/path/to/audio.mp3\" },\n    name: \"Voice Cloner audio\",\n    style: { prompt: \"Hello, this is my cloned voice.\" },\n  },\n  {\n    waitForCompletion: true,\n    downloadOutputs: true,\n    downloadDirectory: \".\",\n  },\n);"},{"lang":"go","source":"package main\n\nimport (\n\tos \"os\"\n\n\tsdk \"github.com/magichourhq/magic-hour-go/client\"\n\tnullable \"github.com/magichourhq/magic-hour-go/nullable\"\n\tai_voice_cloner \"github.com/magichourhq/magic-hour-go/resources/v1/ai_voice_cloner\"\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.AiVoiceCloner.Create(ai_voice_cloner.CreateRequest{\n\t\tAssets: types.V1AiVoiceClonerCreateBodyAssets{\n\t\t\tAudioFilePath: \"api-assets/id/1234.mp3\",\n\t\t},\n\t\tName: nullable.NewValue(\"My Voice Cloner audio\"),\n\t\tStyle: types.V1AiVoiceClonerCreateBodyStyle{\n\t\t\tPrompt: \"Hello, this is my cloned voice.\",\n\t\t},\n\t})\n}"},{"lang":"rust","source":"let client = magic_hour::Client::default()\n    .with_bearer_auth(&std::env::var(\"API_TOKEN\").unwrap());\nlet res = client\n    .v1()\n    .ai_voice_cloner()\n    .create(magic_hour::resources::v1::ai_voice_cloner::CreateRequest {\n        assets: magic_hour::models::V1AiVoiceClonerCreateBodyAssets {\n            audio_file_path: \"api-assets/id/1234.mp3\".to_string(),\n        },\n        name: Some(\"My Voice Cloner audio\".to_string()),\n        style: magic_hour::models::V1AiVoiceClonerCreateBodyStyle {\n            prompt: \"Hello, this is my cloned voice.\".to_string(),\n        },\n    })\n    .await;"},{"lang":"curl","source":"curl --request POST \\\n     --url https://api.magichour.ai/v1/ai-voice-cloner \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer <token>' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"My Voice Cloner audio\",\n  \"assets\": {\n    \"audio_file_path\": \"api-assets/id/1234.mp3\"\n  },\n  \"style\": {\n    \"prompt\": \"Hello, this is my cloned voice.\"\n  }\n}\n'"},{"lang":"php","source":"<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n  CURLOPT_URL => \"https://api.magichour.ai/v1/ai-voice-cloner\",\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_ENCODING => \"\",\n  CURLOPT_MAXREDIRS => 10,\n  CURLOPT_TIMEOUT => 30,\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n  CURLOPT_CUSTOMREQUEST => \"POST\",\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'My Voice Cloner audio',\n    'assets' => [\n        'audio_file_path' => 'api-assets/id/1234.mp3'\n    ],\n    'style' => [\n        'prompt' => 'Hello, this is my cloned voice.'\n    ]\n  ]),\n  CURLOPT_HTTPHEADER => [\n    \"accept: application/json\",\n    \"authorization: Bearer <token>\",\n    \"content-type: application/json\"\n  ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n  echo \"cURL Error #:\" . $err;\n} else {\n  echo $response;\n}"},{"lang":"java","source":"HttpResponse<String> response = Unirest.post(\"https://api.magichour.ai/v1/ai-voice-cloner\")\n  .header(\"accept\", \"application/json\")\n  .header(\"content-type\", \"application/json\")\n  .header(\"authorization\", \"Bearer <token>\")\n  .body(\"{\\\"name\\\":\\\"My Voice Cloner audio\\\",\\\"assets\\\":{\\\"audio_file_path\\\":\\\"api-assets/id/1234.mp3\\\"},\\\"style\\\":{\\\"prompt\\\":\\\"Hello, this is my cloned voice.\\\"}}\")\n  .asString();"}]}}},"info":{"title":"Magic Hour API","version":"beta","description":"\nMagic Hour provides an API (beta) that can be integrated into your own application to generate videos and images using AI. \n\nWebhook documentation can be found [here](https://magichour.ai/docs/webhook).\n\nIf you have any questions, please reach out to us via [discord](https://discord.gg/JX5rgsZaJp).\n\n# Authentication\n\nEvery request requires an API key.\n\nTo get started, first generate your API key [here](https://magichour.ai/settings/developer).\n\nThen, add the `Authorization` header to the request.\n\n| Key | Value |\n|-|-|\n| Authorization | Bearer mhk_live_apikey |\n\n> **Warning**: any API call that renders a video will utilize credits in your account.\n","termsOfService":"https://magichour.ai/terms-of-service"},"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\"."}}},"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"}],"servers":[{"url":"https://api.magichour.ai"}]}