Ingest API#
LogTap's client SDKs (Browser/Node, Go, Flutter) all use the HTTP endpoints and JSON data model below for "log" and "event/tracking" reporting. Languages without an SDK can call the HTTP API directly.
Conventions#
- Base URL: your LogTap gateway address, e.g.
http://localhost:8080 - Project ID: visible on the project page in the console; used as a path parameter
/api/:projectId/... - Auth (enforced once
AUTH_SECRETis set): reporting must carry a project key — any of:X-Project-Key: pk_...Authorization: Bearer pk_...- the Sentry SDK's
X-Sentry-Auth(sentry_key=...)
- Batching: the same endpoint accepts a single object or a JSON array
- Compression:
Content-Encoding: gzipis supported - Success response:
202 Accepted(the gateway only validates and enqueues; consumers write to the database asynchronously)
1. Structured logs#
Endpoint: POST /api/:projectId/logs/
{
"level": "info",
"message": "hello",
"timestamp": "2025-01-01T00:00:00Z",
"device_id": "d1",
"trace_id": "t1",
"span_id": "s1",
"fields": { "k": "v" },
"tags": { "env": "prod" },
"user": { "id": "u1" },
"contexts": { "app": { "version": "1.2.3" } }
}Field notes:
message: requiredlevel: suggested valuesdebug / info / warn / error / fatal; defaults toinfoserver-side when emptytimestamp: RFC3339; the server fills in the current UTC time when omitteduser.id: used for unique-user metrics (DAU/MAU, funnels); falls back todevice_idwhen absentfields: custom structured fields — put business dimensions heretags/contexts: labels and app context stored with the log and filterable in the console
Batch example (same endpoint, JSON array):
[
{ "level": "info", "message": "hello-1", "user": { "id": "u1" }, "fields": { "k": "v1" } },
{ "level": "info", "message": "hello-2", "user": { "id": "u1" }, "fields": { "k": "v2" } }
]2. Events / tracking#
Endpoint: POST /api/:projectId/track/
{
"name": "signup",
"timestamp": "2025-01-01T00:00:00Z",
"user": { "id": "u1" },
"device_id": "d1",
"properties": { "plan": "pro", "ab": "b" }
}name: event name, requiredproperties: event properties, used for funnel filtering and property breakdowns
Storage rule: events are written to the logs table (level = "event", message = name, fields = properties), so event analytics only count level="event" rows and stay unpolluted by regular logs.
Batch example:
[
{ "name": "signup", "user": { "id": "u1" }, "properties": { "plan": "pro" } },
{ "name": "purchase", "user": { "id": "u1" }, "properties": { "sku": "s1" } }
]3. Search and queries#
- Log/event queries, keyword full-text search, time-series aggregation, funnels, and retention are all done through the console
- Sentry error reporting uses its own protocol — see Sentry compatibility
Recommendations#
- Keep "logs" and "tracking events" separate: logs go to
/logs/, events to/track/ - For high-volume scenarios prefer batch arrays + gzip to cut request counts and network overhead
- Put business dimensions into
fields/properties— console filtering and funnels are built on structured fields