Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.
Use two separate Windmill REST scripts: create an image once, then recover its saved
project ID. The example requests one 640px square flux-2-klein image, uses no SDK
or chat model, and downloads only the first PNG result, up to 8 MiB.
These actions use one Magic Hour account’s credits. Keep the secret variable,
resource, and scripts under a private user path. Anyone granted permission to
run creation with that resource can spend the account’s credits.
A worker must listen for the nativets tag to run these actions. If your hosted or
self-hosted instance already has one, keep its configuration.On a self-hosted Community Edition instance with only the default worker group,
open Workers → default → Edit config → Tags and add nativets. Preserve all
existing tags. Leave Native Mode off: these scripts do not require it.
In Variables, add your Magic Hour API key at a private user path such as
u/YOUR_USERNAME/magic_hour_api_key, with Secret enabled. Enter the raw API
key without a Bearer prefix.
In Resources, add the custom resource type magic_hour with this schema:
Use Windmill’s variable picker to select the existing secret. Do not paste the key
into resource JSON: resource history preserves inline values. Scripts receive the
resolved resource, while their saved input selects $res:u/YOUR_USERNAME/magic_hour.
Keep credentials, raw job arguments, and temporary download URLs out of shared
exports, screenshots, and logs.
Create two scripts through Windmill’s native REST editor. Paste the creation script
and recovery script into separate scripts under your private user path. Keep
their //native header. They use the current BunNative builder; the normal worker
must complete its native dependency/bundle job before the script is ready.The companion .script.json files describe the input forms and execution settings
for an existing Windmill CLI workspace. Copy each .bun.ts file and matching
.script.json beside one another under your own u/<username>/ path. Let Windmill
produce its lock through native deployment; no generated lock is supplied here.Use normal one-off scripts: no dedicated worker, perpetual restart, result cache,
retry, or configured additional triggers, schedules, or handlers. Windmill’s
built-in authenticated webhook, email, and CLI routes still exist. On a self-hosted
instance, ensure its operator has disabled automatic zombie-job restarts with
RESTART_ZOMBIE_JOBS=false; this is not an exactly-once guarantee. Keep normal
login, TLS verification, and instance security settings enabled.
Open the creation script and select your private magic_hour resource.
Review prompt, then run the action once. The prompt is sent to Magic Hour.
This is a billable request.
Save its returned id and credits_charged before doing anything else.
Only creation submits a billable Magic Hour generation. It returns the accepted
project ID and actual charge immediately, without polling, downloading media, or
submitting another creation. A failed or timed-out run may
have been accepted by Magic Hour: if no ID returned, confirm the request status
before resubmitting. If you have an accepted ID, recover that project.
Select the same private resource and enter the accepted project_id.
Run it once. GET recovery does not create an image or submit a new paid generation.
While the project is queued or rendering, it returns the ID, provider status,
and actual charge/refund values, preserving zero and an absent refund field. It also
returns provider error or canceled status with any actual error details, preserving
a missing error field separately from null, without creating a replacement.
Check the same ID again later when appropriate; there is no automatic polling.Once complete, the action makes a separate HTTPS media request without an API key
or redirects. It rejects non-200 responses, downloads over 8 MiB, and non-PNG
content. Its result contains a base64-encoded file with the filename
magic-hour-<project-id>.png. The completed-file result does not include a signed
URL or repeat the metadata object.For large results, the Run page may show Download as JSON instead of a PNG
button. Windmill’s job metadata can return WINDMILL_TOO_BIG; use its documented
GET /api/w/<workspace>/jobs_u/completed/get_result/<job-id> endpoint with normal
Windmill authentication to retrieve the full result JSON. Save it as result.json,
then decode it with Python’s standard library:
The script runs in Windmill’s editor; this full-result API download is a separate
supported output-recovery step, not a guaranteed native PNG button.If a download expires or fails, run recovery again with the same ID. Do not run
creation to recover a file. Never attach these scripts to automatic retry or
restart logic around the paid request.
Windmill Community Edition 1.848.2 ran both scripts through its native editor.
The tested setup stored the API key in a native secret variable and selected the
private resource through a saved $res reference. A manual creation returned one
accepted image ID and an actual charge of 5 Magic Hour credits. A separate native
recovery run used that same ID and returned the completed PNG.Windmill’s documented completed-result API retrieved the 353,212-byte, 640×640 PNG;
it passed a full image decode. The large job metadata returned WINDMILL_TOO_BIG,
so this proves editor execution plus native product API output recovery, rather
than a GUI PNG download click. No chat model or Magic Hour SDK was used.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Magic Hour API Docs","description":"Easily generate videos, images, and audio using Magic Hour's API. Follow our documentation to seamlessly integrate AI content creation into your applications.","colors":{"primary":"#3b82f6","light":"#0564ff","dark":"#3b82f6"},"logo":{"light":"https://mintcdn.com/magichour/5sgGJpuuipkw5s5v/icons/logo-light.svg?fit=max\u0026auto=format\u0026n=5sgGJpuuipkw5s5v\u0026q=85\u0026s=1f167e30baf11927bc2e0932411e455b","dark":"https://mintcdn.com/magichour/5sgGJpuuipkw5s5v/icons/logo-dark.svg?fit=max\u0026auto=format\u0026n=5sgGJpuuipkw5s5v\u0026q=85\u0026s=15c8bda28931ac4e1e2fab2c0ba6f0d5"},"favicon":"https://mintcdn.com/magichour/kbUwXh9ksnVyRSci/icons/favicon.png?fit=max\u0026auto=format\u0026n=kbUwXh9ksnVyRSci\u0026q=85\u0026s=c4fda903b24dd7067dadd1bb75508987","appearance":{"default":"dark","strict":false},"background":{"decoration":"gradient"},"navbar":{"links":[{"href":"mailto:support@magichour.ai","label":"Support"}],"primary":{"type":"button","label":"Get API key","href":"https://magichour.ai/developer?tab=api-keys\u0026ref=docs-navbar\u0026utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=navbar"}},"footer":{"socials":{"website":"https://magichour.ai/?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=footer","x":"https://x.com/magichourai","github":"https://github.com/magichourhq","linkedin":"https://linkedin.com/company/magichour","instagram":"https://instagram.com/magichourai","youtube":"https://youtube.com/@magichourai"}},"seo":{"metatags":{"og:image":"https://d28dkohlqf5vwj.cloudfront.net/open-graph/logo-social-noisy-spectrum.jpg","twitter:image":"https://d28dkohlqf5vwj.cloudfront.net/open-graph/logo-social-noisy-spectrum.jpg"}},"integrations":{"ga4":{"measurementId":"G-CZ9Q9NBZB3"},"posthog":{"apiKey":"phc_EmzSy2RU0TOPhpouazMzxFedNdMyhze8HakyjffW2Wr","apiHost":"https://us.i.posthog.com"}},"contextual":{"options":["chatgpt","claude","perplexity","mcp","cursor","vscode","copy","view"],"display":"header"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"API quickstart","icon":"forward-fast","href":"/get-started/quick-start"},{"anchor":"API pricing","icon":"credit-card","href":"/billing/overview"},{"anchor":"Community","icon":"discord","href":"https://discord.com/invite/JX5rgsZaJp"},{"anchor":"Status","icon":"wave-pulse","href":"https://status.magichour.ai"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"magichour","hasAudioNarration":false,"actualSubdomain":"magichour","customDomains":["docs.magichour.ai"],"gitSource":{"type":"github","owner":"magichourhq","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6adc9a016db7bf41f81e7b6f","collectionId":"c2a21452-9870-4805-bf84-8fdeaf505524","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adc9a016db7bf41f81e7b6f"},"feedback":{"thumbs":true,"issues":true,"edits":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6adca0c43e0e90aa2af8d93c","clientVersion":"0.0.3964","searchFilterCounts":[{"language":"default","tag":"Documentation","count":82},{"language":"default","tag":"API Reference","count":42},{"language":"default","tag":"Integration","count":41},{"language":"default","tag":"Tools","count":30},{"language":"default","tag":"Image Projects","count":16},{"language":"default","tag":"Images","count":15},{"language":"default","tag":"Video Projects","count":14},{"language":"default","tag":"Video","count":12},{"language":"default","tag":"Webhook Reference","count":10},{"language":"default","tag":"Get Started","count":7}]},"assistantConfig":{},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"#sidebar,#table-of-contents-content{scrollbar-width:thin;scrollbar-gutter:none;scrollbar-color:gray transparent}"}],"page":{"pagePath":"integration/windmill","slug":"/integration/windmill","pageMetadata":{"title":"Windmill","description":"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.","href":"/integration/windmill"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,img:`img`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Use two separate Windmill REST scripts: create an image once, then recover its saved\nproject ID. The example requests one 640px square `,_jsx(_components.code,{children:`flux-2-klein`}),` image, uses no SDK\nor chat model, and downloads only the first PNG result, up to 8 MiB.`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`These actions use one Magic Hour account’s credits. Keep the secret variable,\nresource, and scripts under a private user path. Anyone granted permission to\nrun creation with that resource can spend the account’s credits.`})}),`\n`,_jsx(Heading,{level:`2`,id:`check-worker-tags`,children:`Check worker tags`}),`\n`,_jsxs(_components.p,{children:[`A worker must listen for the `,_jsx(_components.code,{children:`nativets`}),` tag to run these actions. If your hosted or\nself-hosted instance already has one, keep its configuration.`]}),`\n`,_jsxs(_components.p,{children:[`On a self-hosted Community Edition instance with only the default worker group,\nopen `,_jsx(_components.strong,{children:`Workers → default → Edit config → Tags`}),` and add `,_jsx(_components.code,{children:`nativets`}),`. Preserve all\nexisting tags. Leave `,_jsx(_components.strong,{children:`Native Mode`}),` off: these scripts do not require it.`]}),`\n`,_jsx(Heading,{level:`2`,id:`store-the-api-key-as-a-secret-reference`,children:`Store the API key as a secret reference`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.strong,{children:`Variables`}),`, add your Magic Hour API key at a private user path such as\n`,_jsx(_components.code,{children:`u/YOUR_USERNAME/magic_hour_api_key`}),`, with `,_jsx(_components.strong,{children:`Secret`}),` enabled. Enter the raw API\nkey without a `,_jsx(_components.code,{children:`Bearer `}),` prefix.`]}),`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.strong,{children:`Resources`}),`, add the custom resource type `,_jsx(_components.code,{children:`magic_hour`}),` with this schema:`]}),`\n`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"object\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"properties\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"api_key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"string\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"required\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"api_key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.ol,{start:`3`,children:[`\n`,_jsxs(_components.li,{children:[`Add a private resource of that type, such as `,_jsx(_components.code,{children:`u/YOUR_USERNAME/magic_hour`}),`, whose\nvalue references the secret variable:`]}),`\n`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"api_key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"$var:u/YOUR_USERNAME/magic_hour_api_key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Use Windmill’s variable picker to select the existing secret. Do not paste the key\ninto resource JSON: resource history preserves inline values. Scripts receive the\nresolved resource, while their saved input selects `,_jsx(_components.code,{children:`$res:u/YOUR_USERNAME/magic_hour`}),`.\nKeep credentials, raw job arguments, and temporary download URLs out of shared\nexports, screenshots, and logs.`]}),`\n`,_jsx(Heading,{level:`2`,id:`add-the-separate-actions`,children:`Add the separate actions`}),`\n`,_jsx(_components.p,{children:`Download the scripts and companion metadata:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://raw.githubusercontent.com/magichourhq/docs/main/examples/windmill/create-image.bun.ts`,children:`Creation script`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://raw.githubusercontent.com/magichourhq/docs/main/examples/windmill/create-image.script.json`,children:`Creation metadata`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://raw.githubusercontent.com/magichourhq/docs/main/examples/windmill/recover-image.bun.ts`,children:`Recovery script`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://raw.githubusercontent.com/magichourhq/docs/main/examples/windmill/recover-image.script.json`,children:`Recovery metadata`})}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Create two scripts through Windmill’s native REST editor. Paste the creation script\nand recovery script into separate scripts under your private user path. Keep\ntheir `,_jsx(_components.code,{children:`//native`}),` header. They use the current BunNative builder; the normal worker\nmust complete its native dependency/bundle job before the script is ready.`]}),`\n`,_jsxs(_components.p,{children:[`The companion `,_jsx(_components.code,{children:`.script.json`}),` files describe the input forms and execution settings\nfor an existing Windmill CLI workspace. Copy each `,_jsx(_components.code,{children:`.bun.ts`}),` file and matching\n`,_jsx(_components.code,{children:`.script.json`}),` beside one another under your own `,_jsx(_components.code,{children:`u/\u003cusername>/`}),` path. Let Windmill\nproduce its lock through native deployment; no generated lock is supplied here.`]}),`\n`,_jsxs(_components.p,{children:[`Use normal one-off scripts: no dedicated worker, perpetual restart, result cache,\nretry, or configured additional triggers, schedules, or handlers. Windmill’s\nbuilt-in authenticated webhook, email, and CLI routes still exist. On a self-hosted\ninstance, ensure its operator has disabled automatic zombie-job restarts with\n`,_jsx(_components.code,{children:`RESTART_ZOMBIE_JOBS=false`}),`; this is not an exactly-once guarantee. Keep normal\nlogin, TLS verification, and instance security settings enabled.`]}),`\n`,_jsx(Heading,{level:`2`,id:`create-once-and-save-the-id`,children:`Create once and save the ID`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Open the creation script and select your private `,_jsx(_components.strong,{children:`magic_hour`}),` resource.`]}),`\n`,_jsxs(_components.li,{children:[`Review `,_jsx(_components.strong,{children:`prompt`}),`, then run the action once. The prompt is sent to Magic Hour.\nThis is a billable request.`]}),`\n`,_jsxs(_components.li,{children:[`Save its returned `,_jsx(_components.strong,{children:`id`}),` and `,_jsx(_components.strong,{children:`credits_charged`}),` before doing anything else.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Only creation submits a billable Magic Hour generation. It returns the accepted\nproject ID and actual charge immediately, without polling, downloading media, or\nsubmitting another creation. A failed or timed-out run may\nhave been accepted by Magic Hour: if no ID returned, confirm the request status\nbefore resubmitting. If you have an accepted ID, recover that project.`}),`\n`,_jsx(Heading,{level:`2`,id:`recover-and-download`,children:`Recover and download`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Open the separate recovery script.`}),`\n`,_jsxs(_components.li,{children:[`Select the same private resource and enter the accepted `,_jsx(_components.strong,{children:`project_id`}),`.`]}),`\n`,_jsx(_components.li,{children:`Run it once. GET recovery does not create an image or submit a new paid generation.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`While the project is `,_jsx(_components.code,{children:`queued`}),` or `,_jsx(_components.code,{children:`rendering`}),`, it returns the ID, provider status,\nand actual charge/refund values, preserving zero and an absent refund field. It also\nreturns provider `,_jsx(_components.code,{children:`error`}),` or `,_jsx(_components.code,{children:`canceled`}),` status with any actual error details, preserving\na missing error field separately from `,_jsx(_components.code,{children:`null`}),`, without creating a replacement.\nCheck the same ID again later when appropriate; there is no automatic polling.`]}),`\n`,_jsxs(_components.p,{children:[`Once complete, the action makes a separate HTTPS media request without an API key\nor redirects. It rejects non-200 responses, downloads over 8 MiB, and non-PNG\ncontent. Its result contains a base64-encoded file with the filename\n`,_jsx(_components.code,{children:`magic-hour-\u003cproject-id>.png`}),`. The completed-file result does not include a signed\nURL or repeat the metadata object.`]}),`\n`,_jsxs(_components.p,{children:[`For large results, the Run page may show `,_jsx(_components.strong,{children:`Download as JSON`}),` instead of a PNG\nbutton. Windmill’s job metadata can return `,_jsx(_components.code,{children:`WINDMILL_TOO_BIG`}),`; use its documented\n`,_jsx(_components.code,{children:`GET /api/w/\u003cworkspace>/jobs_u/completed/get_result/\u003cjob-id>`}),` endpoint with normal\nWindmill authentication to retrieve the full result JSON. Save it as `,_jsx(_components.code,{children:`result.json`}),`,\nthen decode it with Python’s standard library:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` base64`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` json`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` pathlib `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Path`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`file`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` json.loads(Path(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"result.json\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).read_text())[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`image `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` base64.b64decode(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`file`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"content\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`], `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`validate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`True`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Path(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`file`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"filename\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]).write_bytes(image)`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The script runs in Windmill’s editor; this full-result API download is a separate\nsupported output-recovery step, not a guaranteed native PNG button.`}),`\n`,_jsx(_components.p,{children:`If a download expires or fails, run recovery again with the same ID. Do not run\ncreation to recover a file. Never attach these scripts to automatic retry or\nrestart logic around the paid request.`}),`\n`,_jsx(Heading,{level:`2`,id:`verified-behavior`,children:`Verified behavior`}),`\n`,_jsxs(_components.p,{children:[`Windmill Community Edition 1.848.2 ran both scripts through its native editor.\nThe tested setup stored the API key in a native secret variable and selected the\nprivate resource through a saved `,_jsx(_components.code,{children:`$res`}),` reference. A manual creation returned one\naccepted image ID and an actual charge of 5 Magic Hour credits. A separate native\nrecovery run used that same ID and returned the completed PNG.`]}),`\n`,_jsxs(_components.p,{children:[`Windmill’s documented completed-result API retrieved the 353,212-byte, 640×640 PNG;\nit passed a full image decode. The large job metadata returned `,_jsx(_components.code,{children:`WINDMILL_TOO_BIG`}),`,\nso this proves editor execution plus native product API output recovery, rather\nthan a GUI PNG download click. No chat model or Magic Hour SDK was used.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.img,{src:`https://github.com/magichourhq/docs/releases/download/docs-render-proof-20261023/windmill-px623-output.png`,alt:`The 640×640 PNG created by the native Windmill action and recovered through Windmill's completed-result API`})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Windmill","description":"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.","href":"/integration/windmill"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Check worker tags","slug":"check-worker-tags","depth":2,"children":[]},{"title":"Store the API key as a secret reference","slug":"store-the-api-key-as-a-secret-reference","depth":2,"children":[]},{"title":"Add the separate actions","slug":"add-the-separate-actions","depth":2,"children":[]},{"title":"Create once and save the ID","slug":"create-once-and-save-the-id","depth":2,"children":[]},{"title":"Recover and download","slug":"recover-and-download","depth":2,"children":[]},{"title":"Verified behavior","slug":"verified-behavior","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"magichour","siteName":"Magic Hour API Docs","title":"Windmill - Magic Hour API Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-24T11:12:15.434Z","originalFileLocation":"integration/windmill.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Magic Hour API Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Windmill - Magic Hour API Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Magic Hour API Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.magichour.ai/integration/windmill\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://d28dkohlqf5vwj.cloudfront.net/open-graph/logo-social-noisy-spectrum.jpg\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Windmill - Magic Hour API Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://d28dkohlqf5vwj.cloudfront.net/open-graph/logo-social-noisy-spectrum.jpg\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/magichour/pV2W72GIHTaiOFzk/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Magic Hour API Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#3b82f6\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.magichour.ai/integration/windmill\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/integration/windmill.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.magichour.ai/#organization\",\"name\":\"Magic Hour API Docs\",\"url\":\"https://docs.magichour.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/magichour/5sgGJpuuipkw5s5v/icons/logo-light.svg?fit=max\u0026auto=format\u0026n=5sgGJpuuipkw5s5v\u0026q=85\u0026s=1f167e30baf11927bc2e0932411e455b\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.magichour.ai#website\",\"name\":\"Magic Hour API Docs\",\"url\":\"https://docs.magichour.ai\",\"publisher\":{\"@id\":\"https://docs.magichour.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.magichour.ai/integration/windmill#webpage\",\"url\":\"https://docs.magichour.ai/integration/windmill\",\"name\":\"Windmill\",\"description\":\"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\",\"dateModified\":\"2026-10-24T11:12:15.434Z\",\"isPartOf\":{\"@id\":\"https://docs.magichour.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.magichour.ai/integration/windmill#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.magichour.ai/integration/windmill#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Integration\",\"item\":\"https://docs.magichour.ai/integration/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Windmill\",\"item\":\"https://docs.magichour.ai/integration/windmill\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.magichour.ai/integration/windmill#article\",\"headline\":\"Windmill\",\"name\":\"Windmill\",\"description\":\"Create and recover Magic Hour images with separate native Windmill REST actions and an encrypted secret reference.\",\"url\":\"https://docs.magichour.ai/integration/windmill\",\"mainEntityOfPage\":{\"@id\":\"https://docs.magichour.ai/integration/windmill#webpage\"},\"image\":\"https://d28dkohlqf5vwj.cloudfront.net/open-graph/logo-social-noisy-spectrum.jpg\",\"dateModified\":\"2026-10-24T11:12:15.434Z\",\"publisher\":{\"@id\":\"https://docs.magichour.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.magichour.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Magic Hour API Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Magic Hour API Docs","nav":{"global":{"anchors":[{"anchor":"API quickstart","icon":"forward-fast","href":"/get-started/quick-start"},{"anchor":"API pricing","icon":"credit-card","href":"/billing/overview"},{"anchor":"Community","icon":"discord","href":"https://discord.com/invite/JX5rgsZaJp"},{"anchor":"Status","icon":"wave-pulse","href":"https://status.magichour.ai"}]},"tabs":[{"tab":"Documentation","pages":[{"group":"Get Started","pages":[{"title":"Magic Hour API Documentation","sidebarTitle":"Introduction","href":"/introduction"},{"title":"Magic Hour API Quickstart","sidebarTitle":"Quick Start","href":"/get-started/quick-start"},{"title":"Authentication","href":"/get-started/authentication"},{"title":"Magic Hour MCP","href":"/integration/model-context-protocol"},{"title":"API Cookbook - Google Colab","href":"/get-started/cookbook"},{"title":"Product Video and Lip-Sync Recipes","href":"/get-started/starter-recipes"},{"title":"Bulk Face Swap API: Safe Batch Processing","sidebarTitle":"Bulk Face Swap","href":"/get-started/bulk-face-swap"}]},{"group":"Integration","pages":[{"title":"Integration Overview","sidebarTitle":"Overview","href":"/integration/overview"},{"title":"Compare AI Media APIs on Your Workload","sidebarTitle":"Evaluate API Providers","href":"/integration/evaluating-media-apis"},{"title":"Choose a Commercial AI Media Workflow","sidebarTitle":"Choose a Workflow","href":"/integration/commercial-media-workflows"},{"title":"Evaluate Lip Sync for Agency and Localization Work","sidebarTitle":"Agency Lip-Sync Pilot","href":"/integration/agency-lip-sync"},{"title":"smolagents","href":"/integration/smolagents"},{"title":"Creating Your First Integration","sidebarTitle":"Creating Your First Integration","href":"/integration/first-integration"},{"title":"PydanticAI","href":"/integration/pydantic-ai"},{"title":"Vercel AI SDK","href":"/integration/vercel-ai-sdk"},{"title":"OpenAI Agents SDK","href":"/integration/openai-agents-sdk"},{"title":"Google ADK","href":"/integration/google-adk"},{"title":"Genkit","href":"/integration/genkit"},{"title":"DSPy","href":"/integration/dspy"},{"title":"VoltAgent","href":"/integration/voltagent"},{"title":"Strands Agents","href":"/integration/strands-agents"},{"title":"LlamaIndex","href":"/integration/llamaindex"},{"title":"Spring AI","href":"/integration/spring-ai"},{"title":"Open WebUI","href":"/integration/open-webui"},{"title":"Node-RED","description":"Generate and recover Magic Hour images with Node-RED's built-in HTTP Request and file nodes.","href":"/integration/node-red"},{"title":"Windmill","href":"/integration/windmill"},{"title":"Prefect","description":"Recover an existing Magic Hour image project's status through a native Prefect flow and task without a language model.","href":"/integration/prefect"},{"title":"Dagster","href":"/integration/dagster"},{"title":"CrewAI","href":"/integration/crewai"},{"title":"Langflow","href":"/integration/langflow"},{"title":"Haystack","href":"/integration/haystack"},{"title":"Figma plugin","href":"/integration/figma"},{"title":"Framer plugin","href":"/integration/framer"},{"title":"Adobe Express add-on","href":"/integration/adobe-express"},{"title":"Canva app","href":"/integration/canva"},{"title":"Webflow extension","href":"/integration/webflow"},{"title":"Postman Collection","href":"/integration/postman"},{"title":"Adding API to Your App","href":"/integration/adding-api-to-your-app"},{"title":"Handling Inputs and Outputs","sidebarTitle":"Inputs \u0026 Outputs","href":"/integration/inputs-and-outputs"},{"title":"LangChain and LangGraph","href":"/integration/langchain"},{"title":"Mastra","href":"/integration/mastra"},{"title":"Development and Testing","href":"/integration/development-and-testing"},{"group":"Webhook","pages":[{"title":"Webhook Quickstart","sidebarTitle":"Quick Start","href":"/integration/webhook/overview"},{"title":"Create a Webhook","href":"/integration/webhook/create-webhook"},{"title":"Securing Your Webhook Handler","sidebarTitle":"Securing Handler","href":"/integration/webhook/secure-handler"},{"title":"Production Webhook Handler","sidebarTitle":"Production Setup","href":"/integration/webhook/create-handler"},{"title":"Webhook Event Types","sidebarTitle":"Event Types","href":"/integration/webhook/event-types"}]},{"title":"Postman Collection","href":"/integration/postman"},{"title":"API Docs MCP","href":"/integration/api-docs-mcp"}]},{"group":"Billing","pages":[{"title":"Magic Hour API Pricing","sidebarTitle":"Pricing Overview","href":"/billing/overview"},{"title":"Subscription Pricing","href":"/billing/subscription-pricing"},{"title":"Usage-Based Billing","href":"/billing/usage-based-pricing"},{"title":"Resolution Limits","href":"/billing/resolution-limits"}]},{"group":"Tools","pages":[{"group":"Video","pages":[{"title":"Video Tools","href":"/tools/video-tools"},{"title":"Face Swap Video API","sidebarTitle":"Face Swap Video","href":"/tools/video/face-swap-video"},{"title":"AI Talking Photo API","sidebarTitle":"Talking Photo","href":"/tools/video/talking-photo"},{"title":"Text to Video API","sidebarTitle":"Text to Video","href":"/tools/video/text-to-video"},{"title":"Lip Sync API","sidebarTitle":"Lip Sync","href":"/tools/video/lip-sync"},{"title":"Character Replace API","sidebarTitle":"Character Replace","href":"/tools/video/character-replace"},{"title":"Video to Video API","sidebarTitle":"Video to Video","href":"/tools/video/video-to-video"},{"title":"AI Video Editor API","sidebarTitle":"AI Video Editor","href":"/tools/video/video-editor"},{"title":"Audio to Video API","sidebarTitle":"Audio to Video","href":"/tools/video/audio-to-video"},{"title":"Auto Subtitle Generator API","sidebarTitle":"Auto Subtitle","href":"/tools/video/auto-subtitle-generator"},{"title":"Image to Video API","sidebarTitle":"Image to Video","href":"/tools/video/image-to-video"},{"title":"Animation API","sidebarTitle":"Animation","href":"/tools/video/animation"}]},{"group":"Images","pages":[{"title":"Image Tools","href":"/tools/image-tools"},{"title":"AI Image Editor API","sidebarTitle":"Image Editor","href":"/tools/image/image-editor"},{"title":"Face Swap Photo API","sidebarTitle":"Face Swap Photo","href":"/tools/image/face-swap-photo"},{"title":"AI Image Upscaler API","sidebarTitle":"Image Upscaler","href":"/tools/image/image-upscaler"},{"title":"AI Image Generator API","sidebarTitle":"Image Generator","href":"/tools/image/image-generator"},{"title":"Head Swap API","sidebarTitle":"Head Swap","href":"/tools/image/head-swap"},{"title":"AI Clothes Changer API","sidebarTitle":"Clothes Changer","href":"/tools/image/clothes-changer"},{"title":"Image Background Remover API","sidebarTitle":"Background Remover","href":"/tools/image/background-remover"},{"title":"Body Swap API","sidebarTitle":"Body Swap","href":"/tools/image/body-swap"},{"title":"AI Headshot Generator API","sidebarTitle":"Headshot Generator","href":"/tools/image/headshot-generator"},{"title":"AI Face Editor API","sidebarTitle":"Face Editor","href":"/tools/image/face-editor"},{"title":"Photo Colorizer API","sidebarTitle":"Photo Colorizer","href":"/tools/image/photo-colorizer"},{"title":"AI GIF Generator API","sidebarTitle":"GIF Generator API","href":"/tools/image/gif-generator"},{"title":"AI Meme Generator API","sidebarTitle":"Meme Generator","href":"/tools/image/meme-generator"},{"title":"AI QR Code Generator API","sidebarTitle":"QR Code Generator","href":"/tools/image/qr-code-generator"}]},{"group":"Audio","pages":[{"title":"Audio Tools","href":"/tools/audio-tools"},{"title":"AI Voice Cloner API","sidebarTitle":"Voice Cloner","href":"/tools/audio/voice-cloner"},{"title":"AI Voice Generator API","sidebarTitle":"Voice Generator","href":"/tools/audio/voice-generator"}]}]}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference/overview"}]},{"tab":"Webhook Reference","pages":[{"title":"Webhook Reference","href":"/webhook-reference/overview"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog"}]}]},"title":"Windmill - Magic Hour API Docs","buildId":"dpl_HcHmUS6i3UwswnTHJUEdcTtwfdTQ","deploymentId":"dpl_HcHmUS6i3UwswnTHJUEdcTtwfdTQ","dynamics":["a74be98ba7"],"chunks":["zoom-image-lightbox-CFBqa0On.js","lightbox-handle-r17bVUz3.js"]}