Prompt Spark
Most prompt-generation modes return text. Prompt Spark returns ready-to-run model calls: a prompt plus the dynamic parameters that conform to the target model’s own input schema (its “signature”).
You give it a target model and, optionally, an idea and some reference images. You get back one or more payloads you can send straight to the generation endpoint, with no manual parameter mapping in between.
Endpoint: POST https://api.cloud.scenario.com/v1/generate/prompt - API Reference
The mode is opted into with "mode": "contextual-v2". It is the only mode that returns a calls array.
Why use it
Section titled “Why use it”| Without Prompt Spark | With contextual-v2 |
|---|---|
| Fetch the model, read its inputs, guess sensible values | The engine reads the signature for you |
| Write a prompt that may ignore the model’s conventions (image reference syntax, trigger words, phrasing) | Prompts follow the model’s own prompt guide and example generations |
| Validate ranges, enums and defaults client-side | Every proposed call is schema-valid by construction |
| Attach reference images to the right file input yourself | References are bound to the matching input slot |
The response is synchronous: prompts and calls come back in the same request, together with a completed job record. No polling.
Request
Section titled “Request”| Field | Type | Required | Description |
|---|---|---|---|
mode | string | Yes | Must be contextual-v2. |
modelId | string | Yes | The target model the call is proposed for. You must have read access to it. |
prompt | string | No | Your idea, in any language. Omit it and the engine invents a brief from scratch, grounded in the model’s examples. |
images | string[] | No | Up to 15 references, as asset IDs (asset_...) or data: URLs. Image and video assets are both accepted. |
numResults | number | No | How many distinct calls to propose. 1 to 5, default 1. |
Fields accepted by other modes but ignored in contextual-v2: temperature, topP, seed, ensureIPCleared. The engine owns its own model selection and sampling, so there is no LLM knob to turn.
assetIds is deprecated. It is still read as a fallback when images and image are both absent, but new integrations should send images.
curl -X POST "https://api.cloud.scenario.com/v1/generate/prompt" \ -H "Authorization: Basic <YOUR_BASE64_CREDENTIALS>" \ -H "Content-Type: application/json" \ -d '{ "mode": "contextual-v2", "modelId": "model_bfl-flux-1-dev", "prompt": "a weathered stone shield with a dragon emblem", "numResults": 2 }'Response
Section titled “Response”{ "mode": "contextual-v2", "prompts": [ "A weathered stone shield bearing a carved dragon emblem, moss in the grooves, chipped edges, dramatic side lighting, dark slate background", "Ancient granite kite shield with a coiled dragon relief, sun-bleached surface, fine cracks across the boss, museum lighting, neutral backdrop" ], "calls": [ { "modelId": "model_bfl-flux-1-dev", "parameters": { "prompt": "A weathered stone shield bearing a carved dragon emblem, moss in the grooves, chipped edges, dramatic side lighting, dark slate background", "width": 1104, "height": 832, "numInferenceSteps": 28, "guidance": 3.5 }, "rationale": "Landscape framing and moderate guidance match the model's example generations." }, { "modelId": "model_bfl-flux-1-dev", "parameters": { "prompt": "Ancient granite kite shield with a coiled dragon relief, ...", "width": 1104, "height": 832 } } ], "job": { "jobId": "job_...", "jobType": "generate-prompt", "status": "success", "progress": 1 }}Three rules govern the payload:
promptsandcallsare index-aligned.prompts[i]is the prompt text ofcalls[i].- The prompt text is not duplicated on the call. There is no
calls[i].prompt. The text lives insidecalls[i].parameters, under whatever the model names its prompt input. - Some models have no prompt input at all. For those,
parameterscarries only the non-text inputs and the text exists solely inprompts[i].
rationale is optional and may be absent on any call.
Running the proposed call
Section titled “Running the proposed call”calls[i].parameters is the request body for the generation endpoint. Nothing needs to be rewritten:
POST https://api.cloud.scenario.com/v1/generate/custom/{modelId} - API Reference
curl -X POST "https://api.cloud.scenario.com/v1/generate/custom/model_bfl-flux-1-dev" \ -H "Authorization: Basic <YOUR_BASE64_CREDENTIALS>" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A weathered stone shield ...", "width": 1104, "height": 832 }'TypeScript Example
Section titled “TypeScript Example”import Scenario from '@scenario-labs/sdk';
const client = new Scenario({ apiKey: 'YOUR_API_KEY', apiSecret: 'YOUR_API_SECRET',});
async function sparkAndGenerate(modelId: string, idea: string) { // 1. Ask Prompt Spark for ready-to-run calls const spark = await client.generate.prompt({ mode: 'contextual-v2', modelId, prompt: idea, numResults: 3, });
spark.prompts.forEach((p, i) => console.log(`[${i}] ${p}`));
const call = spark.calls?.[0]; if (!call) throw new Error('No call proposed');
// 2. Run the first proposal as-is const response = await client.generate.runModel(call.modelId, { body: call.parameters, });
const completed = await response.job.wait(); console.log(completed.status, completed.metadata?.assetIds);}
sparkAndGenerate( 'model_bfl-flux-1-dev', 'a weathered stone shield with a dragon emblem',);Python Example
Section titled “Python Example”from scenario_sdk import Scenario
client = Scenario( api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET",)
def spark_and_generate(model_id: str, idea: str): # 1. Ask Prompt Spark for ready-to-run calls spark = client.generate.prompt( mode="contextual-v2", model_id=model_id, prompt=idea, num_results=3, )
for i, p in enumerate(spark.prompts): print(f"[{i}] {p}")
if not spark.calls: raise RuntimeError("No call proposed")
call = spark.calls[0]
# 2. Run the first proposal as-is job = client.generate.run_model(call.model_id, body=call.parameters) print(job)
spark_and_generate("model_bfl-flux-1-dev", "a weathered stone shield with a dragon emblem")Reference images and videos
Section titled “Reference images and videos”Pass references in images, as asset IDs or data: URLs, up to 15 per request.
- Videos count as one reference. A video asset is looked at through its first and last frames (a single frame when only one is available), but it stays one reference and binds as one unit.
- The engine binds references to file inputs. When the target model has image inputs, the proposed call carries your original reference (the asset ID or data URL you sent), never a resolved CDN URL, so the call stays valid after signed URLs expire.
- Many models have their own reference syntax. Because the engine sees the model’s signature and prompt guide, the generated text uses that model’s convention (for instance an
@image1style reference) instead of a generic phrasing. - References must be image or video assets you can read. Anything else is rejected rather than silently dropped.
curl -X POST "https://api.cloud.scenario.com/v1/generate/prompt" \ -H "Authorization: Basic <YOUR_BASE64_CREDENTIALS>" \ -H "Content-Type: application/json" \ -d '{ "mode": "contextual-v2", "modelId": "model_flux-kontext-editing", "prompt": "make it look like a rainy night scene", "images": ["asset_GTrL3mq4SXWyMxkOHRxlpw"], "numResults": 1 }'Batch variant: the Prompt Spark model
Section titled “Batch variant: the Prompt Spark model”The same engine is also exposed as a custom model, for batch use, workflow nodes and agents:
POST https://api.cloud.scenario.com/v1/generate/custom/model_scenario-prompt-spark
| Input | Type | Default | Notes |
|---|---|---|---|
targetModelId | string | required | The model the call is proposed for. |
prompt | string | - | Optional idea. Leave empty to invent from scratch. |
images | file_array | [] | Up to 5 context images. |
numResults | number | 4 | 1 to 10. |
thoroughness | string | thorough | fast or thorough. thorough adds an extra critique and de-duplication pass. |
It behaves like any other asynchronous generation: you get a jobId, you poll, and each result comes back as a JSON Text asset. Each asset is self-contained, so unlike the synchronous response it repeats the prompt at the top level:
{ "prompt": "A weathered stone shield ...", "modelId": "model_bfl-flux-1-dev", "parameters": { "prompt": "A weathered stone shield ...", "width": 1104 }}Use the synchronous endpoint for interactive flows (a spark button, an agent turn) and this model when you want many proposals at once, or a spark step inside a workflow.
Prompt Spark is billed in Creative Units, under the same quota as the other prompt-generation modes. The charge is a deterministic pre-run estimate, driven by the number of results and the number of vision frames, so it is known before the engine runs.
Indicative figures, rounded up in 0.25 CU increments:
| Request | Approximate cost |
|---|---|
| 1 result, no references | ~2.75 CU |
| Each additional result | ~2.5 CU |
| Each reference image | ~1.4 CU (a video reference counts as 2 frames) |
For the exact figure on a given payload, send the same request with ?dryRun=true. It returns the estimated cost with a 269 status and consumes nothing.
curl -X POST "https://api.cloud.scenario.com/v1/generate/prompt?dryRun=true" \ -H "Authorization: Basic <YOUR_BASE64_CREDENTIALS>" \ -H "Content-Type: application/json" \ -d '{ "mode": "contextual-v2", "modelId": "model_bfl-flux-1-dev", "numResults": 5 }'Errors
Section titled “Errors”| Status | Message | Cause |
|---|---|---|
| 400 | modelId is required for contextual-v2 mode | modelId missing. |
| 400 | numResults out of range | Must be an integer between 1 and 5 on this endpoint. |
| 400 | images cannot have more than 15 references | Trim the list, or split into several requests. |
| 400 | images: unknown reference "..." | The entry is neither a readable asset ID nor a data: URL. |
| 400 | images: asset "..." is not an image or a video | Only image and video assets can be used as references. |
| 400 | images: video asset "..." has no extractable frame | No first or last frame could be resolved for that video. |
| 403 | - | You do not have read access to the target model or to one of the referenced assets. |
See Understanding API Responses and Errors for the general error contract.
Notes and limits
Section titled “Notes and limits”- Timeouts. The engine is multi-step and vision-heavy. Allow at least 60 seconds of client timeout; requests with many references sit in the 20 to 30 second range.
- No model selection. The underlying LLM is chosen by the engine and is not part of the API contract. If its primary provider is unavailable, steps fall back automatically, which degrades quality rather than failing your request.
- Parameters are always validated. Proposed values are clamped to the signature’s ranges, checked against allowed values and completed with defaults, so a call cannot be rejected by the generation endpoint for a malformed parameter.
- Signature coverage. Trained models resolve their signature through their base model or architecture wrapper. A handful of legacy Stable Diffusion types expose no public wrapper, so their proposals are prompt-only:
calls[i].parametersis empty and the text is inprompts[i]. contextualmay be served by the same engine. Some accounts have the legacycontextualmode routed to this engine. When that happens the response echoes"mode": "contextual"and stays backward compatible, so readpromptsand treatcallsas optional if you support both modes.