# Traces

Send OpenTelemetry traces to Altertable when you want spans, service timing, status, attributes, events, and links to be queryable beside product, operational, and business data.

Accepted spans are written to `opentelemetry.main.spans`.

| Table                      | Description                                                             |
| -------------------------- | ----------------------------------------------------------------------- |
| `opentelemetry.main.spans` | Trace spans with service, timing, status, attributes, events, and links |

## Endpoint

Send OTLP/HTTP protobuf traces to:

```text
POST https://api.altertable.ai/v1/traces
```

Use `Content-Type: application/x-protobuf` and authenticate with the same HTTP Basic Auth credentials used by the [Lakehouse API](/docs/api-references/lakehouse.md).

```bash
curl https://api.altertable.ai/v1/traces \
  -H "Authorization: Basic $ALTERTABLE_BASIC_AUTH_TOKEN" \
  -H "Content-Type: application/x-protobuf" \
  --data-binary @traces.pb
```

## SDK and collector setup

Use the standard OpenTelemetry SDK for your application language and configure its OTLP/HTTP exporter to send traces to Altertable. The SDK handles instrumentation, batching, resource attributes, and protobuf encoding.

See the [OpenTelemetry SDK documentation](https://opentelemetry.io/docs/languages/) for language-specific setup guides.

> **Recommendation: use time-prefixed IDs:**
>
> Most OpenTelemetry SDKs generate fully random IDs. For Altertable, prefer time-prefixed IDs (AWS X-Ray style):
>
> - **Trace ID** (16 bytes): 4-byte unix seconds prefix + 12 random bytes
> - **Span ID** (8 bytes): 4-byte unix seconds prefix + 4 random bytes
>
> That trades a little entropy for time locality. Spans created in the same second share an ID prefix, so co-ingested rows cluster together and lakehouse [sorted tables](/docs/lakehouse/features/sorted-tables.md) get tighter locality and better metadata pruning.
>
> Register a custom ID generator in your OpenTelemetry SDK when your language supports it.

## Query traces

Spans are normal SQL rows once they are ingested:

```sql
SELECT
  trace_id,
  span_id,
  service_name,
  name,
  start_time,
  duration_ms,
  status_code
FROM opentelemetry.main.spans
ORDER BY start_time DESC
LIMIT 100;
```

You can also explore traces in the Altertable Explore tab with Lucene-syntax search.