---
title: "Ingest OTLP traces for a run (monitor-URL form)"
method: POST
path: "/{monitor_id}/v1/traces"
tags: ["Traces"]
---

# Ingest OTLP traces for a run (monitor-URL form)

`POST /{monitor_id}/v1/traces`

## Request

- Base URL: `https://ping.lastping.dev`
- URL: `https://ping.lastping.dev/{monitor_id}/v1/traces`
- Auth: one of:
  - none
  - HTTP bearer

The alternative to the Bearer form above, for an exporter that
cannot set headers: the URL's `monitor_id` names the
check and its project directly — the monitor id in the URL is
itself the capability, exactly like a ping URL. No `Authorization`
header is required.

A `lastping.monitor_id` resource attribute is still allowed, but
only to REPEAT the URL's id — never to override it; a mismatch is
400. `lastping.run_id` is optional, exactly as on the Bearer form:
without it each trace becomes its own run. The request is subject
to every cap and the same 3,600-requests/hour/project bucket the
Bearer form uses.

A `Bearer` header MAY additionally be sent on this form; if
present, it must be a valid key belonging to this monitor's own
project (403 otherwise, not 404 — the URL already proves the
monitor exists, so unlike the Bearer-only form there is no
existence oracle to protect here). A key bound to a different
monitor is 400.

Secrets are redacted and the daily span budget applies exactly as
on the Bearer form.

## Request body

- object: The OTLP JSON mapping of `ExportTraceServiceRequest`.

## Response `202`

Accepted and enqueued.

- object
  - `accepted` integer, required
  - `dropped` integer, required

## Other responses

- `400`: Malformed OTLP payload, too many spans, a `lastping.monitor_id` attribute that disagrees with the URL, or a Bearer key bound to a different monitor.
- `401`: A Bearer key was present but is unknown, revoked or expired.
- `403`: A Bearer key was present but its scope is `read`, or it belongs to a different project than this monitor's.
- `404`: `monitor_id` does not name a check on this deployment. No existence oracle.
- `413`: Decompressed body exceeds 1 MiB.
- `415`: Content-Type is neither `application/x-protobuf` nor `application/json`.
- `429`: Trace rate cap exceeded for this project (3,600 requests/hour), independent of the ping rate limit, with `Retry-After: 60`. Or the project's daily span budget is used up (default 2,000,000 spans per UTC day): the problem body carries `code: "SPAN_BUDGET_EXCEEDED"` and `Retry-After` runs to 00:00 UTC. Or LastPing is already reading as many OTLP exports as it takes at once: `code: "OTLP_BUSY"`, `Retry-After: 5`.
- `503`: Tracing is unavailable on this deployment, the spans queue could not accept the message, or the span budget could not be read (refused rather than admitted unmetered). Retry.

---

[API](https://skmtc.dev/lastping/apis/lastping-management-api.md) · [All operations](https://skmtc.dev/lastping/apis/lastping-management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lastping/apis/lastping-management-api/revisions/bbc6eda91c46?raw)
