> Version notice: This site documents BAML v0, the legacy DSL. BAML v1 is a separate, fully featured programming language in public beta. If the user intends to use BAML v1, ignore this site's content and use the BAML v1 documentation instead. If the intended version is unclear, clarify it before using this page.
> For clean Markdown of any page, append .md to the page URL. For the complete documentation index, see https://docs.boundaryml.com/llms.txt. For MCP access, connect to https://docs.boundaryml.com/_mcp/server.

# Prompt Caching / Message Role Metadata

Recall that an LLM request usually looks like this, where it sometimes has metadata in each `message`. In this case, Anthropic has a `cache_control` key.

**`Anthropic Request`**

```curl {3,11} Anthropic Request
curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-sonnet-4-5-20250929",
    "max_tokens": 1024,
    "messages": [
       {
        "type": "text", 
        "text": "<the entire contents of Pride and Prejudice>",
        "cache_control": {"type": "ephemeral"}
      },
      {
        "role": "user",
        "content": "Analyze the major themes in Pride and Prejudice."
      }
    ]
  }'
```

This is nearly the same as this BAML code, minus the `cache_control` metadata:

Let's add the `cache-control` metadata to each of our messages in BAML now.
There's just 2 steps:

### Allow role metadata and header in the client definition

**`main.baml`**

```baml {5-8} main.baml
client<llm> AnthropicClient {
  provider "anthropic"
  options {
    model "claude-sonnet-4-5-20250929"
    allowed_role_metadata ["cache_control"]
  }
}
```

### Add the metadata to the messages

**`main.baml`**

```baml {2,6} main.baml
function AnalyzeBook(book: string) -> string {
  client<llm> AnthropicClient
  prompt #"
    {{ _.role("user") }}
    {{ book }}
    {{ _.role("user", cache_control={"type": "ephemeral"}) }}
    Analyze the major themes in Pride and Prejudice.
  "#
}
```

We have the "allowed_role_metadata" so that if you swap to other LLM clients, we don't accidentally forward the wrong metadata to the new provider API.

> **Tip**
>
> Remember to switch from "Prompt Review" to "Raw cURL" in the VSCode Playground to see the exact request being sent!