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

# Update trace metadata

> Update metadata on an existing trace by trace ID. Injects a synthetic span through the standard ingestion pipeline carrying the new attributes.

## `PATCH /api/traces/{traceId}/metadata`

Update metadata on a trace after it has been created. Under the hood, this injects a synthetic span through the standard ingestion pipeline — traces remain immutable per the OpenTelemetry spec, and "updating" a trace means adding a span that carries the new attributes. This is useful for attaching labels, user identity, or custom metadata from backend processes that resolve after trace ingestion.

### Authentication

Pass your LangWatch API key in the `X-Auth-Token` header.

### Path Parameters

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `traceId` | string | Yes      | The trace ID to update |

### Request Body

```json theme={null}
{
  "metadata": {
    "user_id": "user-123",
    "customer_id": "cust-456",
    "thread_id": "thread-789",
    "labels": ["production", "reviewed"],
    "custom_key": "custom_value",
    "config": { "retries": 3, "timeout": 30 }
  }
}
```

### Metadata Fields

#### Reserved Fields

| Field         | Type      | Stored As                | Description                     |
| ------------- | --------- | ------------------------ | ------------------------------- |
| `user_id`     | string    | `langwatch.user_id`      | User identity for analytics     |
| `customer_id` | string    | `langwatch.customer_id`  | Customer identity for analytics |
| `thread_id`   | string    | `gen_ai.conversation.id` | Thread/conversation grouping    |
| `labels`      | string\[] | `langwatch.labels`       | Trace labels for filtering      |

#### Custom Fields

Any key not in the reserved list is stored as `metadata.{key}` in trace attributes. Custom fields support strings, numbers, booleans, string arrays, and JSON objects.

### Merge Semantics

* **Attribute accumulation**: the synthetic span's resource attributes are processed through the standard attribute accumulation pipeline — new keys are added, existing keys are updated by the last-write-wins rule
* **Labels**: the labels array is set as-is on the span resource. If a later span also carries labels, last write wins
* **Custom fields**: stored as `langwatch.metadata.*` resource attributes on the synthetic span

### Size Limits

| Limit                     | Value |
| ------------------------- | ----- |
| Individual metadata value | 4 KB  |
| Total metadata payload    | 32 KB |

### Permissions

Requires `traces:update` permission on the project.

### Response

```json theme={null}
{
  "traceId": "trace-abc-123"
}
```

### Error Responses

| Status | Description                                                       |
| ------ | ----------------------------------------------------------------- |
| 400    | Empty metadata object, oversized payload, or invalid field values |
| 403    | Missing `traces:update` permission                                |

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH https://app.langwatch.ai/api/traces/trace-abc-123/metadata \
    -H "X-Auth-Token: your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "metadata": {
        "user_id": "user-456",
        "labels": ["reviewed", "production"],
        "environment": "staging"
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      "https://app.langwatch.ai/api/traces/trace-abc-123/metadata",
      headers={"X-Auth-Token": "your-api-key"},
      json={
          "metadata": {
              "user_id": "user-456",
              "labels": ["reviewed", "production"],
              "environment": "staging",
          }
      },
  )
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://app.langwatch.ai/api/traces/trace-abc-123/metadata",
    {
      method: "PATCH",
      headers: {
        "X-Auth-Token": "your-api-key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        metadata: {
          user_id: "user-456",
          labels: ["reviewed", "production"],
          environment: "staging",
        },
      }),
    }
  );
  ```
</CodeGroup>

<Note>
  Custom metadata keys share the same namespace as metadata set via the SDK during trace ingestion. If both the SDK and this API set the same key, the last write wins.
</Note>
