Browse docs
API ReferenceUpdated March 27, 2026

Log

The Log API is how you ingest events into Telemetry. Use it for application events, user activity, metrics, or structured logs.

Telemetry accepts flexible JSON input, but it is not a pure pass-through endpoint. The API normalizes table names, fills in timestamps, and prunes null or empty values before forwarding data to storage.

POST https://api.telemetry.sh/log

Headers

Name Type Description
Content-Type String application/json
Authorization String Your API key, either as the raw key or as Bearer <key>

Body

Name Type Description
table String Destination table name. Spaces are converted to underscores, letters are lowercased, and after normalization only lowercase ASCII letters, numbers, and _ are allowed.
data JSON Event payload. Supported shapes are a JSON object, an array of JSON objects, a JSON string that decodes to a JSON object, or an array mixing JSON objects with JSON strings that decode to JSON objects.

Accepted data shapes

The API accepts:

  • a single JSON object
  • an array of JSON objects
  • a JSON string that itself parses into a JSON object
  • an array containing JSON objects and JSON strings that parse into JSON objects

The API rejects:

  • top-level numbers, booleans, and null
  • JSON strings that decode to non-object values such as arrays, numbers, booleans, or null
  • arrays containing non-object, non-string items
  • arrays containing JSON strings that decode to non-object values
  • JSON payloads nested deeper than 64 levels

Server-side normalization

When data contains JSON objects, Telemetry applies these rules before ingest:

  • adds timestamp with the current UTC time if it is missing
  • if timestamp is null, replaces it with the current UTC time
  • if timestamp is a Unix timestamp integer or numeric string, interprets it as Unix seconds and converts it to RFC 3339
  • removes timestamp_utc if present
  • removes null values, empty objects, and empty arrays recursively

Examples:

  • Telemetry Events becomes telemetry_events
  • timestamp: 1700000000 becomes an RFC 3339 timestamp string
  • { "user": "alice", "meta": null } is stored without meta

Example Usage with cURL

To send Uber ride data to a table named uber_rides using cURL, you can use the following command:

curl -X POST https://api.telemetry.sh/log \
  -H "Content-Type: application/json" \
  -H "Authorization: $API_KEY" \
  -d '{
    "table": "uber_rides",
    "data": {
      "city": "paris",
      "price": 42,
      "timestamp": "'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"
    }
  }'

Using the JavaScript SDK

We recommend using our SDKs for a better developer experience. Here’s an example of how to use our JavaScript SDK:

import telemetry from "telemetry-sh";

telemetry.init("YOUR_API_KEY");

telemetry.log("uber_rides", {
  city: "paris",
  price: 42,
  timestamp: new Date().toISOString()
});

Bulk logging

You can also pass in an array of objects to bulk ingest events. This is useful for limiting the number of requests to the API. For example, instead of:

telemetry.log("uber_rides", { a: 1 })

You can do:

telemetry.log("uber_rides", [{a: 1}, {a: 2}])

This will ingest the data as two rows.

Common errors

  • 400 Bad Request if the JSON body is invalid
  • 400 Bad Request if the table name contains invalid characters after normalization
  • 400 Bad Request if data is not in a supported shape
  • 400 Bad Request if a JSON string in data decodes to a non-object value
  • 400 Bad Request if a Unix timestamp is outside the supported range
  • 401 Unauthorized if the API key is missing or invalid
  • 429 Too Many Requests if the API key exceeds the gateway rate limit