API guide
Create with text, images and video.
One API key. A consistent job-based workflow.
Quick start
Register and verify your email, sign in, create an API key, add credit, then select an available Nightfolio text, image or motion model. The account must have enough available credit for the quoted request.
Base URL https://developer.nightfolioai.com/v1
Compatibility: GET /v1/models and POST /v1/chat/completions follow the OpenAI formats. Image and video generation use Nightfolio AI asynchronous jobs (202 plus polling), not drop-in OpenAI SDK responses. Each Nightfolio model exposes only its supported capability profile. Claude Messages (/v1/messages), Responses and the OpenAI image-edit endpoint are not supported.
curl "https://developer.nightfolioai.com/v1/images/generations" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "nightfolio-image-4.5",
"prompt": "A small ceramic vase on a warm gray background.",
"size": "2848x1600",
"image": [
"asset://YOUR_REFERENCE_IMAGE_ID"
],
"watermark": false
}'Authentication
Send your Nightfolio AI API key in the Authorization header. You never need a supplier key. Keep your key on your application server. Revoked keys stop working immediately.
Authorization: Bearer mh_YOUR_API_KEYEach new generation needs an Idempotency-Key (1–100 characters). Save it before sending. To retry the same operation, reuse the same key and body.
Models & pricing
GET /v1/models returns only published Nightfolio text, image and motion models. The model directory shows media defaults and supported parameter options. Each request is quoted from its normalized parameters using the displayed Nightfolio pricing, then reserved before submission.
curl "https://developer.nightfolioai.com/v1/models" -H "Authorization: Bearer $NIGHTFOLIO_API_KEY"Text generation
POST /v1/chat/completionsPublished text models: nightfolio-text-2.0-mini, deepseek-v4.1-flash-1017 and deepseek-v4-pro. Use text messages in the OpenAI Chat Completions format, including system messages and multi-turn history. Only n=1 and text content are supported.
curl "https://developer.nightfolioai.com/v1/chat/completions" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4.1-flash-1017","messages":[{"role":"user","content":"Explain how caching reduces inference costs."}],"thinking":{"type":"disabled"},"max_tokens":1024}'DeepSeek thinking: set thinking.type to enabled or disabled. With thinking enabled, use reasoning_effort low, high or max; reasoning_content is returned separately from the final content. If omitted, the upstream thinking defaults apply. The workspace starts with thinking off. The platform output limit is 65,536 tokens, including reasoning. Input is conservatively limited by serialized request bytes plus message overhead to 1,000,000. Non-text inputs are not enabled.
curl -N "https://developer.nightfolioai.com/v1/chat/completions" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"What is 17 times 19?"}],"thinking":{"type":"enabled"},"reasoning_effort":"low","max_tokens":2048,"stream":true}'stream=true returns SSE deltas followed by usage and [DONE]. Final usage can appear on a chunk that also has choices. Process reasoning_content and content separately. The service requests usage automatically. Allow up to 10 minutes for DeepSeek; a stream may return an error event after partial text. Keep X-Request-ID for support and check usage before retrying an interrupted request, as chat requests are not deduplicated.
DeepSeek uses the connected MR account catalog price with zero markup, for uncached input, cached input and output. The model directory shows current rates and all time rules in UTC (weekday 1=Monday through 7=Sunday). A request snapshots the applicable rule when it starts. Charge = uncached input × input rate + cached input × cache rate + output × output rate, rounded up once to $0.000001. Reasoning tokens are already included in output and are never charged twice. A maximum charge is held first and the remainder released after valid usage is received. Missing or inconsistent usage retains the hold for review. Estimated supplier cost uses the same catalog; supplier invoice reconciliation remains manual. Other models keep their published prices.
Reference assets
Use your Nightfolio API key to upload images, video or audio without signing in to Console. Assets belong to your account and are shared with its Console library and other keys. Other accounts cannot list, query, delete or reference them.
curl "https://developer.nightfolioai.com/v1/assets" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-F "file=@./reference.png" \
-F "name=reference.png"File uploads use multipart/form-data with exactly one file. name is optional; type is inferred from the file (an optional type must match). Limits: images 30 MB (JPEG, PNG, WebP, BMP, TIFF, GIF, HEIC/HEIF), video 200 MB (MP4/MOV), audio 15 MB (WAV/MP3). Uploads are limited to 8 attempts per minute per account, shared with Console.
curl "https://developer.nightfolioai.com/v1/assets" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-cdn.com/reference.png","type":"image","name":"reference.png"}'URL imports require url and type (image, video or audio); name is optional. Use a publicly reachable HTTPS URL on port 443, without embedded credentials. Processing validates the remote media. size_bytes is null when its size is unknown.
{
"id": "YOUR_ASSET_ID",
"object": "asset",
"name": "reference.png",
"type": "image",
"status": "processing",
"reference_url": "asset://YOUR_ASSET_ID",
"size_bytes": 1024,
"created_at": "2026-10-24T00:00:00.000Z",
"updated_at": "2026-10-24T00:00:00.000Z"
}Save the returned ID. Poll GET /v1/assets/{id} about every 2 seconds until status is active or failed. Only active assets can be used in image generation references, video input_references or frame_images. A status-query error does not mean the upload failed: retry the query. Uploads do not support Idempotency-Key; after an uncertain upload response, list existing assets before uploading again.
curl "https://developer.nightfolioai.com/v1/assets/YOUR_ASSET_ID" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY"curl "https://developer.nightfolioai.com/v1/assets?type=image&status=active&page=1&page_size=20" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY"List responses contain object=list, data, total, page and page_size (1–100, default 20). type and status filters are optional. Lists show the last saved status; query each processing asset to refresh it. The API returns a reference_url for generation, not a download URL. Assets created in Console can also be queried and used through this API.
curl -X DELETE "https://developer.nightfolioai.com/v1/assets/YOUR_ASSET_ID" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY"Deletion returns {id, object: "asset", deleted: true} and removes the same asset from Console. Wait for any generation using it to finish before deleting. Unknown or other-account IDs return 404. Revoked keys and inactive accounts return 401.
Image generation
POST /v1/images/generationsText-to-image and reference-image generation, one output image per request. The API returns HTTP 202 and a Nightfolio AI job ID immediately. Poll GET /v1/images/{id} for the result. This is an asynchronous Nightfolio AI contract; it is not a drop-in synchronous OpenAI images response.
curl "https://developer.nightfolioai.com/v1/images/generations" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "nightfolio-image-4.5",
"prompt": "A small ceramic vase on a warm gray background.",
"size": "2848x1600",
"image": [
"asset://YOUR_REFERENCE_IMAGE_ID"
],
"watermark": false
}'Required: model and prompt (1–8,000 characters). Optional size and watermark values must exactly match the selected model catalog. image accepts one HTTPS or owned asset:// reference, or an array within the selected model limit. Nightfolio Image 5.0 Pro accepts up to 10 references; other published Seedream profiles accept up to 14. Arbitrary sizes, multiple outputs, callbacks and extra_body are not supported.
Video generation
POST /v1/videos/generationsText-to-video, multimodal reference, first/last-frame generation, video editing and extension share this endpoint. Return HTTP 202, then poll GET /v1/videos/{id}. Nightfolio is always asynchronous, so do not send async.
curl "https://developer.nightfolioai.com/v1/videos/generations" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "nightfolio-motion-2.0-fast",
"prompt": "A slow camera movement through a sunlit forest.",
"seconds": 4,
"resolution": "480p",
"aspect_ratio": "16:9",
"generate_audio": false
}'| Model family | Duration | Resolution | Audio |
|---|---|---|---|
| Nightfolio Motion 1.0 / 1.5 | 5s | 720p | Off |
| Nightfolio Motion 2.0 | 4–15s | 480p / 720p / 1080p / 4k | true / false |
| Nightfolio Motion 2.0 Fast / Mini | 4–15s | 480p / 720p | true / false |
| Nightfolio Motion 2.5 | 4–30s | 480p / 720p | true / false |
Nightfolio Motion uses seconds and aspect_ratio for duration and ratio controls. Supported aspect ratios for Nightfolio Motion 2.x are 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 and adaptive. Omitted parameters keep the backward-compatible default: 5 seconds, 720p, 16:9 and audio off. A video reference must explicitly use seconds=-1. Reference-image and frame-control requests do not support 1080p.
input_references accepts image, video and audio items using matching reference_image, reference_video and reference_audio roles. Nightfolio Motion 2.0/Fast/Mini allow up to 9 images, 3 videos and 3 audio clips (15 total) and cannot use audio alone. Nightfolio Motion 2.5 allows up to 30 images, 10 videos and 10 audio clips (50 total), including audio-only reference. Each URL may be an active asset:// item owned by your account or a public HTTPS URL.
curl "https://developer.nightfolioai.com/v1/videos/generations" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "nightfolio-motion-2.5",
"prompt": "Edit video 1: replace the background with image 1. Keep the subject, timing, camera movement and audio unchanged.",
"seconds": -1,
"resolution": "480p",
"aspect_ratio": "adaptive",
"output_format": "mov",
"input_references": [
{
"type": "video",
"url": "asset://YOUR_VIDEO_ASSET_ID",
"role": "reference_video"
},
{
"type": "image",
"url": "asset://YOUR_IMAGE_ASSET_ID",
"role": "reference_image"
}
]
}'Video editing and extension are selected by the prompt intent: use explicit actions such as edit, replace, remove, extend or continue, and identify materials as video 1, image 1 and so on. For Nightfolio Motion 2.5 editing/extension, use aspect_ratio=adaptive. References containing a non-public human face should use a trusted asset:// item rather than a public URL.
curl "https://developer.nightfolioai.com/v1/videos/generations" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "nightfolio-motion-2.5",
"prompt": "Move smoothly from the first frame to the last frame.",
"seconds": 4,
"resolution": "480p",
"aspect_ratio": "adaptive",
"frame_images": [
{
"frame_type": "first_frame",
"image_url": "asset://YOUR_FIRST_FRAME_ASSET_ID"
},
{
"frame_type": "last_frame",
"image_url": "asset://YOUR_LAST_FRAME_ASSET_ID"
}
]
}'frame_images accepts one first_frame, or one first_frame plus one last_frame. frame_images and input_references are mutually exclusive. Nightfolio Motion 2.5 frame control requires aspect_ratio=adaptive. If you need reference materials as well, use input_references and describe the desired opening frame in the prompt; exact frame consistency is not guaranteed in that mode.
Asset uploads accept images up to 30 MB, MP4/MOV video up to 200 MB, and WAV/MP3 audio up to 15 MB. Public HTTPS references must remain reachable while the upstream task runs.
Job status & results
{
"id": "mh_image_JOB_ID",
"object": "image",
"model": "nightfolio-image-4.5",
"status": "queued",
"created_at": 1788696000,
"charge": 0,
"reserved": 50000,
"billing_status": "processing",
"result_expires_at": 0
}Illustrative amounts only; this response is not a price quote. Monetary response fields use micro-USD: 1 USD = 1,000,000 units.
curl "https://developer.nightfolioai.com/v1/images/mh_image_JOB_ID" \
-H "Authorization: Bearer $NIGHTFOLIO_API_KEY"| Status | Meaning |
|---|---|
queued | Waiting to submit |
submitting | Submitting to the generator |
processing | Generation in progress; keep polling |
completed | Result available; billing settled |
failed | Failed; reserved credit released |
needs_review | Outcome uncertain; hold retained for support review |
Completed images contain result.data[0].b64_json or url. Videos contain result.data[0].url. Save the result promptly: response data is retained for 24 hours; external download links may expire earlier. Only the job owner can query it.
Billing & retries
Credit is reserved before submitting and charged once on successful completion at the saved quote. The quote is calculated from the selected model and request parameters. A confirmed failure releases the hold. An interrupted or uncertain submission keeps the hold for review. Never create a new generation just because a request timed out.
For seconds=-1 video-reference jobs, Nightfolio reserves a conservative maximum before submission, then replaces it with the lower actual charge calculated from the provider-reported output-token usage after successful completion. If valid usage is missing or exceeds the reservation, the job moves to needs_review instead of guessing or overcharging.
Retry submission with the same Idempotency-Key and identical body; query existing jobs instead of recreating them. Poll every 5–10 seconds and back off on 429. Limits: 12 submissions/minute, 120 queries/minute per account, and at most 4 active requests.
Errors
{
"error": {
"code": "model_not_published",
"message": "This model is not published."
}
}| HTTP | Action |
|---|---|
| 400 | Check required fields and fixed parameters |
| 401 | Check your API key or account status |
| 402 | Ask your account manager to add credit |
| 404 | Check model, job ID and ownership |
| 409 | Idempotency-Key conflicts with earlier input |
| 429 | Back off; do not submit duplicate jobs |
| 503 | Model not published or provider unavailable |
