> This page is for version v5.0 (default).
> For other versions, use one of these documentation indexes:
> - v5.0 (default): https://humanloop.com/docs/v5/llms.txt
> - v4.0: https://humanloop.com/docs/v4/llms.txt

> 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.

# Log to an Agent

POST https://api.humanloop.com/v5/agents/log
Content-Type: application/json

Create an Agent Log.

You can use query parameters `version_id`, or `environment`, to target
an existing version of the Agent. Otherwise, the default deployed version will be chosen.

If you create the Agent Log with a `log_status` of `incomplete`, you should later update it to `complete`
in order to trigger Evaluators.

Reference: https://humanloop.com/docs/api/agents/log

## Authentication

- `X-API-KEY` header (required) — API Key authentication via header

## Request

### Query parameters

- `version_id` (string, optional) — A specific Version ID of the Agent to log to.
- `environment` (string, optional) — Name of the Environment identifying a deployed version to log to.

### Body (application/json)

This endpoint expects an object.

- `run_id` (string, optional) — Unique identifier for the Run to associate the Log to.
- `path` (string, optional) — Path of the Agent, including the name. This locates the Agent in the Humanloop filesystem and is used as as a unique identifier. For example: `folder/name` or just `name`.
- `id` (string, optional) — ID for an existing Agent.
- `output_message` (ChatMessage, optional) — The message returned by the provider.
- `prompt_tokens` (integer, optional) — Number of tokens in the prompt used to generate the output.
- `reasoning_tokens` (integer, optional) — Number of reasoning tokens used to generate the output.
- `output_tokens` (integer, optional) — Number of tokens in the output generated by the model.
- `prompt_cost` (double, optional) — Cost in dollars associated to the tokens in the prompt.
- `output_cost` (double, optional) — Cost in dollars associated to the tokens in the output.
- `finish_reason` (string, optional) — Reason the generation finished.
- `messages` (list of ChatMessage, optional) — The messages passed to the to provider chat endpoint.
- `tool_choice` (AgentLogRequestToolChoice, optional) — Controls how the model uses tools. The following options are supported: * `'none'` means the model will not call any tool and instead generates a message; this is the default when no tools are provided as part of the Prompt. * `'auto'` means the model can decide to call one or more of the provided tools; this is the default when tools are provided as part of the Prompt. * `'required'` means the model must call one or more of the provided tools. * `{'type': 'function', 'function': {name': <TOOL_NAME>}}` forces the model to use the named function.
- `agent` (AgentLogRequestAgent, optional) — The Agent configuration to use. Two formats are supported: - An object representing the details of the Agent configuration - A string representing the raw contents of a .agent file A new Agent version will be created if the provided details do not match any existing version.
- `start_time` (datetime, optional) — When the logged event started.
- `end_time` (datetime, optional) — When the logged event ended.
- `output` (string, optional) — Generated output from your model for the provided inputs. Can be `None` if logging an error, or if creating a parent Log with the intention to populate it later.
- `created_at` (datetime, optional) — User defined timestamp for when the log was created.
- `error` (string, optional) — Error message if the log is an error.
- `provider_latency` (double, optional) — Duration of the logged event in seconds.
- `stdout` (string, optional) — Captured log and debug statements.
- `provider_request` (map from string to any, optional) — Raw request sent to provider.
- `provider_response` (map from string to any, optional) — Raw response received the provider.
- `inputs` (map from string to any, optional) — The inputs passed to the prompt template.
- `source` (string, optional) — Identifies where the model was called from.
- `metadata` (map from string to any, optional) — Any additional metadata to record.
- `source_datapoint_id` (string, optional) — Unique identifier for the Datapoint that this Log is derived from. This can be used by Humanloop to associate Logs to Evaluations. If provided, Humanloop will automatically associate this Log to Evaluations that require a Log for this Datapoint-Version pair.
- `trace_parent_id` (string, optional) — The ID of the parent Log to nest this Log under in a Trace.
- `user` (string, optional) — End-user ID related to the Log.
- `environment` (string, optional) — The name of the Environment the Log is associated to.
- `save` (boolean, optional, default: true) — Whether the request/response payloads will be stored on Humanloop.
- `log_id` (string, optional) — This will identify a Log. If you don't provide a Log ID, Humanloop will generate one for you.

## Response

### 200

Successful Response

