Pingtower Docs
Docs The service Ingest

Ingest

One endpoint, one JSON object per line, one bearer token per source. Everything Pingtower knows starts here.

POST /v1/ingest, authenticated with a pti_ source token. Nothing in the body names a project or a source; the token decides.

Payload

FieldTypeMeaning
messageREQUIREDstringThe line. Template extraction runs on this. Up to 64 KiB.
levelintegerSeverity. 100 debug, 200 info, 300 warn, 400 error, 500 critical.
keysobjectUp to 128 named values. Each value is substituted out of the message to form the template, is available to rule conditions, and can group alerts through identifier_keys. Scalars only; they are stored as strings.
tagsstring[]Up to 64 free-form labels a rule can match on.
{
  "message": "payment gateway timeout after 30012ms for order o_48113",
  "level": 400,
  "keys": { "order": "o_48113", "gateway": "stripe", "latency_ms": 30012 },
  "tags": ["billing", "prod"]
}

The server timestamps the line on arrival. There is no client timestamp field.

Response

202 Accepted with {"alerted": true|false, "template_id": "…"}. alerted says whether any rule fired on this line, which makes a one-line smoke test possible. template_id is the SHA-256 of the recovered template.

StatusMeans
401The bearer is missing, malformed, or not an ingest token.
429Over the plan’s ingest rate, or the tenant’s storage quota. Retry-After says how long to wait.
500The daemon could not store the line.

What happens to a line

  1. Template extraction. Every value in keys is found in the message and replaced by {{ .name }}. Longest value first, every occurrence, so order o_48113 and order o_48120 share the template order {{ .order }}. A message with no key hits is its own template.
  2. Rule evaluation. Every rule in the project is evaluated against the line’s level, source, tags, template and keys.
  3. Dedup. A line whose template matches an alert that is already firing bumps that alert’s count instead of opening a new one. See Rules for how identifier_keys split that.
  4. Retention. If the source has retain_logs, the raw line is kept so the log tail can show it. Retention is capped by plan and by the daemon’s flags; a cap costs you history, never an alert.
Only what you name is maskedTemplate extraction replaces the values you passed as keys, nothing else. Put every variable part of the message, ids, durations, hosts, in keys, or two lines that differ only there will open two alerts.

Batching and backpressure

One object per request. The endpoint does very little work per call, so batching gains nothing and loses the per-line alerted answer. Over the rate you get 429 and a Retry-After. The addons agent spools to disk and drains when the tower is reachable again; if you write your own sender, do the same rather than dropping lines.

Last updated 1 Sep 2026 Report a problem with this page