> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Version prompts

> Track a prompt's history, restore or compare earlier versions, and keep production on a known-good version as you iterate.

Every change to a prompt creates a new version, and by default your application uses the latest one. A prompt you edit in the UI takes effect immediately, with no redeploy. To control when a change reaches production, pin a version in code or assign versions to environments.

As each prompt change creates a new version automatically, you can:

* Compare performance across versions.
* Roll back to previous versions.
* Pin experiments to specific versions.
* Track which version is used in production.

View version history in the prompt editor and select any version to restore or compare. When saving prompt changes, the update dialog shows a **Preview changes** section that displays the diff between your changes and the previous version. Large text and object diffs are truncated by default for performance. Click **Show more** to view the complete diff.

Expand **Version comment** in the update dialog to describe what changed, up to 5,000 characters. The comment is saved with that version. The field isn't available if your organization has disabled comments, since the comment wouldn't be visible afterward.

The prompt's **Activity** tab lists version history alongside any comments. Each entry that created a version shows the version it replaced next to the new one, and you can select either to view or compare it.

## Pin a specific version

Every prompt save creates a new version with a unique ID. Pin a version in production code so later saves don't affect your application until you update the pin. Both ways of [using a prompt in code](/docs/evaluate/prompts/use-in-code) accept a `version` parameter.

To pin a version you invoke on Braintrust:

<CodeGroup dropdown>
  ```typescript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import { invoke } from "braintrust";

  const result = await invoke({
    projectName: "My Project",
    slug: "summarizer",
    version: "5878bd218351fb8e", // Pin to specific version
    input: { text: "Long text to summarize..." },
  });
  ```

  ```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  from braintrust import invoke

  result = invoke(
      project_name="My Project",
      slug="summarizer",
      version="5878bd218351fb8e",  # Pin to specific version
      input={"text": "Long text to summarize..."},
  )
  ```
</CodeGroup>

To pin a version you load and run with your own LLM client:

<CodeGroup dropdown>
  ```typescript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  const prompt = await loadPrompt({
    projectName: "My Project",
    slug: "summarizer",
    version: "5878bd218351fb8e", // Pin to specific version
  });
  ```

  ```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  prompt = load_prompt("My Project", "summarizer", version="5878bd218351fb8e")
  ```

  ```go #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  p, err := bt.LoadPrompt(ctx, prompt.LoadOpts{
  	Slug:    "summarizer",
  	Version: "5878bd218351fb8e",
  })
  ```

  ```ruby theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  require "braintrust"

  prompt = Braintrust::Prompt.load(
    project: "My Project",
    slug: "summarizer",
    version: "5878bd218351fb8e" # Pin to specific version
  )

  params = prompt.build(text: "Long text to summarize...")
  ```
</CodeGroup>

Without a `version` parameter, every one of these uses the latest version.

<Tip>
  Use [`bt prompts versions`](/docs/reference/cli/prompts) to look up a prompt's version IDs from the terminal. Both short and decimal transaction IDs are accepted.
</Tip>

## Use environments

Environments separate dev, staging, and production configurations. Assign a prompt version to an environment, then load the version assigned to that environment from your code.

To assign a prompt to an environment:

<Tabs>
  <Tab title="UI" icon="mouse-pointer-2">
    1. Go to **<Icon icon="message-circle" /> Prompts**.
    2. Open the prompt.
    3. Click the <Icon icon="layers" /> icon.
    4. Select an environment.
  </Tab>

  <Tab title="CLI" icon="terminal">
    List the prompt's versions, then assign one to an environment:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    bt prompts versions my-prompt
    bt prompts assign my-prompt --version 1234 --environment production
    ```

    To remove the prompt from the environment:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    bt prompts unassign my-prompt --environment production
    ```
  </Tab>

  <Tab title="API" icon="code">
    Use [`POST /v1/prompt`](/docs/api-reference/prompts/create-prompt) or [`PUT /v1/prompt`](/docs/api-reference/prompts/create-or-replace-prompt) and pass `environment_slugs` to assign the prompt to one or more environments in a single atomic request. If any slug doesn't exist, the entire request fails and no prompt is created.

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    curl -X POST https://api.braintrust.dev/v1/prompt \
      -H "Authorization: Bearer $BRAINTRUST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "your-project-id",
        "name": "My prompt",
        "slug": "my-prompt-slug",
        "environment_slugs": ["dev", "staging"],
        "prompt_data": {
          "prompt": {
            "type": "chat",
            "messages": [{"role": "system", "content": "You are a helpful assistant"}]
          },
          "options": {
            "model": "gpt-5-mini"
          }
        }
      }'
    ```
  </Tab>
</Tabs>

Once assigned, load prompts for that environment in your code:

<Tabs>
  <Tab title="SDK" icon="code">
    <CodeGroup dropdown>
      ```typescript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      import { loadPrompt } from "braintrust";

      // Load from specific environment
      const prompt = await loadPrompt({
        projectName: "My Project",
        slug: "my-prompt",
        environment: "production",
      });

      // Use conditional versioning
      const prompt = await loadPrompt({
        projectName: "My Project",
        slug: "my-prompt",
        version: process.env.NODE_ENV === "production" ? "5878bd218351fb8e" : undefined,
      });
      ```

      ```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      from braintrust import load_prompt
      import os

      # Load from specific environment
      prompt = load_prompt(
          project="My Project",
          slug="my-prompt",
          environment="production"
      )

      # Use conditional versioning
      prompt = load_prompt(
          "My Project",
          "my-prompt",
          version="5878bd218351fb8e" if os.environ.get("NODE_ENV") == "production" else None,
      )
      ```
    </CodeGroup>
  </Tab>

  <Tab title="API" icon="code">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    # Load by project ID and slug
    curl "https://api.braintrust.dev/v1/prompt?slug=my-prompt-slug&project_id=PROJECT_ID&environment=production" \
      -H "Authorization: Bearer $BRAINTRUST_API_KEY"

    # Load by prompt ID
    curl "https://api.braintrust.dev/v1/prompt/PROMPT_ID?environment=production" \
      -H "Authorization: Bearer $BRAINTRUST_API_KEY"
    ```
  </Tab>
</Tabs>

<Accordion title="Invoke an environment-pinned prompt with invoke()">
  `invoke()` does not accept an `environment` parameter. To execute an environment-pinned prompt server-side via `invoke()`, resolve the version with `loadPrompt()` first and pass it to `invoke()`:

  ```typescript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  const prompt = await loadPrompt({
    projectName: "My Project",
    slug: "summarizer",
    environment: "production",
  });

  const result = await invoke({
    projectName: "My Project",
    slug: "summarizer",
    version: prompt.version,
    input: { text: "Long text to summarize..." },
  });
  ```

  This pins the call to the version that was assigned to the environment when `loadPrompt()` ran. Re-call `loadPrompt()` if you need to pick up environment reassignments.
</Accordion>

<Tip>
  Assigning versions to environments is how you manage different versions of a prompt across your development lifecycle. See [Manage environments](/docs/deploy/environments) for details on creating and using environments.
</Tip>

## Next steps

* [Manage environments](/docs/deploy/environments) to separate dev, staging, and production across prompts, datasets, and functions.
* [Use prompts in code](/docs/evaluate/prompts/use-in-code) to invoke pinned or environment-scoped prompts.
* [Manage prompts](/docs/evaluate/prompts/manage) to duplicate prompts and customize the **Prompts** page.
* [Monitor deployments](/docs/deploy/monitor) to track prompt performance in production.