- `id` (string, required) — Unique identifier for the Log.
- `agent_id` (string, required) — Unique identifier for the Agent.
- `version_id` (string, required) — Unique identifier for the Agent Version.
- `log_status` (enum, optional) — Status of the Agent Log. When a Agent Log is marked as `complete`, no more Logs can be added to it.
  - Allowed values: `complete`, `incomplete`

## Errors

### 422 Log Agents Log Post Request Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### ChatMessage

- `role` (enum, required) — Role of the message author.
  - Allowed values: `user`, `assistant`, `system`, `tool`, `developer`
- `content` (ChatMessageContent, optional) — The content of the message.
- `name` (string, optional) — Optional name of the message author.
- `tool_call_id` (string, optional) — Tool call that this message is responding to.
- `tool_calls` (list of ToolCall, optional) — A list of tool calls requested by the assistant.
- `thinking` (list of ChatMessageThinkingItem, optional) — Model's chain-of-thought for providing the response. Present on assistant messages if model supports it.

### AgentLogRequestToolChoice

Controls how the model uses tools. The following options are supported: * `'none'` means the model will not call any tool and instead generates a message; this is the default when no tools are provided as part of the Prompt. * `'auto'` means the model can decide to call one or more of the provided tools; this is the default when tools are provided as part of the Prompt. * `'required'` means the model must call one or more of the provided tools. * `{'type': 'function', 'function': {name': <TOOL_NAME>}}` forces the model to use the named function.

### AgentLogRequestAgent

The Agent configuration to use. Two formats are supported: - An object representing the details of the Agent configuration - A string representing the raw contents of a .agent file A new Agent version will be created if the provided details do not match any existing version.

### ValidationError

- `loc` (list of ValidationErrorLocItem, required)
- `msg` (string, required)
- `type` (string, required)

### ChatMessageContent

The content of the message.

### ToolCall

A tool call to be made.

- `id` (string, required)
- `type` ("function", required) — The type of tool to call.
- `function` (FunctionTool, required) — A function tool to be called by the model where user owns runtime.

### ChatMessageThinkingItem

### ToolChoice

Tool choice to force the model to use a tool.

- `type` ("function", required) — The type of tool to call.
- `function` (FunctionToolChoice, required) — A function tool to be called by the model where user owns runtime.

### AgentKernelRequest

Base class used by both PromptKernelRequest and AgentKernelRequest. Contains the consistent Prompt-related fields.

