> For the complete documentation index, see [llms.txt](https://docs.concurrence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.concurrence.com/developer-guide/platform-api/safety/trace-export.md).

# Trace Export

Export durable tool-call and supported voice operational spans as OTLP/JSON for external observability collectors.

The trace export endpoint lets you pull a workspace's durable `gen_ai.*` tool-call spans and supported `voice.*` operational spans as OpenTelemetry Protocol (OTLP/HTTP JSON). It is a read-only, paginated pull API for external observability collectors and partner monitoring stacks. Treat emitter names and voice-runtime attributes as opaque implementation metadata rather than stable topology identifiers.

Tool calls in voice calls, text conversations, and simulations are exported as `execute_tool` spans. A trace ID can cover more than one session: the tool calls of one simulation run, for example, can share a trace across its steps, sessions, and forks. Don't treat one trace as one conversation.

## Endpoint

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/traces:export" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

Trace spans carry tool-call metadata, so this endpoint requires `Audit:View`, which the admin and owner roles carry. A request covers spans from `start_time`, inclusive, up to `end_time`, exclusive.

### Example Request

```json
{
  "start_time": "2026-07-01T00:00:00Z",
  "end_time": "2026-07-02T00:00:00Z",
  "limit": 100
}
```

## Response Body

The response is a paginated pull envelope: a `resourceSpans` array of OTLP/JSON `ResourceSpans` (empty when no spans match), a `has_more` boolean indicating whether additional pages are available, and an opaque `continuation_token` cursor (`null` when no more pages). See the endpoint schema above for the full response shape.

### Example Response (abridged)

```json
{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          { "key": "amigo.workspace.id", "value": { "stringValue": "abc123-..." } }
        ]
      },
      "scopeSpans": [
        {
          "spans": [
            {
              "traceId": "00000000000000000123456789abcdef",
              "spanId": "0123456789abcdef",
              "name": "execute_tool get_schedule",
              "kind": 3,
              "startTimeUnixNano": "1719792000000000000",
              "endTimeUnixNano": "1719792000500000000",
              "attributes": [
                { "key": "gen_ai.operation.name", "value": { "stringValue": "execute_tool" } },
                { "key": "gen_ai.tool.name", "value": { "stringValue": "get_schedule" } },
                { "key": "latency_ms", "value": { "intValue": "500" } },
                { "key": "success", "value": { "boolValue": true } }
              ],
              "status": { "code": 1 }
            }
          ]
        }
      ]
    }
  ],
  "has_more": false,
  "continuation_token": null
}
```

## OTLP/JSON Encoding

The response follows OTLP/HTTP JSON encoding conventions:

* **Integer values** (timestamps, `intValue`) are encoded as decimal strings.
* **Trace IDs** are 32 lowercase hex characters (16 bytes).
* **Span IDs** are 16 lowercase hex characters (8 bytes).
* **`AnyValue`** uses the typed oneof encoding - exactly one of `stringValue`, `intValue`, `boolValue`, or `doubleValue` is set per value.
* **Span kind** is `3` (CLIENT) - tool calls are outbound operations.
* **Status code**: `1` = OK, `2` = ERROR.

## Exported Attributes

The endpoint uses a fixed allowlist. Customer integrations can rely on these tool-call attributes when present:

| Attribute Key             | Type    | Description                                            |
| ------------------------- | ------- | ------------------------------------------------------ |
| `gen_ai.operation.name`   | string  | The operation type (e.g., `execute_tool`).             |
| `gen_ai.tool.name`        | string  | The tool that was called.                              |
| `gen_ai.tool.integration` | string  | The integration the tool belongs to.                   |
| `gen_ai.tool.endpoint`    | string  | The endpoint within the integration.                   |
| `gen_ai.tool.protocol`    | string  | The protocol used for the tool call.                   |
| `latency_ms`              | integer | Tool call duration in milliseconds.                    |
| `success`                 | boolean | Whether the tool call succeeded.                       |
| `call_id`                 | string  | Call identifier used to correlate related trace spans. |

Supported `voice.*` spans can include additional allowlisted operational attributes. Preserve them when forwarding OTLP, but do not depend on their names or values as a resource inventory, routing signal, or stable service-topology contract.

Raw error text and any non-allowlisted fields are excluded. The `success` field and `status.code` convey failure without exposing error messages.

## Resource Metadata

Spans include the `amigo.workspace.id` resource attribute plus standard OTLP emitter and instrumentation metadata. Preserve the resource and scope objects when forwarding. Do not branch application behavior on emitter service names or instrumentation-scope identifiers because those values describe the current runtime implementation and can change.

## Forwarding to an OTLP Collector

The response is a paginated pull envelope, not a bare OTLP `ExportTraceServiceRequest`. To forward spans to an OTLP collector:

1. Extract the `resourceSpans` array from the response.
2. Wrap it as `{"resourceSpans": [...]}` to form a valid OTLP push payload.
3. POST the payload to your collector's OTLP/HTTP endpoint.

The `has_more` and `continuation_token` fields are not part of the OTLP spec and should be stripped before forwarding.

## Pagination

Use cursor-based pagination to retrieve all spans in a time window:

1. Send the initial request without `continuation_token`.
2. If `has_more` is `true`, send another request with the returned `continuation_token`.
3. Repeat until `has_more` is `false`.

## Errors

A few endpoint-specific conditions are worth calling out beyond the schema above:

* **403** - The credential lacks `Audit:View`, or the workspace ID does not match the key.
* **422** - Invalid request body, such as `end_time` before `start_time` or an invalid `continuation_token`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.concurrence.com/developer-guide/platform-api/safety/trace-export.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
