# Prompt Wizard

> Turn a rough idea into an optimized prompt over REST: ask for guided questions, build a prompt from the answers, or improve a prompt in one call.

Source: https://nodaro.ai/docs/developers/api/prompt-wizard

The **Prompt Wizard API** turns a rough idea into an optimized prompt for a generation node. One endpoint, `POST /v1/prompt-helper/wizard`, does three things, chosen by the `action` field. It asks guided questions (`analyze`), builds a prompt from your answers (`generate`), or rewrites a prompt in one step (`enhance`). It is the same wizard the editor opens from the AI button on a prompt field.

The route works on every edition and takes a bearer token. Each call reserves credits for one language-model call. See [Authentication](https://nodaro.ai/docs/developers/api/authentication).

## Endpoints

| Method | Path | `action` | Returns |
| --- | --- | --- | --- |
| `POST` | `/v1/prompt-helper/wizard` | `analyze` | `{ jobId, questions }` |
| `POST` | `/v1/prompt-helper/wizard` | `generate` | `{ jobId, prompt, recommendedModel? }` |
| `POST` | `/v1/prompt-helper/wizard` | `enhance` | `{ jobId, prompt, recommendedModel? }` |

## Ask for guided questions

`analyze` reads your idea and the target node type, and returns questions about what would most improve the prompt: the subject, the lighting, the camera, the mood and more. Each question comes with suggested answers, and the best one is selected when the wizard can tell. Omit `prompt` to start from scratch; the wizard then picks the key questions and selects nothing.

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/prompt-helper/wizard \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
"action": "analyze",
"nodeType": "generate-image",
"prompt": "a snow leopard on a ridge",
"provider": "nano-banana-pro",
"aspectRatio": "16:9"
}'
```

**TypeScript SDK**

```ts

const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})

const { questions } = await client.promptHelper.analyze({
nodeType: 'generate-image',
prompt: 'a snow leopard on a ridge',
})
```

**CLI**

```bash
nodaro prompt analyze --node-type generate-image --prompt "a snow leopard on a ridge" --json

# Interactive questions and answers in the terminal:
nodaro prompt wizard --node-type generate-image --prompt "a snow leopard on a ridge"
```

```json
{
"jobId": "3b7d1f9a-5c2e-4a8b-9d6f-1e4c7a2b5d8f",
"questions": [
{
"category": "lighting",
"label": "Lighting",
"options": [
{ "value": "golden-hour", "label": "Golden hour", "description": "Low warm sun, long shadows" },
{ "value": "overcast", "label": "Overcast", "description": "Soft, even light" },
{ "value": "blizzard", "label": "Blizzard haze", "description": "Flat light through blowing snow" }
],
"selected": "golden-hour",
"allowCustom": true
}
]
}
```

A response holds 1 to 12 questions. Each question is `{ category, label, options, selected, allowCustom, multi? }`:

| Field | What it holds |
| --- | --- |
| `category` | The question's id. Send it back in your answer. |
| `label` | The question, as shown to a person. |
| `options` | The suggested answers, each `{ value, label, description? }`. |
| `selected` | The suggested answer's `value`, a list of values when `multi` is `true`, or `null` when nothing is suggested. |
| `allowCustom` | Whether you may answer with your own words. |
| `multi` | Present and `true` when several answers may be chosen. |

## Build a prompt from the answers

`generate` builds one optimized prompt from your answers. Send one selection per answered question, `{ category, value, isCustom }`; set `isCustom` to `true` when `value` is your own words. Add `originalPrompt` to weave the original idea into the result.

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/prompt-helper/wizard \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
"action": "generate",
"nodeType": "generate-image",
"originalPrompt": "a snow leopard on a ridge",
"selections": [
{ "category": "lighting", "value": "golden-hour", "isCustom": false },
{ "category": "camera", "value": "telephoto from below, 400mm", "isCustom": true }
]
}'
```

**TypeScript SDK**

```ts
const { prompt, recommendedModel } = await client.promptHelper.generate({
nodeType: 'generate-image',
originalPrompt: 'a snow leopard on a ridge',
selections: [
{ category: 'lighting', value: 'golden-hour', isCustom: false },
{ category: 'camera', value: 'telephoto from below, 400mm', isCustom: true },
],
})
```

**CLI**

```bash
nodaro prompt generate --node-type generate-image \
  --original-prompt "a snow leopard on a ridge" \
  --selection lighting=golden-hour --selection camera="telephoto from below, 400mm" --json
```

```json
{
"jobId": "9e1a3c5b-7d2f-4b6a-8c4e-2f5d8b1a3c7e",
"prompt": "A snow leopard stands on a rocky ridge at golden hour, low warm sun raking across its spotted coat, shot from below on a 400mm telephoto lens, snow dust drifting in the backlight.",
"recommendedModel": {
"provider": "nano-banana-pro",
"field": "provider",
"label": "Nano Banana Pro",
"reason": "Strong fine detail for fur and snow texture."
}
}
```

