Skip to main content

Prompt Management

Store prompts server-side, version them, label a release, pin model parameters as presets, and render a template without calling a model.

Overview

Prompt management moves your system prompts out of your deployment and into the gateway, so you can change wording without shipping code.

  • A prompt is a named container.
  • A version is an immutable snapshot of a template, its declared variables, and optionally a model and parameter set. Versions are append-only — you never edit one, you add the next.
  • A label (production, staging, …) points at exactly one version. Moving the label is the release.
  • A preset pins a model plus a parameter block, optionally bound to a prompt version, so several call sites share one configuration.

Rendering happens server-side with POST /{prompt_id}/render. It substitutes variables and returns the text — it never calls a model and never costs credits. Feed the result into POST /v1/chat/completions yourself.

Authentication

Authorization: Bearer cm_your_api_key
OperationScope
Every GET, plus POST /{prompt_id}/renderprompts:read
Every POST, PATCH, DELETE that changes stored dataprompts:write

Render is a read: it writes nothing, so it only needs prompts:read.

Limits

ThingLimit
Prompt name255 characters
Description500 characters
Template body65,536 characters
Declared variables100 per version
Variables sent to render100 keys, each string value at most 8,000 characters
Label64 characters
Pinned params32,000 characters when serialised
List paginationlimit 1..200 (default 50), offset 0..100000

Prompts

GET /api/v1/gateway/prompts

Newest first. Accepts limit and offset.

[
  {
    "id": "7c1e…",
    "tenant_id": "a0b1…",
    "name": "support-greeting",
    "description": "Opening turn for the WhatsApp support agent",
    "current_version": 4,
    "created_at": "2026-08-01T09:00:00Z",
    "updated_at": "2026-08-16T11:20:00Z"
  }
]

current_version is the version number the most recent POST /versions created — it is what render uses when you pass neither version nor label.

POST /api/v1/gateway/prompts

FieldTypeRequiredConstraints
namestringYes1–255 characters, not blank. Unique per tenant
descriptionstringNoAt most 500 characters

Returns 201 with the prompt. A duplicate name returns 409 A prompt named '…' already exists.

GET / PATCH / DELETE /api/v1/gateway/prompts/{prompt_id}

PATCH accepts name and description only — current_version is server-managed. DELETE returns 204 and cascades the prompt's versions; presets that pointed at one of those versions keep their pinned model and params, with prompt_version_id set to null.

404 Prompt not found for an unknown or another tenant's id.

Versions

GET /api/v1/gateway/prompts/{prompt_id}/versions

Highest version first. Accepts limit (1..200, default 50) and offset.

POST /api/v1/gateway/prompts/{prompt_id}/versions

FieldTypeRequiredConstraints
templatestringYes1–65,536 characters, not blank
variablesstring[]NoAt most 100. Each must match ^[A-Za-z_][A-Za-z0-9_.]*$. Defaults to the names the template references
modelstringNoAt most 128 characters
paramsobjectNoPinned inference parameters (see below)
labelstringNo1–64 characters
curl -X POST https://api.callmissed.com/api/v1/gateway/prompts/7c1e…/versions \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "You are {{brand}} support. Answer in {{language}}. Be brief.",
    "model": "kimi-k2.6",
    "params": { "temperature": 0.3, "max_tokens": 400 },
    "label": "production"
  }'
{
  "id": "3f9a…",
  "prompt_id": "7c1e…",
  "version": 5,
  "template": "You are {{brand}} support. Answer in {{language}}. Be brief.",
  "variables": ["brand", "language"],
  "model": "kimi-k2.6",
  "params": { "temperature": 0.3, "max_tokens": 400 },
  "label": "production",
  "created_by_user_id": null,
  "created_at": "2026-08-17T10:04:00Z"
}

Creating a version bumps the prompt's current_version. Version numbers are allocated as max + 1; under heavy concurrency the API retries and, if it still cannot allocate, returns 409 Could not allocate a version number — retry.

Reusing a label moves it: the previous holder loses it in the same transaction.

GET /api/v1/gateway/prompts/{prompt_id}/versions/{version}

One version by its integer number. 404 Prompt version not found.

POST /api/v1/gateway/prompts/{prompt_id}/versions/{version}/label

FieldTypeRequiredConstraints
labelstring or nullYes1–64 characters. null clears the label

This is the release switch: promote a tested version by pointing production at it. 409 Label '…' is already in use only fires when the label is held elsewhere and cannot be moved.

Rendering

POST /api/v1/gateway/prompts/{prompt_id}/render

Requires prompts:read. No model is called and no credits are charged.

FieldTypeRequiredConstraints
variablesobjectNoAt most 100 keys. Values may be string, number, boolean or null; strings at most 8,000 characters
versionintegerNo1..1000000
labelstringNo1–64 characters

Resolution order: version, then label, then the prompt's current_version.

curl -X POST https://api.callmissed.com/api/v1/gateway/prompts/7c1e…/render \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "label": "production", "variables": { "brand": "Acme", "language": "Hindi" } }'
{
  "prompt_id": "7c1e…",
  "version": 5,
  "rendered": "You are Acme support. Answer in Hindi. Be brief.",
  "missing_variables": [],
  "model": "kimi-k2.6",
  "params": { "temperature": 0.3, "max_tokens": 400 }
}

missing_variables lists placeholders the template referenced that you did not supply. Rendering does not fail on a missing variable — check the array and decide whether to proceed.

Errors: 404 Prompt not found, 404 Prompt version not found, 404 No version labelled '…', 404 Prompt has no versions yet.

Presets

A preset is a named model + parameter block. It is the reusable half of a version, useful when several prompts should share one decoding configuration.

PresetOut: id, tenant_id, name, model, params, prompt_version_id, created_at, updated_at.

MethodPathScope
GET/api/v1/gateway/prompts/presetsprompts:read
POST/api/v1/gateway/prompts/presetsprompts:write
PATCH/api/v1/gateway/prompts/presets/{preset_id}prompts:write
DELETE/api/v1/gateway/prompts/presets/{preset_id}prompts:write
FieldTypeRequiredConstraints
namestringYes1–255 characters, unique per tenant
modelstringYes1–128 characters
paramsobjectNoDefaults to {}. Allowlisted keys only
prompt_version_idUUIDNoMust be a version in your tenant

Pinnable parameters

temperature, max_tokens, top_p, top_k, frequency_penalty, presence_penalty, repetition_penalty, seed, stop, logit_bias, logprobs, top_logprobs, n, tools, tool_choice, parallel_tool_calls, response_format, structured_outputs, reasoning, reasoning_effort, provider, models, route.

Bounds match the chat completion request (for example temperature 0..2, n 1..5). Anything outside the list returns 422 Unsupported parameter(s): …; an out-of-range value returns 422 Invalid parameter value: ….

Errors

StatusWhen
403Key is missing prompts:read / prompts:write
404Prompt, version, label or preset not found in your tenant
409Duplicate prompt or preset name, label already in use, version allocation lost a race
422Blank name/template, bad variable name, unsupported or out-of-range pinned parameter, oversized params

Nothing on this page consumes credits.