Raw prompt mode
Send a custom system/user prompt straight to the model instead of a named pipeline — request shape, model selection, and the constraints that don't apply to named pipelines.
Every other guide in this section calls a named pipeline (translate-string, summarize,
etc.) — a fixed prompt template with declared inputs. Raw mode skips the template: you send your
own system_prompt and user_prompt directly, and the platform runs it as-is. Use it for
prototyping a prompt before it’s worth turning into a real pipeline, or for a one-off call that
doesn’t fit any of the built-in tools.
Getting it enabled
Raw mode is gated separately from named pipelines. Your JWT’s pipelines[] claim needs an
explicit "raw" entry — the same claim used for named pipeline IDs, just with this one extra
string. It is not granted by default, and most end-user session tokens should never have it:
a named pipeline’s cost is bounded by its template, but a raw prompt’s cost is bounded only by
how long a prompt you’re willing to send and how many tokens you ask the model to generate.
If your app mints session tokens itself (see Node.js server
integration’s POST /auth/token section), request
"raw" only for the specific tokens that need it — e.g. an internal admin tool, not tokens handed
to arbitrary end users. Ask your platform operator to confirm your Application’s
allowed_pipelines includes "raw" before you request a token with that claim; a claim your
Application isn’t allowed to grant is silently dropped from the issued token.
A static x-api-key (unbound, operator-scoped — see Get your API
key) bypasses the pipeline-list check entirely, same as it does for
named pipelines. A Console-issued, app-bound x-api-key and a JWT/webtoken caller both need the
explicit "raw" grant.
Calling it — SDK
const out = await ai.run({
raw: {
system_prompt: "You are a terse assistant. Answer in one sentence.",
user_prompt: "What does raw mode skip that a named pipeline has?",
model: "gpt-5-mini", // optional — see "Choosing a model" below
temperature: 0.2, // optional
max_tokens: 500, // optional, up to 32768
},
});
console.log(out.text);
user_prompt can also be a function of inputs when used with ai.runMany(...) — see the SDK’s
fuller Integration Guide (ask your platform operator for a copy — it isn’t public) for that
pattern. ai.button(...) also accepts a raw config in place of pipeline.
Calling it — direct HTTP
Requires Authorization: Bearer <jwt> with the "raw" grant (a static x-api-key works too if
it’s the unbound operator kind — see above). params is optional and both fields inside it are
optional:
curl -X POST "https://api.quravin.com/tickets" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-jwt>" \
-d '{
"mode": "raw",
"system_prompt": "You are a terse assistant. Answer in one sentence.",
"user_prompt": "What does raw mode skip that a named pipeline has?",
"model": "gpt-5-mini",
"params": { "temperature": 0.2, "max_tokens": 500 }
}'
Response (202), then poll the same way as any ticket — see Direct API
integration if you haven’t built that loop yet:
{ "ticket_id": "01J...ULID", "status": "QUEUED" }
curl "https://api.quravin.com/tickets/01J...ULID" \
-H "Authorization: Bearer <your-jwt>"
Response once done — the shape is always the same four fields plus text, regardless of which
model ran it:
{
"ticket_id": "01J...ULID",
"status": "DONE",
"mode": "raw",
"result": {
"text": "It skips the fixed prompt template and declared input schema.",
"model": "gpt-5-mini",
"latency_ms": 640,
"tokens_in": 38,
"tokens_out": 14
},
"created_at": "2026-07-10T12:00:00.000Z",
"updated_at": "2026-07-10T12:00:02.000Z"
}
There’s no pipeline-specific field to look up (no translation, no tldr) — result.text is
always where the model’s output lands.
Choosing a model
model is optional — omit it to use the platform’s current default. If you set it explicitly, it
must be one the platform has a verified cost rate for, checked before the call reaches the LLM:
send anything else and you get 400 invalid_model instead of an expensive surprise. As of this
writing that list is gpt-4o-mini, gpt-4o, o3, and gpt-5-mini — ask your platform operator
for the current list, since it changes as models are added.
What’s different from a named pipeline
- No input schema. A named pipeline validates your
inputsagainst its declared schema before the call is accepted (missing field, wrong type →400). Raw mode has no schema —system_promptanduser_promptare required strings, but their content is never validated. A prompt that doesn’t make sense to the model doesn’t fail upfront; the ticket runs, and you find out when you poll the result. - No caching. Named pipelines cache identical calls by their inputs. Raw mode never checks a cache — every call is a fresh model call, every time, even if you send the exact same prompt twice in a row.
- The global input-size backstop still applies, measured differently:
system_prompt.length + user_prompt.lengthcombined must stay under the platform’s character cap (50,000 by default) — same defense-in-depth limit that bounds named-pipelineinputs, just added up across the two fields instead of the whole JSON body. max_tokensis capped at 32768 regardless of what the underlying model would otherwise allow — a ceiling on a single call’s worst case, not a target to aim for.
Errors
Same authenticated-path error table as any other call — see Direct API
integration for the full list. One error is specific
to raw mode: 400 invalid_model, covered above.
If your JWT doesn’t carry the "raw" grant, you get the same 403 as calling a named pipeline
you’re not allowed to use — see Choose your auth mode for how
credential grants work.