---
title: "Append tool invocations to a call"
method: POST
path: "/v1/call/{callId}/tool-invocations"
tags: ["Call"]
---

# Append tool invocations to a call

`POST /v1/call/{callId}/tool-invocations`

## Request

- Base URL: `https://api.roark.ai`
- URL: `https://api.roark.ai/v1/call/{callId}/tool-invocations`
- Auth: HTTP bearer

Attach tool invocations that fired during a call to an already-existing call, asynchronously after the call was created. Use this when the tool-call data becomes available later than the call itself (e.g. a Roark simulation, or a call submitted via POST /v1/call before its tools were ready). Writes are idempotent: re-sending an invocation already present on the call (same tool name and timing) is skipped, so retries converge instead of double-counting. Optionally pass `metrics` to (re)score metrics over the newly attached tools, which triggers a billed metric collection job and requires the `metric:create` permission.

## Path parameters

- `callId` string, uuid, required

## Request body

- AppendToolInvocationsRequest: Attach tool invocations to an existing call, optionally (re)scoring metrics over them.
  - `toolInvocations` object[], required: Tool invocations that fired during the call, to attach to it. Max 500 per request. Re-sending an invocation already present on the call (same tool name and timing) is skipped, so retries are safe.
    - `name` string, required: Name of the tool that was invoked
    - `description` string: Description of when the tool should be invoked
    - `parameters` object, required: Parameters provided to the tool during invocation
    - `result` union, required: Result returned by the tool after execution. Can be a string or a JSON object
      - string
      - object
    - `startOffsetMs` integer, required: Offset in milliseconds from the start of the call when the tool was invoked
    - `endOffsetMs` integer: Offset in milliseconds from the start of the call when the tool execution completed. Used to calculate duration of the tool execution
    - `agent` object: Metadata about the agent that invoked this tool - used to match which agent from the agents array this tool invocation belongs to
      - `roarkId` string, uuid: The Roark ID of the agent
      - `customId` string: The custom ID set on the agent
  - `metrics` object[]: Optional. Metric definitions to (re)score on this call after the tool invocations are attached, e.g. the Tool Invocation Analysis metrics. Triggers a metric collection job (billed, credit-gated) and requires the 'metric:create' permission. Omit to attach tools without scoring. Max 20.
    - `id` string, uuid, required

## Response `200`

Tool invocations attached to the call

- object
  - `data` AppendToolInvocationsResponse, required: Result of appending tool invocations to a call.
    - `callId` string, uuid, required: The call the tool invocations were attached to
    - `added` integer, required: Number of tool invocations newly written
    - `skipped` integer, required: Number of tool invocations skipped because an identical one (same tool and timing) already existed on the call
    - `metricCollectionJob` MetricCollectionJobResponse, required: A metric collection job that processes metrics for calls or chats
      - `id` string, uuid, required: Unique identifier of the metric collection job
      - `status` 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'CANCELED', required: Current status of the job
      - `triggeredBy` 'USER_MANUAL' | 'USER_API' | 'METRIC_POLICY' | 'SIMULATION', required: What triggered this job
      - `totalItems` integer, required: Total number of call-metric pairs to process
      - `completedItems` integer, required: Number of items that finished without failing: a value was written, or the metric did not apply to the conversation
      - `failedItems` integer, required: Number of items that could not be computed, for example because an artifact the metric reads (such as diarization) failed to generate
      - `startedAt` string, nullable, required: When the job started processing
      - `completedAt` string, nullable, required: When the job completed
      - `errorMessage` string, nullable, required: Why the job failed or, on a COMPLETED job with failedItems above 0, why those items failed
      - `policyIds` string[], required: IDs of the metric policies that triggered this job
      - `createdAt` string, required: When the job was created
      - `updatedAt` string, required: When the job was last updated
    - `metricCollectionError` string, nullable, required: Present (non-null) only when `metrics` were requested but the collection job could not be started (e.g. insufficient credits, or an unknown metric id). The tool invocations were still attached — retry scoring via POST /v1/metric/collection-jobs, or re-send this request (attaching is idempotent). Null on success or when no metrics were requested.

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `402`: Payment Required
- `403`: Forbidden
- `404`: Not Found
- `429`: Too Many Requests
- `500`: Internal Server Error

## Changes

> 187 revisions in range; 1 not diffed.

- **2026-09-04** `7d9ee4f358d1`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/roarkhq/apis/roark-analytics-api/changes/v1/call/:callId/tool-invocations/post.md)

---

[API](https://skmtc.dev/roarkhq/apis/roark-analytics-api.md) - [All operations](https://skmtc.dev/roarkhq/apis/roark-analytics-api/llms.txt) - [OpenAPI document](https://skmtc.dev/roarkhq/apis/roark-analytics-api/revisions/1a91a5c90e44?raw)
