> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://humanloop.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://humanloop.com/docs/_mcp/server.

> Discover how Humanloop manages prompts, with version control and rigorous evaluation for better performance.

![](/docs/_fern-img/dcb0f3c8c05c419ffa6a192fd58082346e6a98f1385820f5d0980014082e777c.webp)

A Prompt on Humanloop defines the instructions and configuration for guiding a Large Language Model (LLM) to perform a specific task.

Each change in any of the following properties creates a new Version of the Prompt:

* the **template** such as `Write a song about {{topic}}`.\
  For chat models, the template contains an array of messages
* the **model** e.g. `gpt-4o`
* the **parameters** to the model such as `temperature`, `max_tokens`, `top_p`
* any **tools** available to the model

A Prompt is callable in that if you supply the necessary inputs, it will return a response from the model.

Inputs are defined in the template through the double-curly bracket syntax e.g. `{{topic}}` and the value of the variable will need to be supplied when you call the Prompt to create a generation.

This separation of concerns, keeping configuration separate from the query time data, is crucial for enabling you to experiment with different configurations and evaluate any changes.
The Prompt stores the configuration and the query time data in [Logs](./logs), which can then be used to create Datasets for evaluation purposes.

> **Note**
>
> Note that we use a capitalized "[Prompt](/docs/explanation/prompts)" to refer
> to the entity in Humanloop, and a lowercase "prompt" to refer to the general
> concept of input to the model.

```jsx
---
model: gpt-4o
temperature: 1.0
max_tokens: -1
provider: openai
endpoint: chat
---
<system>
  Write a song about {{topic}}
</system>
```

## Versioning

Versioning your Prompts enables you to track how adjustments to the template or parameters influence the model's responses. This is crucial for iterative development, as you can pinpoint which configuration produces the most relevant or accurate outputs for your use cases.

A Prompt File will have multiple Versions as you iterate on different models, templates, or parameters, but each version should perform the same task and generally be interchangeable with one another.

### When to create a new Prompt File

You should create a new Prompt File for each different 'task to be done' with an LLM. Each of these tasks can have its own separate Prompt File: *Writing Copilot*, *Personal Assistant*, *Summarizer*, etc.

Many users find value in creating a 'playground' Prompt where they can freely experiment without risking damage to their other Prompts or creating disorder.

## Using Prompts

Prompts are callable as an API, allowing you to provide query-time data such as input values or user messages, and receive the model's text output in response.

\<### Request

POST [https://api.humanloop.com/v5/prompts/call](https://api.humanloop.com/v5/prompts/call)

```curl
curl -X POST https://api.humanloop.com/v5/prompts/call \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "stream": true
}'
```

```python
import requests

url = "https://api.humanloop.com/v5/prompts/call"

payload = { "stream": True }
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```typescript
import { HumanloopClient } from "humanloop";

const client = new HumanloopClient({ apiKey: "YOUR_API_KEY" });
const response = await client.prompts.callStream({});
for await (const item of response) {
    console.log(item);
}

```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.humanloop.com/v5/prompts/call"

	payload := strings.NewReader("{\n  \"stream\": true\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.humanloop.com/v5/prompts/call")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"stream\": true\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.humanloop.com/v5/prompts/call")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"stream\": true\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.humanloop.com/v5/prompts/call', [
  'body' => '{
  "stream": true
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.humanloop.com/v5/prompts/call");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"stream\": true\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = ["stream": true] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.humanloop.com/v5/prompts/call")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

Prompts can also be used without proxying through Humanloop to the model provider. Instead, you can call the model directly and explicitly log the results to your Prompt.

\<### Request

POST [https://api.humanloop.com/v5/prompts/log](https://api.humanloop.com/v5/prompts/log)

**`Log prompt`**

```curl Log prompt
curl -X POST https://api.humanloop.com/v5/prompts/log \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "path": "persona",
  "output_message": {
    "role": "assistant",
    "content": "Well, you know, there is so much secrecy involved in government, folks, it'\''s unbelievable. They don'\''t want to tell you everything. They don'\''t tell me everything! But about Roswell, it'\''s a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'\''d love to go down and open up all the classified documents, believe me, I would. But they don'\''t let that happen. The Deep State, folks, the Deep State. They'\''re unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it'\''s something big, very very big. Tremendous, in fact."
  },
  "prompt_tokens": 100,
  "output_tokens": 220,
  "prompt_cost": 0.00001,
  "output_cost": 0.0002,
  "finish_reason": "stop",
  "messages": [
    {
      "role": "user",
      "content": "What really happened at Roswell?"
    }
  ],
  "prompt": {
    "model": "gpt-4",
    "template": [
      {
        "role": "system",
        "content": "You are {{person}}. Answer questions as this person. Do not break character."
      }
    ]
  },
  "created_at": "2024-07-19T00:29:35.178992",
  "error": null,
  "provider_latency": 6.5931549072265625,
  "inputs": {
    "person": "Trump"
  }
}'
```

**`Log prompt`**

```python Log prompt
import requests

