Prompt management

A prompt management platform with versions, aliases and diffs.

Prompts are versioned data, not code. Every save commits an immutable version, and the production alias points at whichever one you promote — so shipping a new prompt is a promotion, not a release.

render.ts
// ask for the alias, not a version number
const { messages, tools } = await hub.prompts.render(
  'support-agent',
  'production',
  { ticket },
);

What you get

Versions, aliases, templating and an audit trail.

Immutable versions

Every save commits a new numbered version. Nothing is overwritten, so you can always read back, compare, or return to exactly what shipped last Tuesday.

Named aliases

production and staging are pointers, not copies. Promote a version and the next render through the API returns it; SDK callers pick it up within their cache window — 60 seconds by default, and configurable per client.

Server-side templating

Message sets render on the server with nunjucks, the Jinja2-style syntax: {{ variables }}, {% if %} branches, {% for %} loops and filters. No client is left string-building its own copy.

Diff and audit trail

A unified diff between any two versions, plus a newest-first record of who changed what and when — commits, promotions and renames, each naming the member. On every plan, self-hosted included, in the dashboard and over the API.

Templating

One prompt, every branch of your logic.

Templating is more than substitution. Because rendering runs nunjucks on the server, a single version can carry the tier-specific paragraph, the optional context block and the list of past tickets — instead of your code assembling three near-identical prompts.

Variables

{{ ticket }} takes the value you pass at render time. Every name the template mentions needs a value: a missing one comes back as a 400 that names it, rather than a prompt that silently rendered an empty string.

Conditions

{% if plan == "enterprise" %} … {% else %} … {% endif %} keeps one prompt where teams usually keep three. Filters and dotted access work too — {{ user.name | upper }}.

Loops

{% for msg in history %} … {% endfor %} walks a list you pass in, and {% for k, v in fields %} destructures pairs. The loop variable counts as a referenced name, so give it any value — the render never reads it.

The dashboard Preview tab binds every variable as text, so a loop over a real array is exercised against the render endpoint or an SDK rather than in Preview. A conditional-only example works in Preview as it is.

Guide: conditional logic in templates

Prompts + gateway

Send the prompt name, not the messages.

A gateway completion can carry a stored prompt reference in place of a message array. The platform renders the version the alias points at, attaches the tools bound to it, calls the model and records the version behind the answer — in one request.

What you send

A model name, plus prompt: { name, alias, variables }. Which version is live stays out of your code entirely.

What comes back

An ordinary OpenAI-shaped response, with the provider, cost and prompt version on the gateway headers and in the trace.

Or keep the two steps

Render first when your app needs the messages itself — a client-side tool loop, or a provider you call directly. Rendering does not require the gateway at all.

Reference: gateway completionsGuide: manage prompts from the SDK

In the dashboard

Everything without writing a line of code.

The API and SDKs cover the automated path. For the day-to-day, the dashboard does the same work in the browser.

  • Edit a prompt and commit a new version straight from the browser.
  • Preview a render with sample variables before you commit it.
  • Set a default model per prompt so callers never have to pass one.
  • Attach tools from the catalog — render returns them alongside the messages.
  • Promote or roll back an alias in one click, written to the audit log.
  • Export a version as portable JSON, and import it back into another team.
The AcruxCore prompt editor showing the support-reply prompt with production and staging aliases on v2, a default model, and system and user messages containing template variables.
The prompt editor: aliases on the left, message set below, and a commit that mints the next version.

Go deeper

Documentation for this piece.

Guide: version a promptGuide: conditional logic in templatesGuide: diff, export and importGuide: prompts from the SDKAPI: prompts & versionsCore concepts

The rest of the platform

It composes with the other five.

Each piece works on its own, and they get better together — a trace links back to a prompt version, a dataset is built from feedback.

GatewayAn LLM gateway that speaks OpenAI to every provider you connect. Bring your own keys; get routing, fallbacks, cost and caching.TracingLLM observability for every call — spans for model, tokens, latency and cost. Or export your own spans over OpenTelemetry.ToolsLLM tool calling from a versioned catalog: functions bound to a prompt alias and handed to the model.EvaluationAn LLM evaluation platform: score prompt versions and models on a dataset, judge live traffic on a standing rule, and optimize the next version.AuditAn audit log of every recorded action — keys, members, gateway, secrets, prompts and tools — filtered by area, event or actor.

Create your first prompt.

Commit a version, point the production alias at it, and render it by name from your app. No credit card required, and the gateway is optional.