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

# instance.record_tool_result

> Report what a tool returned, so Synap can anticipate the turn your agent is about to write.

<Note>
  Requires `maximem-synap` 0.5.1 or newer (Python) and
  `@maximem/synap-js-sdk` 0.5.1 or newer (JS). Earlier versions do not
  have this method, and 0.5.0 loses events sent immediately after
  `listen()`.
</Note>

<CodeGroup>
  ```python Python theme={null}
  await sdk.instance.record_tool_result(
      result,
      tool_name=None,
      tool_call_id=None,
      conversation_id=None,
      user_id=None,
      customer_id=None,
      session_id=None,
      metadata=None,
  )
  ```

  ```typescript TypeScript theme={null}
  await sdk.instance.record_tool_result(options: RecordToolResultOptions)
  ```
</CodeGroup>

<Note>
  Advanced: for real-time integrations. Requires an active [`instance.listen`](/sdk-reference/instance/listen) stream.
</Note>

`record_tool_result()` reports what a tool handed back. The result travels in its own field rather than in `content`: it is not something a person said, and `content` is the field every reader treats as speech.

<Warning>
  **A tool result is usually your customer's data.** An order, an account, a record. It reaches us, it is used as an anticipation hint, and it is not written into long-term memory. Send what your agent needs in order to be understood, not the whole row. Whatever you do send is subject to your instance's [PII policy](/guides/pii-protection) and is retained for seven days.
</Warning>

## Parameters

<ParamField path="result" type="any" required>
  JSON-encodable, or a plain string. A string is sent as itself, not as a quoted JSON string.
</ParamField>

<ParamField path="tool_name" type="string">
  The tool that produced it.
</ParamField>

<ParamField path="tool_call_id" type="string">
  The id you passed to [`record_tool_call`](/sdk-reference/instance/record-tool-call). This is what ties the result to the call that asked for it.
</ParamField>

<ParamField path="conversation_id" type="string">
  The conversation this result belongs to.
</ParamField>

<ParamField path="user_id" type="string">
  External user identifier.
</ParamField>

<ParamField path="customer_id" type="string">
  External customer identifier. Required on B2B. **Not accepted on B2C.**
</ParamField>

<ParamField path="session_id" type="string">
  External session identifier. Usually unnecessary.
</ParamField>

<ParamField path="metadata" type="dict[str, str]">
  Extra string key-value pairs.
</ParamField>

## Returns

Returns `None`.

## Example

<CodeGroup>
  ```python Python theme={null}
  await sdk.instance.record_tool_result(
      {"status": "shipped", "eta": "2026-10-02"},
      tool_name="lookup_order",
      tool_call_id="call_1",
      conversation_id=conversation_id,
      user_id="user_789",
      customer_id="cust_456",
  )
  ```

  ```typescript TypeScript theme={null}
  await sdk.instance.record_tool_result({
    result: { status: 'shipped', eta: '2026-10-02' },
    tool_name: 'lookup_order',
    tool_call_id: 'call_1',
    conversation_id: conversationId,
    user_id: 'user_789',
    customer_id: 'cust_456',
  });
  ```
</CodeGroup>

## Raises

<ResponseField name="ListeningNotActiveError" type="error">
  No stream has been started, or it has been stopped. A stream that is mid-reconnect does not raise.
</ResponseField>

## See also

* [instance.record\_tool\_call](/sdk-reference/instance/record-tool-call)
* [instance.record\_thinking](/sdk-reference/instance/record-thinking)