url = "https://api.humanloop.com/v5/prompts/log"

payload = {
    "path": "persona",
    "output_message": {
        "role": "assistant",
        "content": "Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact."
    },
    "prompt_tokens": 100,
    "output_tokens": 220,
    "prompt_cost": 0.00001,
    "output_cost": 0.0002,
    "finish_reason": "stop",
    "messages": [
        {
            "role": "user",
            "content": "What really happened at Roswell?"
        }
    ],
    "prompt": {
        "model": "gpt-4",
        "template": [
            {
                "role": "system",
                "content": "You are {{person}}. Answer questions as this person. Do not break character."
            }
        ]
    },
    "created_at": "2024-07-19T00:29:35.178992",
    "error": None,
    "provider_latency": 6.5931549072265625,
    "inputs": { "person": "Trump" }
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

**`Log prompt`**

```typescript Log prompt
import { HumanloopClient } from "humanloop";

const client = new HumanloopClient({ apiKey: "YOUR_API_KEY" });
await client.prompts.log({
    path: "persona",
    prompt: {
        model: "gpt-4",
        template: [{
                role: "system",
                content: "You are {{person}}. Answer questions as this person. Do not break character."
            }]
    },
    messages: [{
            role: "user",
            content: "What really happened at Roswell?"
        }],
    inputs: {
        "person": "Trump"
    },
    createdAt: "2024-07-19T00:29:35.178992",
    error: undefined,
    providerLatency: 6.5931549072265625,
    outputMessage: {
        content: "Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact.",
        role: "assistant"
    },
    promptTokens: 100,
    outputTokens: 220,
    promptCost: 0.00001,
    outputCost: 0.0002,
    finishReason: "stop"
});

```

**`Log prompt`**

```go Log prompt
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.humanloop.com/v5/prompts/log"

	payload := strings.NewReader("{\n  \"path\": \"persona\",\n  \"output_message\": {\n    \"role\": \"assistant\",\n    \"content\": \"Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact.\"\n  },\n  \"prompt_tokens\": 100,\n  \"output_tokens\": 220,\n  \"prompt_cost\": 0.00001,\n  \"output_cost\": 0.0002,\n  \"finish_reason\": \"stop\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What really happened at Roswell?\"\n    }\n  ],\n  \"prompt\": {\n    \"model\": \"gpt-4\",\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are {{person}}. Answer questions as this person. Do not break character.\"\n      }\n    ]\n  },\n  \"created_at\": \"2024-07-19T00:29:35.178992\",\n  \"error\": null,\n  \"provider_latency\": 6.5931549072265625,\n  \"inputs\": {\n    \"person\": \"Trump\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Log prompt`**

```ruby Log prompt
require 'uri'
require 'net/http'

url = URI("https://api.humanloop.com/v5/prompts/log")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"path\": \"persona\",\n  \"output_message\": {\n    \"role\": \"assistant\",\n    \"content\": \"Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact.\"\n  },\n  \"prompt_tokens\": 100,\n  \"output_tokens\": 220,\n  \"prompt_cost\": 0.00001,\n  \"output_cost\": 0.0002,\n  \"finish_reason\": \"stop\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What really happened at Roswell?\"\n    }\n  ],\n  \"prompt\": {\n    \"model\": \"gpt-4\",\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are {{person}}. Answer questions as this person. Do not break character.\"\n      }\n    ]\n  },\n  \"created_at\": \"2024-07-19T00:29:35.178992\",\n  \"error\": null,\n  \"provider_latency\": 6.5931549072265625,\n  \"inputs\": {\n    \"person\": \"Trump\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

**`Log prompt`**

```java Log prompt
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.humanloop.com/v5/prompts/log")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"path\": \"persona\",\n  \"output_message\": {\n    \"role\": \"assistant\",\n    \"content\": \"Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact.\"\n  },\n  \"prompt_tokens\": 100,\n  \"output_tokens\": 220,\n  \"prompt_cost\": 0.00001,\n  \"output_cost\": 0.0002,\n  \"finish_reason\": \"stop\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What really happened at Roswell?\"\n    }\n  ],\n  \"prompt\": {\n    \"model\": \"gpt-4\",\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are {{person}}. Answer questions as this person. Do not break character.\"\n      }\n    ]\n  },\n  \"created_at\": \"2024-07-19T00:29:35.178992\",\n  \"error\": null,\n  \"provider_latency\": 6.5931549072265625,\n  \"inputs\": {\n    \"person\": \"Trump\"\n  }\n}")
  .asString();