- `model` (string, required) — The model instance used, e.g. `gpt-4`. See [supported models](https://humanloop.com/docs/reference/supported-models)
- `endpoint` (enum, optional) — The provider model endpoint used.
  - Allowed values: `complete`, `chat`, `edit`
- `template` (AgentKernelRequestTemplate, optional) — The template contains the main structure and instructions for the model, including input variables for dynamic values. For chat models, provide the template as a ChatTemplate (a list of messages), e.g. a system message, followed by a user message with an input variable. For completion models, provide a prompt template as a string. Input variables should be specified with double curly bracket syntax: `{{input_name}}`.
- `template_language` (enum, optional) — The template language to use for rendering the template.
  - Allowed values: `default`, `jinja`
- `provider` (enum, optional) — The company providing the underlying model service.
  - Allowed values: `anthropic`, `bedrock`, `cohere`, `deepseek`, `google`, `groq`, `mock`, `openai`, `openai_azure`, `replicate`
- `max_tokens` (integer, optional, default: -1) — The maximum number of tokens to generate. Provide max_tokens=-1 to dynamically calculate the maximum number of tokens to generate given the length of the prompt
- `temperature` (double, optional, default: 1) — What sampling temperature to use when making a generation. Higher values means the model will be more creative.
- `top_p` (double, optional, default: 1) — An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass.
- `stop` (AgentKernelRequestStop, optional) — The string (or list of strings) after which the model will stop generating. The returned text will not contain the stop sequence.
- `presence_penalty` (double, optional, default: 0) — Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the generation so far.
- `frequency_penalty` (double, optional, default: 0) — Number between -2.0 and 2.0. Positive values penalize new tokens based on how frequently they appear in the generation so far.
- `other` (map from string to any, optional) — Other parameter values to be passed to the provider call.
- `seed` (integer, optional) — If specified, model will make a best effort to sample deterministically, but it is not guaranteed.
- `response_format` (ResponseFormat, optional) — The format of the response. Only `{"type": "json_object"}` is currently supported for chat.
- `reasoning_effort` (AgentKernelRequestReasoningEffort, optional) — Guidance on how many reasoning tokens it should generate before creating a response to the prompt. OpenAI reasoning models (o1, o3-mini) expect a OpenAIReasoningEffort enum. Anthropic reasoning models expect an integer, which signifies the maximum token budget.
- `tools` (list of AgentKernelRequestToolsItem, optional)
- `attributes` (map from string to any, optional) — Additional fields to describe the Prompt. Helpful to separate Prompt versions from each other with details on how they were created or used.
- `max_iterations` (integer, optional) — The maximum number of iterations the Agent can run. This is used to limit the number of times the Agent model is called.

### ValidationErrorLocItem

### FunctionTool

A function tool to be called by the model where user owns runtime.

- `name` (string, required)
- `arguments` (string, optional)

### AnthropicThinkingContent

- `type` ("thinking", required)
- `thinking` (string, required) — Model's chain-of-thought for providing the response.
- `signature` (string, required) — Cryptographic signature that verifies the thinking block was generated by Anthropic.

### AnthropicRedactedThinkingContent

- `type` ("redacted_thinking", required)
- `data` (string, required) — Thinking block Anthropic redacted for safety reasons. User is expected to pass the block back to Anthropic

### FunctionToolChoice

A function tool to be called by the model where user owns runtime.

- `name` (string, required)

### AgentKernelRequestTemplate

The template contains the main structure and instructions for the model, including input variables for dynamic values. For chat models, provide the template as a ChatTemplate (a list of messages), e.g. a system message, followed by a user message with an input variable. For completion models, provide a prompt template as a string. Input variables should be specified with double curly bracket syntax: `{{input_name}}`.

### AgentKernelRequestStop

The string (or list of strings) after which the model will stop generating. The returned text will not contain the stop sequence.

### ResponseFormat

Response format of the model.

- `type` (enum, required)
  - Allowed values: `json_object`, `json_schema`
- `json_schema` (map from string to any, optional) — The JSON schema of the response format if type is json_schema.

### AgentKernelRequestReasoningEffort

Guidance on how many reasoning tokens it should generate before creating a response to the prompt. OpenAI reasoning models (o1, o3-mini) expect a OpenAIReasoningEffort enum. Anthropic reasoning models expect an integer, which signifies the maximum token budget.

### AgentKernelRequestToolsItem

### AgentLinkedFileRequest

- `type` ("file", required)
- `link` (LinkedFileRequest, required)
- `on_agent_call` (enum, optional) — What an Agent should do when calling a Tool.
  - Allowed values: `stop`, `continue`

### AgentInlineTool

- `type` ("inline", required)
- `json_schema` (ToolFunction, required)
- `on_agent_call` (enum, optional) — What an Agent should do when calling a Tool.
  - Allowed values: `stop`, `continue`

### LinkedFileRequest

- `file_id` (string, required)
- `environment_id` (string, optional)
- `version_id` (string, optional)

### ToolFunction

- `name` (string, required) — Name for the tool referenced by the model.
- `description` (string, required) — Description of the tool referenced by the model
- `strict` (boolean, optional, default: false) — If true, forces the model to output json data in the structure of the parameters schema.
- `parameters` (map from string to any, optional) — Parameters needed to run the Tool, defined in JSON Schema format: https://json-schema.org/

## Examples

**Request**

```json
{
  "path": "Banking/Teller Agent",
  "agent": {
    "provider": "anthropic",
    "endpoint": "chat",
    "model": "claude-3-7-sonnet-latest",
    "reasoning_effort": 1024,
    "template": [
      {
        "role": "system",
        "content": "You are a helpful digital assistant, helping users navigate our digital banking platform."
      }
    ],
    "max_iterations": 3,
    "tools": [
      {
        "type": "file",
        "link": {
          "file_id": "pr_1234567890",
          "version_id": "prv_1234567890"
        },
        "on_agent_call": "continue"
      },
      {
        "type": "inline",
        "json_schema": {
          "name": "stop",
          "description": "Call this tool when you have finished your task.",
          "parameters": {
            "type": "object",
            "properties": {
              "output": {
                "type": "string",
                "description": "The final output to return to the user."
              }
            },
            "additionalProperties": false,
            "required": [
              "output"
            ]
          },
          "strict": true
        },
        "on_agent_call": "stop"
      }
    ]
  }
}
```

**Response**

```json
{
  "id": "log_1234567890",
  "agent_id": "ag_1234567890",
  "version_id": "agv_1234567890"
}
```

**SDK Code**

```python Log agent
import requests

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

payload = {
    "path": "Banking/Teller Agent",
    "agent": {
        "provider": "anthropic",
        "endpoint": "chat",
        "model": "claude-3-7-sonnet-latest",
        "reasoning_effort": 1024,
        "template": [
            {
                "role": "system",
                "content": "You are a helpful digital assistant, helping users navigate our digital banking platform."
            }
        ],
        "max_iterations": 3,
        "tools": [
            {
                "type": "file",
                "link": {
                    "file_id": "pr_1234567890",
                    "version_id": "prv_1234567890"
                },
                "on_agent_call": "continue"
            },
            {
                "type": "inline",
                "json_schema": {
                    "name": "stop",
                    "description": "Call this tool when you have finished your task.",
                    "parameters": {
                        "type": "object",
                        "properties": { "output": {
                                "type": "string",
                                "description": "The final output to return to the user."
                            } },
                        "additionalProperties": False,
                        "required": ["output"]
                    },
                    "strict": True
                },
                "on_agent_call": "stop"
            }
        ]
    }
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

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

const client = new HumanloopClient({ apiKey: "YOUR_API_KEY" });
await client.agents.log({
    path: "Banking/Teller Agent",
    agent: {
        provider: "anthropic",
        endpoint: "chat",
        model: "claude-3-7-sonnet-latest",
        reasoningEffort: 1024,
        template: [{
                role: "system",
                content: "You are a helpful digital assistant, helping users navigate our digital banking platform."
            }],
        maxIterations: 3,
        tools: [{
                type: "file",
                link: {
                    fileId: "pr_1234567890",
                    versionId: "prv_1234567890"
                },
                onAgentCall: "continue"
            }, {
                type: "inline",
                jsonSchema: {
                    name: "stop",
                    description: "Call this tool when you have finished your task.",
                    parameters: {
                        "type": "object",
                        "properties": {
                            "output": {
                                "type": "string",
                                "description": "The final output to return to the user."
                            }
                        },
                        "additionalProperties": false,
                        "required": [
                            "output"
                        ]
                    },
                    strict: true
                },
                onAgentCall: "stop"
            }]
    }
});

```

```go Log agent
package main

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

func main() {

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

	payload := strings.NewReader("{\n  \"path\": \"Banking/Teller Agent\",\n  \"agent\": {\n    \"provider\": \"anthropic\",\n    \"endpoint\": \"chat\",\n    \"model\": \"claude-3-7-sonnet-latest\",\n    \"reasoning_effort\": 1024,\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are a helpful digital assistant, helping users navigate our digital banking platform.\"\n      }\n    ],\n    \"max_iterations\": 3,\n    \"tools\": [\n      {\n        \"type\": \"file\",\n        \"link\": {\n          \"file_id\": \"pr_1234567890\",\n          \"version_id\": \"prv_1234567890\"\n        },\n        \"on_agent_call\": \"continue\"\n      },\n      {\n        \"type\": \"inline\",\n        \"json_schema\": {\n          \"name\": \"stop\",\n          \"description\": \"Call this tool when you have finished your task.\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"output\": {\n                \"type\": \"string\",\n                \"description\": \"The final output to return to the user.\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"output\"\n            ]\n          },\n          \"strict\": true\n        },\n        \"on_agent_call\": \"stop\"\n      }\n    ]\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))

}
```

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

url = URI("https://api.humanloop.com/v5/agents/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\": \"Banking/Teller Agent\",\n  \"agent\": {\n    \"provider\": \"anthropic\",\n    \"endpoint\": \"chat\",\n    \"model\": \"claude-3-7-sonnet-latest\",\n    \"reasoning_effort\": 1024,\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are a helpful digital assistant, helping users navigate our digital banking platform.\"\n      }\n    ],\n    \"max_iterations\": 3,\n    \"tools\": [\n      {\n        \"type\": \"file\",\n        \"link\": {\n          \"file_id\": \"pr_1234567890\",\n          \"version_id\": \"prv_1234567890\"\n        },\n        \"on_agent_call\": \"continue\"\n      },\n      {\n        \"type\": \"inline\",\n        \"json_schema\": {\n          \"name\": \"stop\",\n          \"description\": \"Call this tool when you have finished your task.\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"output\": {\n                \"type\": \"string\",\n                \"description\": \"The final output to return to the user.\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"output\"\n            ]\n          },\n          \"strict\": true\n        },\n        \"on_agent_call\": \"stop\"\n      }\n    ]\n  }\n}"

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

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

HttpResponse<String> response = Unirest.post("https://api.humanloop.com/v5/agents/log")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"path\": \"Banking/Teller Agent\",\n  \"agent\": {\n    \"provider\": \"anthropic\",\n    \"endpoint\": \"chat\",\n    \"model\": \"claude-3-7-sonnet-latest\",\n    \"reasoning_effort\": 1024,\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are a helpful digital assistant, helping users navigate our digital banking platform.\"\n      }\n    ],\n    \"max_iterations\": 3,\n    \"tools\": [\n      {\n        \"type\": \"file\",\n        \"link\": {\n          \"file_id\": \"pr_1234567890\",\n          \"version_id\": \"prv_1234567890\"\n        },\n        \"on_agent_call\": \"continue\"\n      },\n      {\n        \"type\": \"inline\",\n        \"json_schema\": {\n          \"name\": \"stop\",\n          \"description\": \"Call this tool when you have finished your task.\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"output\": {\n                \"type\": \"string\",\n                \"description\": \"The final output to return to the user.\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"output\"\n            ]\n          },\n          \"strict\": true\n        },\n        \"on_agent_call\": \"stop\"\n      }\n    ]\n  }\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.humanloop.com/v5/agents/log', [
  'body' => '{
  "path": "Banking/Teller Agent",
  "agent": {
    "provider": "anthropic",
    "endpoint": "chat",
    "model": "claude-3-7-sonnet-latest",
    "reasoning_effort": 1024,
    "template": [
      {
        "role": "system",
        "content": "You are a helpful digital assistant, helping users navigate our digital banking platform."
      }
    ],
    "max_iterations": 3,
    "tools": [
      {
        "type": "file",
        "link": {
          "file_id": "pr_1234567890",
          "version_id": "prv_1234567890"
        },
        "on_agent_call": "continue"
      },
      {
        "type": "inline",
        "json_schema": {
          "name": "stop",
          "description": "Call this tool when you have finished your task.",
          "parameters": {
            "type": "object",
            "properties": {
              "output": {
                "type": "string",
                "description": "The final output to return to the user."
              }
            },
            "additionalProperties": false,
            "required": [
              "output"
            ]
          },
          "strict": true
        },
        "on_agent_call": "stop"
      }
    ]
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

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

```csharp Log agent
using RestSharp;

var client = new RestClient("https://api.humanloop.com/v5/agents/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\": \"Banking/Teller Agent\",\n  \"agent\": {\n    \"provider\": \"anthropic\",\n    \"endpoint\": \"chat\",\n    \"model\": \"claude-3-7-sonnet-latest\",\n    \"reasoning_effort\": 1024,\n    \"template\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are a helpful digital assistant, helping users navigate our digital banking platform.\"\n      }\n    ],\n    \"max_iterations\": 3,\n    \"tools\": [\n      {\n        \"type\": \"file\",\n        \"link\": {\n          \"file_id\": \"pr_1234567890\",\n          \"version_id\": \"prv_1234567890\"\n        },\n        \"on_agent_call\": \"continue\"\n      },\n      {\n        \"type\": \"inline\",\n        \"json_schema\": {\n          \"name\": \"stop\",\n          \"description\": \"Call this tool when you have finished your task.\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"output\": {\n                \"type\": \"string\",\n                \"description\": \"The final output to return to the user.\"\n              }\n            },\n            \"additionalProperties\": false,\n            \"required\": [\n              \"output\"\n            ]\n          },\n          \"strict\": true\n        },\n        \"on_agent_call\": \"stop\"\n      }\n    ]\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Log agent
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "path": "Banking/Teller Agent",
  "agent": [
    "provider": "anthropic",
    "endpoint": "chat",
    "model": "claude-3-7-sonnet-latest",
    "reasoning_effort": 1024,
    "template": [
      [
        "role": "system",
        "content": "You are a helpful digital assistant, helping users navigate our digital banking platform."
      ]
    ],
    "max_iterations": 3,
    "tools": [
      [
        "type": "file",
        "link": [
          "file_id": "pr_1234567890",
          "version_id": "prv_1234567890"
        ],
        "on_agent_call": "continue"
      ],
      [
        "type": "inline",
        "json_schema": [
          "name": "stop",
          "description": "Call this tool when you have finished your task.",
          "parameters": [
            "type": "object",
            "properties": ["output": [
                "type": "string",
                "description": "The final output to return to the user."
              ]],
            "additionalProperties": false,
            "required": ["output"]
          ],
          "strict": true
        ],
        "on_agent_call": "stop"
      ]
    ]
  ]
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.humanloop.com/v5/agents/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()
```