## Modify Feedback For Step

**patch** `/v1/steps/{step_id}/feedback`

Modify feedback for a given step.

### Path Parameters

- `step_id: string`

  The ID of the step in the format 'step-<uuid4>'

### Body Parameters

- `feedback: optional "positive" or "negative"`

  Whether this feedback is positive or negative

  - `"positive"`

  - `"negative"`

- `tags: optional array of string`

  Feedback tags to add to the step

### Returns

- `Step object { id, agent_id, cache_write_tokens, 27 more }`

  - `id: string`

    The id of the step. Assigned by the database.

  - `agent_id: optional string`

    The ID of the agent that performed the step.

  - `cache_write_tokens: optional number`

    The number of input tokens written to cache (Anthropic only). None if not reported by provider.

  - `cached_input_tokens: optional number`

    The number of input tokens served from cache. None if not reported by provider.

  - `completion_tokens: optional number`

    The number of tokens generated by the agent during this step.

  - `completion_tokens_details: optional map[unknown]`

    Detailed completion token breakdown (e.g., reasoning_tokens).

  - `context_window_limit: optional number`

    The context window limit configured for this step.

  - `error_data: optional map[unknown]`

    Error details including message, traceback, and additional context

  - `error_type: optional string`

    The type/class of the error that occurred

  - `feedback: optional "positive" or "negative"`

    The feedback for this step. Must be either 'positive' or 'negative'.

    - `"positive"`

    - `"negative"`

  - `messages: optional array of InternalMessage`

    The messages generated during this step. Deprecated: use `GET /v1/steps/{step_id}/messages` endpoint instead

    - `id: string`

      The human-friendly ID of the Message

    - `role: MessageRole`

      The role of the participant.

      - `"assistant"`

      - `"user"`

      - `"tool"`

      - `"function"`

      - `"system"`

      - `"approval"`

      - `"summary"`

    - `agent_id: optional string`

      The unique identifier of the agent.

    - `approval_request_id: optional string`

      The id of the approval request if this message is associated with a tool call request.

    - `approvals: optional array of ApprovalReturn or object { status, func_response, stderr, 2 more }`

      The list of approvals for this message.

      - `ApprovalReturn object { approve, tool_call_id, reason, type }`

        - `approve: boolean`

          Whether the tool has been approved

        - `tool_call_id: string`

          The ID of the tool call that corresponds to this approval

        - `reason: optional string`

          An optional explanation for the provided approval status

        - `type: optional "approval"`

          The message type to be created.

          - `"approval"`

      - `LettaSchemasMessageToolReturnOutput object { status, func_response, stderr, 2 more }`

        - `status: "success" or "error"`

          The status of the tool call

          - `"success"`

          - `"error"`

        - `func_response: optional string or array of TextContent or ImageContent`

          The function response - either a string or list of content parts (text/image)

          - `string`

          - `array of TextContent or ImageContent`

            - `TextContent object { text, signature, type }`

              - `text: string`

                The text content of the message.

              - `signature: optional string`

                Stores a unique identifier for any reasoning associated with this text content.

              - `type: optional "text"`

                The type of the message.

                - `"text"`

            - `ImageContent object { source, type }`

              - `source: object { url, type }  or object { data, media_type, detail, type }  or object { file_id, data, detail, 2 more }`

                The source of the image.

                - `URL object { url, type }`

                  - `url: string`

                    The URL of the image.

                  - `type: optional "url"`

                    The source type for the image.

                    - `"url"`

                - `Base64 object { data, media_type, detail, type }`

                  - `data: string`

                    The base64 encoded image data.

                  - `media_type: string`

                    The media type for the image.

                  - `detail: optional string`

                    What level of detail to use when processing and understanding the image (low, high, or auto to let the model decide)

                  - `type: optional "base64"`

                    The source type for the image.

                    - `"base64"`

                - `Letta object { file_id, data, detail, 2 more }`

                  - `file_id: string`

                    The unique identifier of the image file persisted in storage.

                  - `data: optional string`

                    The base64 encoded image data.

                  - `detail: optional string`

                    What level of detail to use when processing and understanding the image (low, high, or auto to let the model decide)

                  - `media_type: optional string`

                    The media type for the image.

                  - `type: optional "letta"`

                    The source type for the image.

                    - `"letta"`

              - `type: optional "image"`

                The type of the message.

                - `"image"`

        - `stderr: optional array of string`

          Captured stderr from the tool invocation

        - `stdout: optional array of string`

          Captured stdout (e.g. prints, logs) from the tool invocation

        - `tool_call_id: optional unknown`

          The ID for the tool call

    - `approve: optional boolean`

      Whether tool call is approved.

    - `batch_item_id: optional string`

      The id of the LLMBatchItem that this message is associated with

    - `content: optional array of TextContent or ImageContent or ToolCallContent or 5 more`

      The content of the message.

      - `TextContent object { text, signature, type }`

      - `ImageContent object { source, type }`

      - `ToolCallContent object { id, input, name, 2 more }`

        - `id: string`

          A unique identifier for this specific tool call instance.

        - `input: map[unknown]`

          The parameters being passed to the tool, structured as a dictionary of parameter names to values.

        - `name: string`

          The name of the tool being called.

        - `signature: optional string`

          Stores a unique identifier for any reasoning associated with this tool call.

        - `type: optional "tool_call"`

          Indicates this content represents a tool call event.

          - `"tool_call"`

      - `ToolReturnContent object { content, is_error, tool_call_id, type }`

        - `content: string`

          The content returned by the tool execution.

        - `is_error: boolean`

          Indicates whether the tool execution resulted in an error.

        - `tool_call_id: string`

          References the ID of the ToolCallContent that initiated this tool call.

        - `type: optional "tool_return"`

          Indicates this content represents a tool return event.

          - `"tool_return"`

      - `ReasoningContent object { is_native, reasoning, signature, type }`

        Sent via the Anthropic Messages API

        - `is_native: boolean`

          Whether the reasoning content was generated by a reasoner model that processed this step.

        - `reasoning: string`

          The intermediate reasoning or thought process content.

        - `signature: optional string`

          A unique identifier for this reasoning step.

        - `type: optional "reasoning"`

          Indicates this is a reasoning/intermediate step.

          - `"reasoning"`

      - `RedactedReasoningContent object { data, type }`

        Sent via the Anthropic Messages API

        - `data: string`

          The redacted or filtered intermediate reasoning content.

        - `type: optional "redacted_reasoning"`

          Indicates this is a redacted thinking step.

          - `"redacted_reasoning"`

      - `OmittedReasoningContent object { signature, type }`

        A placeholder for reasoning content we know is present, but isn't returned by the provider (e.g. OpenAI GPT-5 on ChatCompletions)

        - `signature: optional string`

          A unique identifier for this reasoning step.

        - `type: optional "omitted_reasoning"`

          Indicates this is an omitted reasoning step.

          - `"omitted_reasoning"`

      - `SummarizedReasoning object { id, summary, encrypted_content, type }`

        The style of reasoning content returned by the OpenAI Responses API

        - `id: string`

          The unique identifier for this reasoning step.

        - `summary: array of object { index, text }`

          Summaries of the reasoning content.

          - `index: number`

            The index of the summary part.

          - `text: string`

            The text of the summary part.

        - `encrypted_content: optional string`

          The encrypted reasoning content.

        - `type: optional "summarized_reasoning"`

          Indicates this is a summarized reasoning step.

          - `"summarized_reasoning"`

    - `conversation_id: optional string`

      The conversation this message belongs to

    - `created_at: optional string`

      The timestamp when the object was created.

    - `created_by_id: optional string`

      The id of the user that made this object.

    - `denial_reason: optional string`

      The reason the tool call request was denied.

    - `group_id: optional string`

      The multi-agent group that the message was sent in

    - `is_err: optional boolean`

      Whether this message is part of an error step. Used only for debugging purposes.

    - `last_updated_by_id: optional string`

      The id of the user that made this object.

    - `model: optional string`

      The model used to make the function call.

    - `name: optional string`

      For role user/assistant: the (optional) name of the participant. For role tool/function: the name of the function called.

    - `otid: optional string`

      The offline threading id associated with this message

    - `run_id: optional string`

      The id of the run that this message was created in.

    - `sender_id: optional string`

      The id of the sender of the message, can be an identity id or agent id

    - `step_id: optional string`

      The id of the step that this message was created in.

    - `tool_call_id: optional string`

      The ID of the tool call. Only applicable for role tool.

    - `tool_calls: optional array of object { id, function, type }`

      The list of tool calls requested. Only applicable for role assistant.

      - `id: string`

      - `function: object { arguments, name }`

        The function that the model called.

        - `arguments: string`

        - `name: string`

      - `type: "function"`

        - `"function"`

    - `tool_returns: optional array of object { status, func_response, stderr, 2 more }`

      Tool execution return information for prior tool calls

      - `status: "success" or "error"`

        The status of the tool call

        - `"success"`

        - `"error"`

      - `func_response: optional string or array of TextContent or ImageContent`

        The function response - either a string or list of content parts (text/image)

        - `string`

        - `array of TextContent or ImageContent`

          - `TextContent object { text, signature, type }`

          - `ImageContent object { source, type }`

      - `stderr: optional array of string`

        Captured stderr from the tool invocation

      - `stdout: optional array of string`

        Captured stdout (e.g. prints, logs) from the tool invocation

      - `tool_call_id: optional unknown`

        The ID for the tool call

    - `updated_at: optional string`

      The timestamp when the object was last updated.

  - `model: optional string`

    The name of the model used for this step.

  - `model_endpoint: optional string`

    The model endpoint url used for this step.

  - `model_handle: optional string`

    The model handle (e.g., 'openai/gpt-4o-mini') used for this step.

  - `origin: optional string`

    The surface that this agent step was initiated from.

  - `project_id: optional string`

    The project that the agent that executed this step belongs to (cloud only).

  - `prompt_tokens: optional number`

    The number of tokens in the prompt during this step.

  - `prompt_tokens_details: optional map[unknown]`

    Detailed prompt token breakdown (e.g., cached_tokens, cache_read_tokens, cache_creation_tokens).

  - `provider_category: optional string`

    The category of the provider used for this step.

  - `provider_id: optional string`

    The unique identifier of the provider that was configured for this step

  - `provider_name: optional string`

    The name of the provider used for this step.

  - `reasoning_tokens: optional number`

    The number of reasoning/thinking tokens generated. None if not reported by provider.

  - `request_id: optional string`

    The API request log ID from cloud-api for correlating steps with API requests.

  - `run_id: optional string`

    The unique identifier of the run that this step belongs to. Only included for async calls.

  - `status: optional "pending" or "success" or "failed" or "cancelled"`

    Status of a step execution

    - `"pending"`

    - `"success"`

    - `"failed"`

    - `"cancelled"`

  - `stop_reason: optional StopReasonType`

    The stop reason associated with the step.

    - `"end_turn"`

    - `"error"`

    - `"llm_api_error"`

    - `"invalid_llm_response"`

    - `"invalid_tool_call"`

    - `"max_steps"`

    - `"max_tokens_exceeded"`

    - `"no_tool_call"`

    - `"tool_rule"`

    - `"cancelled"`

    - `"insufficient_credits"`

    - `"requires_approval"`

    - `"context_window_overflow_in_system_prompt"`

  - `tags: optional array of string`

    Metadata tags.

  - `tid: optional string`

    The unique identifier of the transaction that processed this step.

  - `total_tokens: optional number`

    The total number of tokens processed by the agent during this step.

  - `trace_id: optional string`

    The trace id of the agent step.

