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

# OTLP ingestion

> Send OpenTelemetry traces, metrics, and logs to AgentVista using the OTLP/HTTP protocol.

AgentVista accepts telemetry in the OpenTelemetry Protocol (OTLP) over HTTP/JSON. You can point any OpenTelemetry-compatible SDK or collector directly at AgentVista with minimal configuration.

All three OTLP signals share the same base path and authentication requirements:

* **Base URL:** `https://api.agentvista.dev/api/v1`
* **Auth:** `Authorization: Bearer <api_key>` with `write` scope
* **Content-Type:** `application/json`

<Tip>
  The `/otlp/v1` prefix matches the OTLP/HTTP convention, so you can configure an OpenTelemetry Collector or SDK exporter to use `https://api.agentvista.dev/api/v1` as the endpoint without any path customization.
</Tip>

***

## Ingest OTLP traces

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.agentvista.dev/api/v1/otlp/v1/traces \
    -H "Authorization: Bearer av_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "resourceSpans": [
        {
          "resource": {
            "attributes": [
              { "key": "service.name", "value": { "stringValue": "checkout-agent" } }
            ]
          },
          "scopeSpans": [
            {
              "spans": [
                {
                  "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
                  "spanId": "00f067aa0ba902b7",
                  "name": "process_order",
                  "kind": 2,
                  "startTimeUnixNano": "1705312800000000000",
                  "endTimeUnixNano": "1705312802000000000",
                  "status": { "code": 1 }
                }
              ]
            }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

`POST /otlp/v1/traces`

Accepts OTLP/HTTP JSON trace data. AgentVista translates the payload into its internal format and stores traces and spans alongside native SDK traces.

**Translation rules:**

* `service.name` resource attribute → Agent name (auto-created if new)
* OTLP span kinds (`SERVER`, `CLIENT`, etc.) → AgentVista span type values
* OTLP hex `traceId` / `spanId` → UUID format
* OTLP status code `2` (ERROR) → `status: "failed"`, codes `0`/`1` → `"completed"`

Returns `400` for malformed JSON or a missing `resourceSpans` key. Returns `429` if your monthly event limit is exceeded.

### Request body

<ParamField body="resourceSpans" type="object[]" required>
  OTLP `ExportTraceServiceRequest.resourceSpans` array. See the [OTLP specification](https://opentelemetry.io/docs/specs/otlp/) for the full schema.
</ParamField>

### Response — 200

<ResponseField name="accepted" type="number">
  Number of traces successfully ingested.
</ResponseField>

<ResponseField name="rejected" type="number">
  Number of traces that failed ingestion.
</ResponseField>

<ResponseField name="errors" type="object[]">
  Per-trace error objects containing `trace_id` and `error` for any rejected traces.
</ResponseField>

***

## Ingest OTLP metrics

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.agentvista.dev/api/v1/otlp/v1/metrics \
    -H "Authorization: Bearer av_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "resourceMetrics": [
        {
          "resource": {
            "attributes": [
              { "key": "service.name", "value": { "stringValue": "web-server" } }
            ]
          },
          "scopeMetrics": [
            {
              "metrics": [
                {
                  "name": "system.cpu.utilization",
                  "description": "CPU utilization as a fraction of capacity",
                  "unit": "1",
                  "gauge": {
                    "dataPoints": [
                      {
                        "asDouble": 0.72,
                        "timeUnixNano": "1705312800000000000",
                        "attributes": [
                          { "key": "host", "value": { "stringValue": "web-1" } }
                        ]
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

`POST /otlp/v1/metrics`

Accepts OTLP/HTTP JSON metrics data. Each data point is stored as a `MetricDataPoint` associated with a named `Metric` stream. Returns `400` for malformed JSON or a missing `resourceMetrics` key.

### Request body

<ParamField body="resourceMetrics" type="object[]" required>
  OTLP `ExportMetricsServiceRequest.resourceMetrics` array.
</ParamField>

### Response — 200

<ResponseField name="accepted" type="number">
  Number of data points successfully ingested.
</ResponseField>

```json theme={null}
{ "accepted": 12 }
```

***

## Ingest OTLP logs

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.agentvista.dev/api/v1/otlp/v1/logs \
    -H "Authorization: Bearer av_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "resourceLogs": [
        {
          "resource": {
            "attributes": [
              { "key": "service.name", "value": { "stringValue": "api-gateway" } }
            ]
          },
          "scopeLogs": [
            {
              "logRecords": [
                {
                  "timeUnixNano": "1705312800000000000",
                  "severityText": "ERROR",
                  "body": { "stringValue": "upstream timeout after 30s" },
                  "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
                  "spanId": "00f067aa0ba902b7"
                }
              ]
            }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

`POST /otlp/v1/logs`

Accepts OTLP/HTTP JSON log data. Log records with `traceId` and `spanId` are linked to their parent trace for cross-signal navigation. Returns `400` for malformed JSON.

### Request body

<ParamField body="resourceLogs" type="object[]" required>
  OTLP `ExportLogsServiceRequest.resourceLogs` array.
</ParamField>

### Response — 200

<ResponseField name="accepted" type="number">
  Number of log records successfully ingested.
</ResponseField>

```json theme={null}
{ "accepted": 47 }
```

***

## OpenTelemetry Collector configuration

Configure the `otlphttp` exporter in your collector to send all three signals to AgentVista:

```yaml otel-collector-config.yaml theme={null}
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

exporters:
  otlphttp:
    endpoint: https://api.agentvista.dev/api/v1
    headers:
      Authorization: "Bearer av_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlphttp]
    metrics:
      receivers: [otlp]
      exporters: [otlphttp]
    logs:
      receivers: [otlp]
      exporters: [otlphttp]
```

***

## Python OpenTelemetry SDK

```python Python SDK example theme={null}
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource

resource = Resource.create({"service.name": "my-agent"})

provider = TracerProvider(resource=resource)

exporter = OTLPSpanExporter(
    endpoint="https://api.agentvista.dev/api/v1/otlp/v1/traces",
    headers={"Authorization": "Bearer av_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
)

provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)

tracer = trace.get_tracer("my-agent")

with tracer.start_as_current_span("classify-lead") as span:
    span.set_attribute("model", "gpt-4o")
    # ... your agent logic
```
