Log ingest HTTP API: JSON lines with curl

Every integration on this site ends up at one of five HTTP endpoints. This page is the reference for the simplest of them, /v1/ingest/jsonline: one JSON object per line, any keys you like. Use it from scripts, cron jobs, CI pipelines or a logging library with an HTTP transport.

Endpoint: https://logs.uptimeeye.com/v1/ingest/jsonline

1.Send your first lines

shell
curl -sS -X POST "https://logs.uptimeeye.com/v1/ingest/jsonline?_stream_fields=service,env" \
  -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @- <<'JSON'
{"_time":"2026-09-04T11:42:08.877Z","_msg":"deploy finished","service":"ci","env":"prod","level":"info","version":"1.42.0"}
{"_msg":"cache warmed in 1.2s","service":"ci","env":"prod","level":"debug","duration_ms":1200}
JSON
Note: _msg is the message, _time the event time (RFC 3339; omit it to use the arrival time). Everything else is a field you can filter on.

2.Compress large batches

Bodies up to 16 MiB uncompressed are accepted; gzip is decompressed on arrival and you are billed for the uncompressed bytes.

shell
gzip -c events.ndjson | curl -sS -X POST "https://logs.uptimeeye.com/v1/ingest/jsonline?_stream_fields=service,env" \
  -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -H "Content-Type: application/x-ndjson" \
  -H "Content-Encoding: gzip" \
  --data-binary @-

3.Map your own field names

If your JSON already uses message and @timestamp, tell the endpoint instead of rewriting your events.

shell
curl -sS -X POST "https://logs.uptimeeye.com/v1/ingest/jsonline?_msg_field=message&_time_field=@timestamp&_stream_fields=service,env" \
  -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  --data-binary @events.ndjson

4.Basic auth instead of a bearer token

Tools that only know user/password: use any user name and the key as password.

shell
curl -sS -u "key:ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -X POST "https://logs.uptimeeye.com/v1/ingest/jsonline" --data-binary @events.ndjson

Tips

  • Batch: one request per line is the slowest way to send logs. Aim for batches of a few hundred lines or a few seconds.
  • Nested objects are flattened to dotted keys (http.status → field http.status).
  • Field names are case-sensitive; Level and level are two fields.

FAQ

Which response codes can I get?
200 accepted · 400 malformed JSON or compression · 401 missing/unknown key · 403 plan without Logs · 413 body over 16 MiB · 415 unsupported Content-Encoding · 429 monthly quota exhausted (see Retry-After) · 502/503 storage or key resolution temporarily unavailable — retry with backoff.
Is there an Elasticsearch-compatible endpoint?
Yes: POST /v1/ingest/elasticsearch/_bulk accepts the bulk format that Filebeat, Vector and Fluent Bit's es output produce. GET /v1/ingest/elasticsearch/ answers the version handshake.
Where do I get the ingest key?
In the app under API Keys → New API Key → type “Log ingest”. The key starts with ue_ingest_ and is shown once. Management keys (ue_live_) are refused by the ingest endpoint.
How do I check that logs arrive?
Open Logs in the app, pick the 15m range and search for service:=<your service>. New lines are searchable within about a second; Live tail shows them with a ~6 s delay.