### Example

```http
curl https://api.letta.com/v1/steps/$STEP_ID/feedback \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $LETTA_API_KEY" \
    -d '{}'
```

#### Response

```json
{
  "id": "id",
  "agent_id": "agent_id",
  "cache_write_tokens": 0,
  "cached_input_tokens": 0,
  "completion_tokens": 0,
  "completion_tokens_details": {
    "foo": "bar"
  },
  "context_window_limit": 0,
  "error_data": {
    "foo": "bar"
  },
  "error_type": "error_type",
  "feedback": "positive",
  "messages": [
    {
      "id": "message-123e4567-e89b-12d3-a456-426614174000",
      "role": "assistant",
      "agent_id": "agent_id",
      "approval_request_id": "approval_request_id",
      "approvals": [
        {
          "approve": true,
          "tool_call_id": "tool_call_id",
          "reason": "reason",
          "type": "approval"
        }
      ],
      "approve": true,
      "batch_item_id": "batch_item_id",
      "content": [
        {
          "text": "text",
          "signature": "signature",
          "type": "text"
        }
      ],
      "conversation_id": "conversation_id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "created_by_id": "created_by_id",
      "denial_reason": "denial_reason",
      "group_id": "group_id",
      "is_err": true,
      "last_updated_by_id": "last_updated_by_id",
      "model": "model",
      "name": "name",
      "otid": "otid",
      "run_id": "run_id",
      "sender_id": "sender_id",
      "step_id": "step_id",
      "tool_call_id": "tool_call_id",
      "tool_calls": [
        {
          "id": "id",
          "function": {
            "arguments": "arguments",
            "name": "name"
          },
          "type": "function"
        }
      ],
      "tool_returns": [
        {
          "status": "success",
          "func_response": "string",
          "stderr": [
            "string"
          ],
          "stdout": [
            "string"
          ],
          "tool_call_id": {}
        }
      ],
      "updated_at": "2019-12-27T18:11:19.117Z"
    }
  ],
  "model": "model",
  "model_endpoint": "model_endpoint",
  "model_handle": "model_handle",
  "origin": "origin",
  "project_id": "project_id",
  "prompt_tokens": 0,
  "prompt_tokens_details": {
    "foo": "bar"
  },
  "provider_category": "provider_category",
  "provider_id": "provider_id",
  "provider_name": "provider_name",
  "reasoning_tokens": 0,
  "request_id": "request_id",
  "run_id": "run_id",
  "status": "pending",
  "stop_reason": "end_turn",
  "tags": [
    "string"
  ],
  "tid": "tid",
  "total_tokens": 0,
  "trace_id": "trace_id"
}
```