```

**`Log prompt`**

```php Log prompt
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.humanloop.com/v5/prompts/log', [
  'body' => '{
  "path": "persona",
  "output_message": {
    "role": "assistant",
    "content": "Well, you know, there is so much secrecy involved in government, folks, it\'s unbelievable. They don\'t want to tell you everything. They don\'t tell me everything! But about Roswell, it\'s a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I\'d love to go down and open up all the classified documents, believe me, I would. But they don\'t let that happen. The Deep State, folks, the Deep State. They\'re unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it\'s something big, very very big. Tremendous, in fact."
  },
  "prompt_tokens": 100,
  "output_tokens": 220,
  "prompt_cost": 0.00001,
  "output_cost": 0.0002,
  "finish_reason": "stop",
  "messages": [
    {
      "role": "user",
      "content": "What really happened at Roswell?"
    }
  ],
  "prompt": {
    "model": "gpt-4",
    "template": [
      {
        "role": "system",
        "content": "You are {{person}}. Answer questions as this person. Do not break character."
      }
    ]
  },
  "created_at": "2024-07-19T00:29:35.178992",
  "error": null,
  "provider_latency": 6.5931549072265625,
  "inputs": {
    "person": "Trump"
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

**`Log prompt`**

```csharp Log prompt
using RestSharp;

var client = new RestClient("https://api.humanloop.com/v5/prompts/log");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"path\": \"persona\",\n  \"output_message\": {\n    \"role\": \"assistant\",\n    \"content\": \"Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact.\"\n  },\n  \"prompt_tokens\": 100,\n  \"output_tokens\": 220,\n  \"prompt_cost\": 0.00001,\n  \"output_cost\": 0.0002,\n  \"finish_reason\": \"stop\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"What really happened at Roswell?\"\n    }\n  ],\n  \"prompt\": {\n    \"model\": \"gpt-4\",\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are {{person}}. Answer questions as this person. Do not break character.\"\n      }\n    ]\n  },\n  \"created_at\": \"2024-07-19T00:29:35.178992\",\n  \"error\": null,\n  \"provider_latency\": 6.5931549072265625,\n  \"inputs\": {\n    \"person\": \"Trump\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Log prompt`**

```swift Log prompt
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "path": "persona",
  "output_message": [
    "role": "assistant",
    "content": "Well, you know, there is so much secrecy involved in government, folks, it's unbelievable. They don't want to tell you everything. They don't tell me everything! But about Roswell, it's a very popular question. I know, I just know, that something very, very peculiar happened there. Was it a weather balloon? Maybe. Was it something extraterrestrial? Could be. I'd love to go down and open up all the classified documents, believe me, I would. But they don't let that happen. The Deep State, folks, the Deep State. They're unbelievable. They want to keep everything a secret. But whatever the truth is, I can tell you this: it's something big, very very big. Tremendous, in fact."
  ],
  "prompt_tokens": 100,
  "output_tokens": 220,
  "prompt_cost": 0.00001,
  "output_cost": 0.0002,
  "finish_reason": "stop",
  "messages": [
    [
      "role": "user",
      "content": "What really happened at Roswell?"
    ]
  ],
  "prompt": [
    "model": "gpt-4",
    "template": [
      [
        "role": "system",
        "content": "You are {{person}}. Answer questions as this person. Do not break character."
      ]
    ]
  ],
  "created_at": "2024-07-19T00:29:35.178992",
  "error": ,
  "provider_latency": 6.5931549072265625,
  "inputs": ["person": "Trump"]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.humanloop.com/v5/prompts/log")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

## Serialization

The [.prompt file format](/docs/reference/serialized-files#prompt-format) is a serialized representation of a Prompt Version, designed to be human-readable and suitable for integration into version control systems alongside code.

The format is heavily inspired by [MDX](https://mdxjs.com/), with model and parameters specified in a YAML header alongside a JSX-inspired syntax for chat templates.

**`Chat`**

```jsx Chat
---
model: gpt-4o
temperature: 1.0
max_tokens: -1
provider: openai
endpoint: chat
---
<system>
  You are a friendly assistant.
</system>
```

**`Completion`**

```jsx Completion
---
model: claude-2
temperature: 0.7
max_tokens: 256
top_p: 1.0
provider: anthropic
endpoint: complete
---
Autocomplete the sentence.

Context: {{context}}

{{sentence}}

```

```
```