The Magic Hour Node SDK provides convenient access to the Magic Hour API via server-side TypeScript or JavaScript.
For full documentation of all APIs, please visit https://docs.magichour.ai
If you have any questions, please reach out to us via discord.
npm install magic-hour
import Client from "magic-hour";
// generate your API Key at https://magichour.ai/developer
const client = new Client({ token: process.env["API_TOKEN"]!! });
const res = await client.v1.faceSwapPhoto.generate(
{
assets: {
faceSwapMode: "all-faces",
sourceFilePath: "/path/to/source/image.png",
targetFilePath: "/path/to/target/image.png",
},
name: "Face Swap image",
},
{
waitForCompletion: true,
downloadOutputs: true,
downloadDirectory: "outputs",
},
);
console.log(`Project ID: ${response.id}`)
console.log(`Status: ${response.status}`)
console.log(`Downloaded files: ${response.downloaded_paths}`)
Most resources that generate media content support two methods:
generate()
- A high-level convenience method that handles the entire workflowcreate()
- A low-level method that only initiates the generation process
The generate()
function provides a complete end-to-end solution:
- Uploads local files to Magic Hour storage
- Calls the API to start generation
- Automatically polls for completion
- Downloads generated files to your local machine
- Returns both API response data and local file paths
Additional Parameters:
waitForCompletion
(boolean, default true): Whether to wait for the project to completedownloadOutputs
(boolean, default true): Whether to download the generated filesdownloadDirectory
(string, optional): Directory to save downloaded files (defaults to current directory)
const response = await client.v1.faceSwapPhoto.generate(
{
assets: {
faceSwapMode: "all-faces",
sourceFilePath: "/path/to/source/image.png",
targetFilePath: "/path/to/target/image.png",
},
name: "Face Swap image",
},
{
waitForCompletion: true, // Wait for status to be complete/error/canceled
downloadOutputs: true, // Download files automatically
downloadDirectory: "./outputs/" // Where to save files
}
);
// You get both the API response AND downloaded file paths
console.log(`Project ID: ${response.id}`);
console.log(`Status: ${response.status}`);
console.log(`Downloaded files: ${response.downloadedPaths}`);
The create()
function provides granular control:
- Only calls the API to start the generation process
- Returns immediately with a project ID and amount of credits used
- Requires manual status checking and file downloading
// upload the files to Magic Hour's storage or you can use direct URLs
const sourceFilePath = await client.v1.files.uploadFile("/path/to/source/image.png")
const targetFilePath = await client.v1.files.uploadFile("/path/to/target/image.png")
// Create function - only starts the process
const createResponse = await client.v1.faceSwapPhoto.create({
assets: {
faceSwapMode: "all-faces",
sourceFilePath: sourceFilePath,
targetFilePath: targetFilePath,
},
name: "Face Swap image"
});
// You get just the project ID and initial response
const projectId = createResponse.id;
console.log(`Started project: ${projectId}`);
// You must handle the rest:
// 1. Poll for completion using the image/video projects API
const result = await client.v1.imageProjects.checkResults(projectId, {
waitForCompletion: true,
downloadOutputs: false,
});
// 2. Download files using the download URLs
const downloadUrls = result.downloads;
// Download the files using your preferred method
Use generate()
when:
- You want a simple, one-call solution
- You're building a straightforward application
- You don't need custom polling or download logic
Use create()
when:
- You need custom status checking logic
- You're integrating with existing job processing systems
- You want to separate generation initiation from completion handling
- You need fine-grained control over the entire workflow
The Magic Hour SDK includes the ApiError
class, which includes the request and response data.
try {
await client.v1.imageToVideo.generate(
{
assets: {
imageFilePath: "/Users/dhu/Desktop/test-files/suit.jpg",
},
endSeconds: 0,
},
);
} catch (error) {
if (error instanceof ApiError) {
console.error(`API Error: ${error.message}`); // API Error: 400 was returned from post /v1/image-to-video
try {
const errorData = await error.response.json();
console.error(`Error Message: ${errorData.message}`); // Error Message: end_seconds must be at least 5
} catch (parseError) {
console.error("Could not parse error response");
}
} else {
console.error("Unexpected error:", error);
}
}
none
- Disable all loggingerror
- Only error messageswarn
- Warnings and errorsinfo
- Info, warnings, and errorsdebug
- All messages including request/response details
You can also configure the logging level using the MAGIC_HOUR_LOG_LEVEL
environment variable:
export MAGIC_HOUR_LOG_LEVEL=debug # Enable debug logging
# or
export MAGIC_HOUR_LOG_LEVEL=error # Only show errors
Valid values are: none
, error
, warn
, info
, debug
(case insensitive). If not set, defaults to info
.
- create - Face Detection
- generate - Face Detection Generate Workflow
- get - Get face detection details
- upload-file - Upload File
- create - Generate asset upload urls
- check-result - Check results
- delete - Delete image
- get - Get image details
- check-result - Check results
- delete - Delete video
- get - Get video details