{"openapi":"3.1.0","info":{"title":"Narva API","version":"1.0.0","description":"Generate images, videos and 3D models and enhance images with Narva's models from your own code. Pay as you go from a prepaid balance: 1 credit = $0.01.","termsOfService":"https://narva.ai/api-terms","contact":{"name":"Narva support","url":"https://narva.ai/contact"}},"servers":[{"url":"https://api.narva.ai/functions/v1/api-gateway"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Image models"},{"name":"Video models"},{"name":"Enhancer models"},{"name":"3D models"},{"name":"Jobs"},{"name":"Assets"},{"name":"Account"}],"paths":{"/v1/generate/image/google/nano-banana-2":{"post":{"operationId":"generate-nano-banana-2","tags":["Image models"],"summary":"Nano Banana 2","description":"Google's fast image model for text-to-image and image editing with up to 14 reference images. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"nano-banana-2","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"resolution":"1K","credits":12},{"resolution":"2K","credits":17},{"resolution":"4K","credits":26}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":3,"maxLength":10000},"image_urls":{"description":"Input images to edit or use as references. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); PNG, JPEG or WebP, up to 20 MB each and 40 MB in total.","type":"array","items":{"type":"string","minLength":1},"maxItems":14},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["1:1","1:4","1:8","2:3","3:2","3:4","4:1","4:3","4:5","5:4","9:16","16:9","21:9"]},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["1K","2K","4K"],"default":"1K"}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/image/google/nano-banana-2.1":{"post":{"operationId":"generate-nano-banana-2-1","tags":["Image models"],"summary":"Nano Banana 2.1","description":"The lower-cost Nano Banana for drafts and high volume, with the same inputs as Nano Banana 2. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"nano-banana-2.1","x-narva-pricing":{"unit":"request","credit_usd":0.01,"input_image_credits":1,"input_images_per_charge":5,"prices":[{"resolution":"1K","credits":7},{"resolution":"2K","credits":10},{"resolution":"4K","credits":21}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":3,"maxLength":10000},"image_urls":{"description":"Input images to edit or use as references. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); PNG, JPEG or WebP, up to 20 MB each and 40 MB in total.","type":"array","items":{"type":"string","minLength":1},"maxItems":14},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["1:1","1:4","1:8","2:3","3:2","3:4","4:1","4:3","4:5","5:4","9:16","16:9","21:9"]},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["1K","2K","4K"],"default":"1K"}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/image/google/nano-banana-pro":{"post":{"operationId":"generate-nano-banana-pro","tags":["Image models"],"summary":"Nano Banana Pro","description":"Google's highest-quality image model, best for text in images and precise edits. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"nano-banana-pro","x-narva-pricing":{"unit":"request","credit_usd":0.01,"input_image_credits":1,"input_images_per_charge":5,"prices":[{"resolution":"1K","credits":23},{"resolution":"2K","credits":23},{"resolution":"4K","credits":40}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":3,"maxLength":10000},"image_urls":{"description":"Input images to edit or use as references. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); PNG, JPEG or WebP, up to 20 MB each and 40 MB in total.","type":"array","items":{"type":"string","minLength":1},"maxItems":14},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["1:1","2:3","3:2","3:4","4:3","4:5","5:4","9:16","16:9","21:9"]},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["1K","2K","4K"],"default":"1K"}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/image/openai/gpt-image-2.5-sunburst":{"post":{"operationId":"generate-gpt-image-2-5-sunburst","tags":["Image models"],"summary":"GPT Image 2.5 Sunburst","description":"OpenAI's image model with selectable quality, for photoreal renders and edits. Each input image adds to the price. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"gpt-image-2.5-sunburst","x-narva-pricing":{"unit":"request","credit_usd":0.01,"input_image_credits":3,"long_prompt":{"included_bytes":1000,"per_bytes":1000,"credits":1},"prices":[{"quality":"low","resolution":"1K","credits":2},{"quality":"low","resolution":"2K","credits":3},{"quality":"low","resolution":"4K","credits":5},{"quality":"medium","resolution":"1K","credits":4},{"quality":"medium","resolution":"2K","credits":6},{"quality":"medium","resolution":"4K","credits":9},{"quality":"high","resolution":"1K","credits":10},{"quality":"high","resolution":"2K","credits":19},{"quality":"high","resolution":"4K","credits":31},{"quality":"xhigh","resolution":"1K","credits":17},{"quality":"xhigh","resolution":"2K","credits":33},{"quality":"xhigh","resolution":"4K","credits":54},{"quality":"max","resolution":"1K","credits":36},{"quality":"max","resolution":"2K","credits":73},{"quality":"max","resolution":"4K","credits":120}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":1,"maxLength":32000},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["16:9","2:1","3:2","4:3","1:1","3:4","2:3","1:2","9:16"]},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["1K","2K","4K"]},"quality":{"description":"Rendering quality. Higher quality costs more and takes longer.","type":"string","enum":["low","medium","high","xhigh","max"],"default":"high"},"image_urls":{"description":"Input images to edit or use as references. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); PNG, JPEG or WebP, up to 20 MB each and 40 MB in total.","type":"array","items":{"type":"string","minLength":1},"maxItems":10}},"additionalProperties":false,"required":["prompt","aspect_ratio","resolution"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/image/openai/gpt-image-2.5-flare":{"post":{"operationId":"generate-gpt-image-2-5-flare","tags":["Image models"],"summary":"GPT Image 2.5 Flare","description":"OpenAI's image model with transparent-background support. Each input image adds to the price. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"gpt-image-2.5-flare","x-narva-pricing":{"unit":"request","credit_usd":0.01,"input_image_credits":3,"long_prompt":{"included_bytes":1000,"per_bytes":1000,"credits":1},"prices":[{"quality":"low","resolution":"1K","credits":2},{"quality":"low","resolution":"2K","credits":3},{"quality":"low","resolution":"4K","credits":5},{"quality":"medium","resolution":"1K","credits":4},{"quality":"medium","resolution":"2K","credits":6},{"quality":"medium","resolution":"4K","credits":9},{"quality":"high","resolution":"1K","credits":10},{"quality":"high","resolution":"2K","credits":19},{"quality":"high","resolution":"4K","credits":31},{"quality":"xhigh","resolution":"1K","credits":17},{"quality":"xhigh","resolution":"2K","credits":33},{"quality":"xhigh","resolution":"4K","credits":54},{"quality":"max","resolution":"1K","credits":36},{"quality":"max","resolution":"2K","credits":73},{"quality":"max","resolution":"4K","credits":120}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":1,"maxLength":32000},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["16:9","2:1","3:2","4:3","1:1","3:4","2:3","1:2","9:16"]},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["1K","2K","4K"]},"quality":{"description":"Rendering quality. Higher quality costs more and takes longer.","type":"string","enum":["low","medium","high","xhigh","max"],"default":"high"},"image_urls":{"description":"Input images to edit or use as references. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); PNG, JPEG or WebP, up to 20 MB each and 40 MB in total.","type":"array","items":{"type":"string","minLength":1},"maxItems":10},"background":{"description":"transparent gives a PNG with an alpha channel.","type":"string","enum":["transparent","opaque","auto"]}},"additionalProperties":false,"required":["prompt","aspect_ratio","resolution"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/video/bytedance/seedance-2":{"post":{"operationId":"generate-seedance-2","tags":["Video models"],"summary":"Seedance 2.0","description":"ByteDance's video model: text, first/last frame or reference media to video, with generated audio. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"seedance-2","x-narva-pricing":{"unit":"second","credit_usd":0.01,"prices":[{"video_ref":"no","resolution":"480p","credits":14},{"video_ref":"no","resolution":"720p","credits":30},{"video_ref":"no","resolution":"1080p","credits":75},{"video_ref":"yes","resolution":"480p","credits":17},{"video_ref":"yes","resolution":"720p","credits":37},{"video_ref":"yes","resolution":"1080p","credits":92}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":1,"maxLength":4000},"start_image":{"description":"First frame of the video. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"end_image":{"description":"Last frame of the video; needs start_image. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["16:9","4:3","1:1","3:4","9:16","21:9"],"default":"16:9"},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["480p","720p","1080p"],"default":"720p"},"duration":{"description":"Video length in seconds: 4 to 15. Priced per second.","type":"integer","default":5},"reference_images":{"description":"Images the video should draw characters, objects or style from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>). Can't be combined with start_image or end_image.","type":"array","items":{"type":"string","minLength":1},"maxItems":9},"reference_videos":{"description":"Videos to take motion or camera work from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP4, WebM or QuickTime, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Using one costs more: the job is billed at this model's video_ref: yes price.","type":"array","items":{"type":"string","minLength":1},"maxItems":3},"reference_audios":{"description":"Audio to follow, e.g. a voice or music. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP3, WAV or M4A, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Needs a reference image or video.","type":"array","items":{"type":"string","minLength":1},"maxItems":3},"seed":{"description":"Fixes randomness so the same request gives a similar result.","type":"integer","minimum":0,"maximum":2147483647},"generate_audio":{"description":"Set to false for a silent video. The price is the same. Try this if a job fails with content_policy because of its generated audio. Can't be false with reference_audios.","type":"boolean","default":true}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/video/bytedance/seedance-2-fast":{"post":{"operationId":"generate-seedance-2-fast","tags":["Video models"],"summary":"Seedance 2.0 Fast","description":"A faster, cheaper Seedance 2.0 at 480p or 720p. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"seedance-2-fast","x-narva-pricing":{"unit":"second","credit_usd":0.01,"prices":[{"video_ref":"no","resolution":"480p","credits":12},{"video_ref":"no","resolution":"720p","credits":25},{"video_ref":"yes","resolution":"480p","credits":14},{"video_ref":"yes","resolution":"720p","credits":29}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":1,"maxLength":4000},"start_image":{"description":"First frame of the video. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"end_image":{"description":"Last frame of the video; needs start_image. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["16:9","4:3","1:1","3:4","9:16","21:9"],"default":"16:9"},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["480p","720p"],"default":"720p"},"duration":{"description":"Video length in seconds: 4 to 15. Priced per second.","type":"integer","default":5},"reference_images":{"description":"Images the video should draw characters, objects or style from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>). Can't be combined with start_image or end_image.","type":"array","items":{"type":"string","minLength":1},"maxItems":9},"reference_videos":{"description":"Videos to take motion or camera work from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP4, WebM or QuickTime, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Using one costs more: the job is billed at this model's video_ref: yes price.","type":"array","items":{"type":"string","minLength":1},"maxItems":3},"reference_audios":{"description":"Audio to follow, e.g. a voice or music. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP3, WAV or M4A, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Needs a reference image or video.","type":"array","items":{"type":"string","minLength":1},"maxItems":3},"seed":{"description":"Fixes randomness so the same request gives a similar result.","type":"integer","minimum":0,"maximum":2147483647},"generate_audio":{"description":"Set to false for a silent video. The price is the same. Try this if a job fails with content_policy because of its generated audio. Can't be false with reference_audios.","type":"boolean","default":true}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/video/bytedance/seedance-2-5":{"post":{"operationId":"generate-seedance-2-5","tags":["Video models"],"summary":"Seedance 2.5","description":"The latest Seedance, up to 30 seconds and up to 30 reference images. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"seedance-2-5","x-narva-pricing":{"unit":"second","credit_usd":0.01,"prices":[{"video_ref":"no","resolution":"480p","credits":18},{"video_ref":"no","resolution":"720p","credits":39},{"video_ref":"yes","resolution":"480p","credits":100},{"video_ref":"yes","resolution":"720p","credits":200}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","minLength":1,"maxLength":4000},"start_image":{"description":"First frame of the video. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"end_image":{"description":"Last frame of the video; needs start_image. An image as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"aspect_ratio":{"description":"Shape of the output.","type":"string","enum":["16:9","4:3","1:1","3:4","9:16","21:9"],"default":"16:9"},"resolution":{"description":"Output resolution. Prices are per resolution.","type":"string","enum":["480p","720p"],"default":"720p"},"duration":{"description":"Video length in seconds: 4 to 15, 20, 25 or 30. Priced per second.","type":"integer","default":5},"reference_images":{"description":"Images the video should draw characters, objects or style from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>). Can't be combined with start_image or end_image.","type":"array","items":{"type":"string","minLength":1},"maxItems":30},"reference_videos":{"description":"Videos to take motion or camera work from. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP4, WebM or QuickTime, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Using one costs more: the job is billed at this model's video_ref: yes price.","type":"array","items":{"type":"string","minLength":1},"maxItems":10},"reference_audios":{"description":"Audio to follow, e.g. a voice or music. Each is an https URL, a base64 data URI or an uploaded asset (asset://<id>); MP3, WAV or M4A, up to 75 MB, and up to 15 seconds in total (30 on Seedance 2.5). Needs a reference image or video.","type":"array","items":{"type":"string","minLength":1},"maxItems":10},"seed":{"description":"Fixes randomness so the same request gives a similar result.","type":"integer","minimum":0,"maximum":2147483647},"generate_audio":{"description":"Set to false for a silent video. The price is the same. Try this if a job fails with content_policy because of its generated audio. Can't be false with reference_audios.","type":"boolean","default":true}},"additionalProperties":false,"required":["prompt"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/enhance/topaz/image-upscale":{"post":{"operationId":"generate-topaz-image-upscale","tags":["Enhancer models"],"summary":"Topaz Image Upscale","description":"Faithful upscaling for photos and renders, up to 6x. Priced by the size of the finished image. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"topaz-image-upscale","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"output_size":"Up to 24 MP","credits":14},{"output_size":"Up to 48 MP","credits":27},{"output_size":"Up to 72 MP","credits":40},{"output_size":"Up to 96 MP","credits":54},{"output_size":"Up to 100 MP","credits":80}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"description":"The image to work on, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"upscale_factor":{"description":"How much bigger to make the image.","type":"string","enum":["2x","4x","6x"],"default":"2x"},"enhance_model":{"description":"The Topaz model. Standard V2 suits most photos and renders; CGI suits computer graphics.","type":"string","enum":["Standard V2","Low Resolution V2","CGI","High Fidelity V2","Text Refine"],"default":"Standard V2"},"output_format":{"description":"The file type of the result.","type":"string","enum":["jpg","png"],"default":"jpg"},"subject_detection":{"description":"Which part of the image to treat as the subject.","type":"string","enum":["None","All","Foreground","Background"],"default":"None"},"face_enhancement":{"description":"Improves faces found in the image.","type":"boolean","default":false},"face_enhancement_creativity":{"description":"How much the face enhancer may invent, from 0 to 1.","type":"number","minimum":0,"maximum":1,"default":0},"face_enhancement_strength":{"description":"How strongly enhanced faces replace the originals, from 0 to 1.","type":"number","minimum":0,"maximum":1,"default":0.8}},"additionalProperties":false,"required":["image_url"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/enhance/topaz/generative-enhance":{"post":{"operationId":"generate-topaz-generative","tags":["Enhancer models"],"summary":"Topaz Generative","description":"Generative enhancement and upscaling with eight Topaz models, up to 6x. Priced by model and the size of the finished image. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"topaz-generative","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"model_group":"Standard","output_size":"Up to 4 MP","credits":7},{"model_group":"Standard","output_size":"Up to 8 MP","credits":14},{"model_group":"Standard","output_size":"Up to 16 MP","credits":27},{"model_group":"Standard","output_size":"Up to 24 MP","credits":40},{"model_group":"Standard","output_size":"Up to 48 MP","credits":80},{"model_group":"Standard","output_size":"Up to 100 MP","credits":167},{"model_group":"Wonder 3","output_size":"Up to 4 MP","credits":7},{"model_group":"Wonder 3","output_size":"Up to 8 MP","credits":7},{"model_group":"Wonder 3","output_size":"Up to 16 MP","credits":14},{"model_group":"Wonder 3","output_size":"Up to 24 MP","credits":20},{"model_group":"Wonder 3","output_size":"Up to 48 MP","credits":40},{"model_group":"Wonder 3","output_size":"Up to 100 MP","credits":87},{"model_group":"Reimagine","output_size":"Up to 4 MP","credits":14},{"model_group":"Reimagine","output_size":"Up to 8 MP","credits":27},{"model_group":"Reimagine","output_size":"Up to 16 MP","credits":54},{"model_group":"Reimagine","output_size":"Up to 24 MP","credits":80},{"model_group":"Reimagine","output_size":"Up to 48 MP","credits":160},{"model_group":"Reimagine","output_size":"Up to 100 MP","credits":334}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"description":"The image to work on, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"model":{"description":"The Topaz model. Price depends on the group: Reimagine, Wonder 3, or Standard for the rest.","type":"string","enum":["Redefine","Recovery","Recovery V2","Reimagine","Wonder 3","Standard MAX","Recover 3","Detail"],"default":"Redefine"},"scale_factor":{"description":"How much bigger to make the image.","type":"integer","minimum":1,"maximum":6,"default":2},"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","maxLength":1000},"creativity":{"description":"How much new detail the model may invent.","type":"integer","minimum":1,"maximum":6,"default":3},"texture":{"description":"How much texture to add, from 1 to 5.","type":"integer","minimum":1,"maximum":5,"default":3},"sharpen":{"description":"How much to sharpen.","type":"number","minimum":0,"maximum":1,"default":0.5},"denoise":{"description":"How much noise to remove, from 0 to 1.","type":"number","minimum":0,"maximum":1,"default":0.5},"detail":{"description":"How much fine detail to recover, from 0 to 1. Ignored by Reimagine.","type":"number","minimum":0,"maximum":1,"default":0.5},"face_enhancement":{"description":"Improves faces found in the image.","type":"boolean","default":false},"face_enhancement_creativity":{"description":"How much the face enhancer may invent, from 0 to 1.","type":"number","minimum":0,"maximum":1,"default":0.5},"face_enhancement_strength":{"description":"How strongly enhanced faces replace the originals, from 0 to 1.","type":"number","minimum":0,"maximum":1,"default":0.5},"subject_detection":{"description":"Which part of the image to treat as the subject.","type":"string","enum":["All","Foreground","Background"],"default":"All"},"output_format":{"description":"The file type of the result.","type":"string","enum":["jpg","png","webp"],"default":"jpg"},"seed":{"description":"Fixes randomness so the same request gives a similar result.","type":"integer","minimum":0,"maximum":2147483647}},"additionalProperties":false,"required":["image_url"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/enhance/magnific/creative":{"post":{"operationId":"generate-magnific-creative","tags":["Enhancer models"],"summary":"Magnific Upscaler Creative","description":"Generative upscaling that adds detail, with creative control, up to 16x and 25.3 MP. Priced by the size of the finished image. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"magnific-creative","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"output_size":"Up to 3.7 MP","credits":19},{"output_size":"Up to 8.3 MP","credits":60},{"output_size":"Up to 25.3 MP","credits":240}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"description":"The image to work on, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"scale_factor":{"description":"How much bigger to make the image.","type":"string","enum":["2x","4x","8x","16x"],"default":"2x"},"optimized_for":{"description":"The kind of image this is.","type":"string","enum":["standard","soft_portraits","hard_portraits","art_n_illustration","videogame_assets","nature_n_landscapes","films_n_photography","3d_renders","science_fiction_n_horror"],"default":"standard"},"engine":{"description":"The Magnific engine. Automatic picks one for you.","type":"string","enum":["automatic","magnific_illusio","magnific_sharpy","magnific_sparkle"],"default":"automatic"},"prompt":{"description":"What to create, or the change to make to the inputs.","type":"string","maxLength":1000},"creativity":{"description":"How much new detail the model may invent.","type":"integer","minimum":-10,"maximum":10,"default":0},"hdr":{"description":"Added definition and contrast, from -10 to 10.","type":"integer","minimum":-10,"maximum":10,"default":0},"resemblance":{"description":"How closely the result follows the original, from -10 to 10.","type":"integer","minimum":-10,"maximum":10,"default":0},"fractality":{"description":"How much detail to add per pixel, from -10 to 10.","type":"integer","minimum":-10,"maximum":10,"default":0}},"additionalProperties":false,"required":["image_url"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/enhance/magnific/precision-v2":{"post":{"operationId":"generate-magnific-precision-v2","tags":["Enhancer models"],"summary":"Magnific Upscaler Precision V2","description":"Upscaling that stays close to the original, up to 16x and 33 MP. Priced by the size of the finished image. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"magnific-precision-v2","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"output_size":"Up to 3.7 MP","credits":19},{"output_size":"Up to 8.3 MP","credits":60},{"output_size":"Up to 33 MP","credits":240}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"description":"The image to work on, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"scale_factor":{"description":"How much bigger to make the image.","type":"integer","minimum":2,"maximum":16,"default":2},"sharpen":{"description":"How much to sharpen.","type":"integer","minimum":0,"maximum":100,"default":7},"smart_grain":{"description":"Film-like grain, from 0 to 100.","type":"integer","minimum":0,"maximum":100,"default":7},"ultra_detail":{"description":"Extra fine detail, from 0 to 100.","type":"integer","minimum":0,"maximum":100,"default":30},"flavor":{"description":"The style of processing. Leave it out to let Magnific choose.","type":"string","enum":["sublime","photo","photo_denoiser"]}},"additionalProperties":false,"required":["image_url"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/enhance/crystal/crystal-upscaler":{"post":{"operationId":"generate-crystal-upscaler","tags":["Enhancer models"],"summary":"Crystal Upscaler","description":"Fast general upscaling, up to 8x. Priced by the size of the finished image. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"crystal-upscaler","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"output_size":"Up to 4.4 MP","credits":9},{"output_size":"Up to 8.8 MP","credits":17},{"output_size":"Up to 17.6 MP","credits":34},{"output_size":"Up to 27.5 MP","credits":67},{"output_size":"Up to 55 MP","credits":134},{"output_size":"Up to 100 MP","credits":267}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"description":"The image to work on, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). PNG, JPEG or WebP, up to 20 MB.","type":"string","minLength":1},"scale_factor":{"description":"How much bigger to make the image.","type":"integer","minimum":2,"maximum":8,"default":2},"creativity":{"description":"How much new detail the model may invent.","type":"integer","minimum":0,"maximum":10,"default":0},"output_format":{"description":"The file type of the result.","type":"string","enum":["jpg","png"],"default":"png"}},"additionalProperties":false,"required":["image_url"]}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/generate/3d/tencent/hunyuan-3d-3.1-pro":{"post":{"operationId":"generate-hunyuan-3d-3-1-pro","tags":["3D models"],"summary":"Hunyuan 3D V3.1 Pro","description":"Tencent's higher-quality 3D model, with extra views for accurate geometry. The result is a GLB file. PBR materials, extra views and a custom face count each add to the price. Returns the queued job at once; poll GET /v1/jobs/{id} or use a webhook.","x-narva-model":"hunyuan-3d-3.1-pro","x-narva-pricing":{"unit":"request","credit_usd":0.01,"prices":[{"extras":"Base","credits":63},{"extras":"One extra","credits":88},{"extras":"Two extras","credits":113},{"extras":"Three extras","credits":138}]},"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":255},"description":"Repeat a request safely: the same key with the same body returns the first response for 24 hours instead of starting a second job."},{"name":"X-Webhook-URL","in":"header","schema":{"type":"string","format":"uri"},"description":"A public https URL that gets a signed POST when this job finishes. Overrides the workspace default."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"description":"What to create. Send either this or image_url.","type":"string","minLength":3,"maxLength":1024},"image_url":{"description":"The image to turn into a model. An https URL, a base64 data URI or an uploaded asset (asset://<id>). Works best with one object on a plain background: photos of whole rooms are refused and refunded. PNG, JPEG or WebP, up to 6 MB, each side 128 to 5000 pixels. Send either this or prompt.","type":"string","minLength":1},"generate_type":{"description":"Normal makes a textured model; Geometry makes the shape only.","type":"string","enum":["Normal","Geometry"],"default":"Normal"},"enable_pbr":{"description":"Adds PBR materials, at a higher price. Needs generate_type Normal.","type":"boolean","default":false},"face_count":{"description":"How many polygons the model has, from 40,000 to 1,500,000. Any value other than 500,000 costs more.","type":"integer","minimum":40000,"maximum":1500000,"default":500000},"back_image_url":{"description":"The back of the object, as an https URL, a base64 data URI or an uploaded asset (asset://<id>). Using any extra view adds to the price once.","type":"string","minLength":1},"left_image_url":{"description":"The left side of the object.","type":"string","minLength":1},"right_image_url":{"description":"The right side of the object.","type":"string","minLength":1},"top_image_url":{"description":"The top of the object.","type":"string","minLength":1},"bottom_image_url":{"description":"The bottom of the object.","type":"string","minLength":1},"left_front_image_url":{"description":"The front left of the object.","type":"string","minLength":1},"right_front_image_url":{"description":"The front right of the object.","type":"string","minLength":1},"seed":{"description":"Fixes randomness so the same request gives a similar result.","type":"integer","minimum":0,"maximum":2147483647}},"additionalProperties":false}}}},"responses":{"200":{"description":"The queued job. Its cost has been reserved from the balance.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Jobs this workspace may have queued or running for this model."},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"Idempotent-Replayed":{"schema":{"type":"string","enum":["true"]},"description":"Set when this is the job of an earlier request with the same Idempotency-Key."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The balance is too low for this request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or a monthly or first-week spend cap is reached (spend_cap_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The model has been retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is over 30 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: too many jobs are running for this model. too_many_refusals: 10 or more of this workspace's requests to Google models were refused by the model in the last hour. Retry after the Retry-After seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{id}":{"get":{"operationId":"get-job","tags":["Jobs"],"summary":"Get a job","description":"Status, cost and, once completed, fresh links to the outputs.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs":{"get":{"operationId":"list-jobs","tags":["Jobs"],"summary":"List jobs","description":"This workspace's jobs, newest first.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"status","in":"query","schema":{"type":"string","enum":["queued","processing","completed","failed","cancelled"]}}],"responses":{"200":{"description":"A page of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobList"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/jobs/{id}/cancel":{"post":{"operationId":"cancel-job","tags":["Jobs"],"summary":"Cancel a job","description":"Cancels a job that hasn't started yet and refunds it in full. Running jobs can't be cancelled.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The cancelled job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The job has already started or finished.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/assets":{"post":{"operationId":"upload-asset","tags":["Assets"],"summary":"Upload an asset","description":"Upload a file once and use its asset://<id> in any media field, as often as you like. Images up to 20 MB when used as image inputs; video and audio up to 75 MB. Needs a positive balance or an earlier top-up; a workspace can keep up to 5 GB of assets.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"PNG, JPEG or WebP; MP4, WebM or QuickTime; MP3, WAV or M4A. Up to 75 MB."},"description":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"The stored asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"The body couldn't be parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The workspace has no balance and has never added funds (insufficient_balance).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended), or this file would take its assets past 5 GB (asset_storage_limit).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The file is over 75 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"The file type isn't accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"list-assets","tags":["Assets"],"summary":"List assets","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."}],"responses":{"200":{"description":"A page of assets, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetList"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/assets/{id}":{"get":{"operationId":"get-asset","tags":["Assets"],"summary":"Get an asset","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"delete-asset","tags":["Assets"],"summary":"Delete an asset","description":"Jobs that already used the asset keep their own copy.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}}}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/balance":{"get":{"operationId":"get-balance","tags":["Account"],"summary":"Get the balance","responses":{"200":{"description":"The workspace balance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/usage":{"get":{"operationId":"get-usage","tags":["Account"],"summary":"Get usage","description":"Charges, refunds and top-ups for a window of whole UTC days (both ends included), newest first, with totals. Defaults to the last 30 days; at most 366.","parameters":[{"name":"start_date","in":"query","schema":{"type":"string","format":"date"},"description":"YYYY-MM-DD."},{"name":"end_date","in":"query","schema":{"type":"string","format":"date"},"description":"YYYY-MM-DD."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."}],"responses":{"200":{"description":"Ledger entries and totals.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"The API key is missing, invalid, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The workspace is suspended (workspace_suspended).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request isn't valid. error.param names the field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/models":{"get":{"operationId":"list-models","tags":["Account"],"summary":"List models","description":"Every available model with its endpoint and current prices. Needs no API key.","security":[],"responses":{"200":{"description":"The models.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}}}}}}},"405":{"description":"This path doesn't take that method. The Allow header lists the ones it does.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on Narva's side. Retry; quote error.request_id to support.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"job.finished":{"post":{"summary":"Job finished","description":"Sent when a job completes, fails or is cancelled, to the request's X-Webhook-URL or the workspace's default URL. The body is the job. Verify Narva-Signature before trusting it. Any 2xx counts as delivered; other answers are retried for 24 hours.","parameters":[{"name":"Narva-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix seconds>,v1=<hex HMAC-SHA256 of `${t}.${raw body}` with your signing secret>"},{"name":"Narva-Event","in":"header","required":true,"schema":{"type":"string","enum":["job.completed","job.failed","job.cancelled"]}},{"name":"Narva-Webhook-Id","in":"header","required":true,"schema":{"type":"string"},"description":"The same for every retry of one delivery; use it to ignore duplicates."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"nva_live_…","description":"An API key from narva.ai/developers/keys, sent as Authorization: Bearer nva_live_…"}},"schemas":{"Job":{"type":"object","required":["job_id","status","model","cost_credits","created_at","started_at","completed_at","result","error"],"properties":{"job_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","processing","completed","failed","cancelled"]},"model":{"type":"string","examples":["nano-banana-2"]},"cost_credits":{"type":"integer","description":"Credits charged (1 credit = $0.01). 0 once a job has failed or been cancelled, since those are refunded in full."},"created_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"result":{"type":["object","null"],"description":"Set when status is completed.","properties":{"urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Signed links to the outputs, valid for 24 hours. Fetch the job again for fresh links, or if a list or generate response came without them."},"expired":{"type":"boolean","description":"True once the outputs were deleted after the 30-day retention; urls is then empty."}}},"error":{"type":["object","null"],"description":"Set when status is failed.","properties":{"code":{"type":"string","enum":["content_policy","generation_refused","invalid_request","provider_error","model_unavailable","timeout","workspace_suspended","internal"]},"message":{"type":"string"}}}}},"JobList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"next_cursor":{"type":["string","null"]}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","request_id"],"properties":{"code":{"type":"string","examples":["validation_failed"]},"message":{"type":"string"},"param":{"type":"string","description":"The field or header the error is about, when there is one."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"request_id":{"type":"string","examples":["req_3f2c…"]}}}}},"Balance":{"type":"object","properties":{"balance_credits":{"type":"integer"},"balance_usd":{"type":"number"}}},"Model":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["image","video","enhancer","3d"]},"endpoint":{"type":"string","examples":["/v1/generate/image/google/nano-banana-2"]},"input_image_credits":{"type":"integer","description":"Credits added for input images, on models that charge for them: per image, or per started group of input_images_per_charge images when that is set."},"input_images_per_charge":{"type":"integer","description":"When present, input_image_credits is charged once per started group of this many images."},"long_prompt":{"type":"object","description":"When present, credits added for long prompts: credits for each started per_bytes of UTF-8 prompt text beyond included_bytes.","properties":{"included_bytes":{"type":"integer"},"per_bytes":{"type":"integer"},"credits":{"type":"integer"}}},"prices":{"type":"array","description":"One entry per priced option combination. unit is request or second.","items":{"type":"object","additionalProperties":true,"properties":{"credits":{"type":"number"},"unit":{"type":"string","enum":["request","second"]}}}}}},"UsageEntry":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["charge","refund","topup","adjustment"]},"credits":{"type":"integer","description":"Negative for charges."},"job_id":{"type":["string","null"]},"model":{"type":["string","null"]},"note":{"type":["string","null"]},"balance_after":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"Usage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UsageEntry"}},"summary":{"type":"object","description":"Totals for the whole date window, in credits.","properties":{"charged":{"type":"integer"},"refunded":{"type":"integer"},"topped_up":{"type":"integer"},"adjusted":{"type":"integer"},"net":{"type":"integer"}}},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"next_cursor":{"type":["string","null"]}}},"Asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","examples":["asset://6b1f…"],"description":"Pass this in any media field of a generate request."},"download_url":{"type":["string","null"],"format":"uri","description":"Signed link, valid for 24 hours."},"mime_type":{"type":"string"},"size_bytes":{"type":"integer"},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"description":{"type":["string","null"]},"uploaded_at":{"type":"string","format":"date-time"}}},"AssetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"next_cursor":{"type":["string","null"]}}}}}}