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

# OTLP contract

> What Squasher accepts and returns over OTLP/HTTP, which encodings each path supports, and what it does not implement.

Squasher accepts OpenTelemetry data over OTLP/HTTP at `https://ingest.squasher.ai`. This page is
the contract for request paths, media types, responses, limits, and intentional non-goals. For
setup and SDK examples, see [OpenTelemetry](/integrations/opentelemetry).

## Paths and authentication

| Path | Signal |
| - | - |
| `POST /v1/traces` | Traces |
| `POST /v1/logs` | Logs |
| `POST /v1/metrics` | Metrics |
| `POST /v1/ai` | AI spans (OTLP resourceSpans body) |

Use `https://ingest.squasher.ai` as the base URL. The **Setup** page also shows a **Collector**
URL. Send OTLP to `https://ingest.squasher.ai` instead: the rate limit and region routing on this
page apply to that endpoint.

Authenticate with one of:

* `x-squasher-key: <key>`
* `Authorization: Bearer <key>`

OTLP requests do not need a project ID. Squasher finds the project from the ingest key.

## Request media types

| `Content-Type` (media type only; parameters ignored) | Logs | Traces | Metrics | `/v1/ai` |
| - | - | - | - | - |
| `application/json` | Yes | Yes | Yes | Yes |
| `application/x-protobuf` | Yes | Yes | Yes | No |
| `application/protobuf` (compatibility alias) | Yes | Yes | Yes | No |

A request without `Content-Type` is read as JSON. Other media types, and protobuf on `/v1/ai`,
return `415`.

Matching is case-insensitive. A value such as `Application/X-Protobuf; charset=binary` is treated
as protobuf.

## Compression and body size

| `Content-Encoding` | Accepted |
| - | - |
| (none) or `identity` | Yes |
| `gzip` | Yes |
| Anything else | No (`415`) |

A gzip body can expand to at most 16 MiB. A larger decompressed body returns `413`. An invalid
gzip body returns `400`.

## Success responses

| Request encoding | HTTP status | Response body |
| - | - | - |
| JSON | `200` | `{}` |
| Protobuf (logs, traces, metrics) | `200` | OTLP `Export*ServiceResponse` with empty `partial_success`, `Content-Type: application/x-protobuf` |

Squasher does not report a rejected subset in `partial_success`. A `200` means the full request was
accepted for storage or for durable replay. Delivery is at least once, so a retry can store a
duplicate. Keep stable trace and span IDs.

## Error responses

| Condition | Status | Notes |
| - | - | - |
| Missing or invalid key | `401` | Fix the key before retrying |
| Wrong path, or a gRPC exporter | `404` | Use a path from the table above |
| Method other than `POST` | `405` | Send `POST` |
| Unsupported media type or encoding; protobuf on `/v1/ai` | `415` | Fix `Content-Type` or `Content-Encoding` |
| Invalid JSON or protobuf body | `400` | Fix the payload |
| Decompressed body over 16 MiB | `413` | Split the batch |
| Project rate limit exceeded | `429` | Back off; see rate-limit headers |
| Temporary ingest unavailability | `503` | Retry after the `Retry-After` value |

Retry `429` and `5xx` with backoff. Do not retry other `4xx` responses before you fix the request.
A `503` can follow a partial write, so a retry can store some records twice.

## Data region

Each project stores its data in one data region. `ingest.squasher.ai` sends each request to the
region of the project that owns the key. Squasher does not store a project's data in another region.
If a request reaches the wrong region, Squasher returns a retryable `503` and stores nothing.

## Rate limits

Each project can send 10,000 records per minute by default. Squasher counts each span, log record,
and metric point in the request. Above the limit, Squasher returns `429` with `Retry-After` and
`X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`.

## What Squasher does with each signal

| Signal | What Squasher stores | Creates an issue when |
| - | - | - |
| Traces | Spans with attributes, events, and links | Span status `ERROR`, or an exception event on a non-error span |
| Logs | Log records with resource and record attributes | Severity 17 (`ERROR`) or more, or an exception at `WARN` (13) or more |
| Metrics | Gauges, sums, histograms, and exponential histograms (summary metrics are dropped) | Never |
| `/v1/ai` | AI observations and scores from OTLP resourceSpans | Never; send errors on `/v1/traces` or `/v1/logs` |

For attribute rename rules and issue grouping detail, see
[OpenTelemetry](/integrations/opentelemetry#what-squasher-does-with-each-signal).

## Sampling and fidelity

Squasher stores the span `traceState` value when the exporter sends it. It does not parse W3C
tracestate sampling keys such as `ot=th`, and service request and error counts use the spans
Squasher accepted, not adjusted counts. If you sample in your OpenTelemetry Collector, follow
[Tail sampling](/integrations/tail-sampling) so error and slow traces still reach Squasher.

## Intentional non-goals

Squasher does **not**:

* Accept OTLP over gRPC (port 4317). Use `http/protobuf` or `http/json`.
* Host an OpenTelemetry Collector with processors for customer pipelines. Bring your own Collector
  when you need processors, then export OTLP/HTTP to Squasher.
* Offer a customer-facing OTLP **export** API. Read data through the product UI, REST API, CLI, or
  MCP.
* Accept protobuf on `/v1/ai`. Send JSON to that path, or send AI spans on `/v1/traces` with the
  usual GenAI attributes.

[Squasher Collector](/integrations/infrastructure-monitoring) is a host and optional Docker
**metrics agent** that exports OTLP/HTTP metrics to Squasher. It is not a hosted Collector for
application OTLP ingest.

## Next steps

<CardGroup cols={2}>
  <Card title="OpenTelemetry setup" icon="https://mintcdn.com/nextbigthingllc/e12gFqmgX0x4CiVm/icons/brands/opentelemetry.svg?fit=max&auto=format&n=e12gFqmgX0x4CiVm&q=85&s=fb5ec167b8e372d6e298b589c6f1f5d4" href="/integrations/opentelemetry" width="1024" height="1024" data-path="icons/brands/opentelemetry.svg">
    Set exporter variables and connect an SDK or Collector.
  </Card>

  <Card title="Tail sampling" icon="https://mintcdn.com/nextbigthingllc/Fg5aclMlZNSrg_Y3/icons/docs/sampling.svg?fit=max&auto=format&n=Fg5aclMlZNSrg_Y3&q=85&s=a8fe09c554ba5d312ea58b35d9d1e37f" href="/integrations/tail-sampling" width="24" height="24" data-path="icons/docs/sampling.svg">
    Keep error and slow traces and drop routine ones.
  </Card>

  <Card title="HTTP ingest API" icon="https://mintcdn.com/nextbigthingllc/Fg5aclMlZNSrg_Y3/icons/docs/ingest.svg?fit=max&auto=format&n=Fg5aclMlZNSrg_Y3&q=85&s=6c3f03aba9d37ff16cfbe16ad22617cc" href="/integrations/http-api" width="24" height="24" data-path="icons/docs/ingest.svg">
    Send events and drain logs without OTLP.
  </Card>

  <Card title="Infrastructure monitoring" icon="https://mintcdn.com/nextbigthingllc/Fg5aclMlZNSrg_Y3/icons/entity/host.svg?fit=max&auto=format&n=Fg5aclMlZNSrg_Y3&q=85&s=9995add7a509f5962226ab2531a1e030" href="/integrations/infrastructure-monitoring" width="24" height="24" data-path="icons/entity/host.svg">
    Run Squasher Collector for host and Docker metrics.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.