`recommendedModel` appears when the wizard can suggest a model for the target node: `provider` is the model id to set, `label` its name and `reason` the explanation. A node type with only one model gets no recommendation.

## Improve a prompt in one call

`enhance` skips the questions and returns the optimized prompt directly. It takes the same fields as `analyze`, without selections.

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/prompt-helper/wizard \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "action": "enhance", "nodeType": "text-to-video", "prompt": "a paper boat in a rainy street", "duration": 5 }'
```

**TypeScript SDK**

```ts
const { prompt } = await client.promptHelper.enhance({
nodeType: 'generate-image',
prompt: 'a snow leopard',
})
const image = await client.nodes.runAndWait('generate-image', { prompt })
```

**CLI**

```bash
PROMPT=$(nodaro prompt enhance --node-type generate-image --prompt "snow leopard" --json | jq -r '.prompt')
nodaro nodes run generate-image --param prompt="$PROMPT" --watch
```

## Request fields

<TypeTable
type={{
action: { type: "'analyze' | 'generate' | 'enhance'", description: 'What the wizard does.', required: true },
nodeType: { type: 'string', description: 'The node the prompt is for, for example generate-image, text-to-video or generate-music. The questions and the model recommendation depend on it.', required: true },
prompt: { type: 'string', description: 'analyze and enhance: your rough idea, up to 5,000 characters.' },
selections: { type: 'array', description: 'generate only, at least one: { category, value, isCustom } per answered question.' },
originalPrompt: { type: 'string', description: 'generate only: the original idea to weave in, up to 5,000 characters.' },
provider: { type: 'string', description: 'The model the prompt will run on, so the wording suits it.' },
style: { type: 'string', description: 'The style already chosen on the node.' },
aspectRatio: { type: 'string', description: 'The frame the prompt will run in.' },
duration: { type: 'number', description: 'The clip length in seconds, for video and audio nodes.' },
nodeContext: { type: 'object', description: 'What is connected to the node: connectedInputTypes, referenceImageCount, referenceImageUrls (up to 10) and hasSourceVideo. The wizard skips what the inputs already cover.' },
llmModel: { type: 'string', description: 'The language model that runs the wizard. It sets the price tier.' },
reasoningEffort: { type: "'none' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'", description: 'How long the model thinks, on models that support it. xhigh and max bill one tier up.' },
advancedMode: { type: 'boolean', description: "Gemini models only: run on the model maker's own API so temperature, maxTokens and the full reasoning range apply. Bills one tier up." },
temperature: { type: 'number', description: 'With advancedMode: the sampling temperature.' },
maxTokens: { type: 'number', description: 'With advancedMode: the maximum length of the answer.' },
}}
/>

An unsupported or omitted `reasoningEffort` uses the model's own default. `advancedMode` on a model that is not a Gemini model returns `400 advanced_mode_unsupported`. See the [Prompt](https://nodaro.ai/docs/nodes/automate/prompt) node for the language models and their tiers.

## Credits

Each call is one language-model call, priced at the tier of `llmModel`, and the credits are reserved when the call starts. A guided flow costs two calls: `analyze`, then `generate`. Asking for new questions costs another call. When a call fails with `500` or `502`, its credits are refunded.

## Use it from MCP

AI assistants use the same endpoint through `analyze_prompt`, `generate_prompt` and `enhance_prompt`, with the `workflows:execute` scope. The tools take the same fields, with `advanced_mode`, `temperature` and `max_tokens` for Gemini models. See the [MCP tools reference](https://nodaro.ai/docs/mcp/tools).

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| `400` | `validation_error` | The body is invalid, for example an unknown `action` or a `generate` without selections. |
| `400` | `advanced_mode_unsupported` | `advancedMode` was sent for a model that is not a Gemini model. |
| `401` | `unauthorized` | The token is missing, invalid or revoked. |
| `402` | `insufficient_credits` | Nodaro Cloud only. The account cannot cover the call. |
| `500` | `llm_error` | The language model call failed. The credits are refunded; retry with backoff. |
| `502` | `malformed_response` | The model's answer could not be used. The credits are refunded. |
| `503` | `provider_unavailable` | No language model is configured on this instance. |

## Frequently asked questions

### What is the difference between analyze, generate and enhance?

analyze turns a rough idea into a few guided questions with suggested answers. generate builds one optimized prompt from the answers you choose. enhance skips the questions and rewrites the prompt in a single call.

### How much does the Prompt Wizard cost?

Each call is one language-model call, priced at the tier of the model you choose with llmModel. A full guided flow is two calls, analyze then generate. Asking for new questions costs another call.

### Does the Prompt Wizard recommend a model?

Often. generate and enhance can return recommendedModel, which names a model for the target node and says why. A node type with a single model gets no recommendation.

### Which node types does the wizard support?

Generation nodes that take a prompt, such as generate-image, image-to-video and generate-music. Pass the node type as nodeType so the questions and the model recommendation fit it.
