When to use it
Use the HTTP API when an SDK does not cover your runtime or workflow yet.
Events sent through the HTTP API show up in the same Logister views as SDK events: errors go to the inbox, logs and metrics go to activity, transaction timings and spans power performance, and check-ins create monitor status. Choose Manual / HTTP API when creating a project for a custom client, unsupported runtime, script, or worker. Use this reference when you are building a custom client, wiring a language without a first-party package, or sending one-off operational events from scripts. Use the metrics reference when you need the broader map of supported telemetry, add-on coverage, chart series, context fields, and data collection boundaries.
Authentication
Use a project API token.
Generate the token from the target project settings page. Store it in the sending app's environment or secret manager, because Logister only shows the token once. Tokens for archived projects are rejected, and archiving a project disables its active tokens; restore the project and generate a fresh token before resuming ingestion.
Authorization: Bearer <token>X-Api-Key: <token>
Rate limits
Public API requests are capped per project token and endpoint.
By default, POST /api/v1/ingest_events and POST /api/v1/check_ins each accept 1,200 requests per minute per API token. Missing, invalid, revoked, or archived-project tokens are capped at 120 authentication failures per minute per source IP.
Rate-limited requests return 429 Too Many Requests with Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. Self-hosters can tune the accepted-request limit, window size, and authentication-failure limit with LOGISTER_PUBLIC_API_RATE_LIMIT_REQUESTS, LOGISTER_PUBLIC_API_RATE_LIMIT_PERIOD_SECONDS, and LOGISTER_PUBLIC_API_AUTH_FAILURE_RATE_LIMIT_REQUESTS. App admins listed in LOGISTER_ADMIN_EMAILS can set project-level overrides from project settings; project owners and shared project members cannot change those overrides.
API tooling
Use Swagger, OpenAPI, or Postman when examples are faster than prose.
| Tool | Best for | Link |
|---|---|---|
| Swagger UI | Interactive API browsing and trying requests with a project API token. | Open API reference |
| OpenAPI YAML | Generating clients or importing the contract into API tooling. | Download openapi.yaml |
| Postman collection | Testing ready-made requests for errors, logs, metrics, transactions, spans, and check-ins. | Download collection |
Ingest events
POST application events with an event root key.
Use this endpoint for errors, logs, metrics, transactions, spans, and check-ins when you want the full event shape. The canonical JSON envelope is event; Logister also accepts uppercase EVENT for clients and runtimes that serialize struct keys that way.
POST /api/v1/ingest_events
Authorization: Bearer <token>
Content-Type: application/json{
"event": {
"event_type": "error",
"level": "error",
"message": "NoMethodError in CheckoutService",
"fingerprint": "checkout-nomethoderror",
"occurred_at": "2026-02-14T12:00:00Z",
"context": {
"environment": "production",
"request_id": "abc123",
"metadata": {
"user_id": 42
},
"request": {
"method": "POST",
"url": "https://app.example.com/checkout",
"route": "POST /checkout",
"request_id": "abc123"
}
}
}
}Event keys are normalized before validation, so common camelCase fields such as eventType, traceId, requestId, transactionName, and durationMs map to the snake_case fields shown here.
Event fields
Send the fields that match what you want to see in Logister.
| Field | Required? | How Logister uses it |
|---|---|---|
event_type | Required | Controls where the event appears. Use error, metric, transaction, span, log, or check_in. |
message | Required for non-span events | Primary label shown in the inbox, activity feed, and event details. Span events use name or message as the span label. |
level | Optional | Severity such as info, warn, error, or fatal. Error groups use it for severity display. |
fingerprint | Optional | Groups repeated errors into the same inbox issue. If absent, Logister falls back to the first message line. |
occurred_at | Optional | Timestamp for when the event happened. If absent, Logister uses receive time. Span events can also use started_at. |
context | Optional | Structured metadata for investigation, filtering, release health, performance, monitor status, request load breakdowns, and related-log correlation. |
For convenience, Logister also accepts common fields next to context and copies them into context when they are not already set: environment, release, trace_id, traceId, request_id, requestId, session_id, sessionId, user_id, userId, transaction_name, transactionName, duration_ms, durationMs, span_id, spanId, parent_span_id, parentSpanId, kind, span_kind, started_at, startedAt, ended_at, endedAt, expected_interval_seconds, check_in_slug, monitor_slug, check_in_status, and status.
Useful context
Context is what makes the product useful after delivery succeeds.
| Goal | Recommended context |
|---|---|
| Make errors easier to triage | environment, release, exception, request, user_id, and a stable fingerprint. |
| Show the failing request prominently | Send request.method and request.url or top-level method and url. Logister also understands request.path, request.query_string, request.route, request.headers, and request.params. |
| Link errors to nearby logs | trace_id, request_id, session_id, or user_id on both error and log events. |
| Power transaction performance | transaction_name, duration_ms, status code, route, method, and release. |
| Build request load waterfall charts | Span events with trace_id, span_id, parent_span_id, kind, name, duration_ms, started_at, route, request ID, and service context. |
| Show database load | Metric events with message set to db.query plus duration_ms, query name, and SQL context when safe to store. |
| Create monitor status | check_in_slug, check_in_status, expected_interval_seconds, environment, release, and optional duration_ms, trace_id, and request_id. |
Spans
Send spans when you want request load waterfalls instead of only transaction totals.
Span events are accepted through the same ingest endpoint but are stored in Logister's trace span store. Root spans should use kind values such as server for backend requests or browser for page loads. Child spans can use db, render, http, cache, queue, resource, app, or internal. Use the same trace_id across the root and children, and set parent_span_id on child spans.
{
"event": {
"event_type": "span",
"name": "GET /checkout",
"kind": "server",
"trace_id": "trace-123",
"span_id": "span-root",
"duration_ms": 245.7,
"started_at": "2026-05-22T12:00:00Z",
"context": {
"route": "GET /checkout",
"request_id": "req-123",
"service": "checkout-api"
}
}
}To add child timing, send another span with the same trace and a parent span ID:
{
"event": {
"event_type": "span",
"name": "SELECT orders",
"kind": "db",
"trace_id": "trace-123",
"span_id": "span-db",
"parent_span_id": "span-root",
"duration_ms": 40.2,
"started_at": "2026-05-22T12:00:00Z"
}
}Check-ins
POST monitor heartbeats for scheduled work with a smaller payload.
Use this endpoint when the thing you are reporting is a cron job, scheduled task, or recurring worker heartbeat. The canonical envelope is check_in; uppercase CHECK_IN is accepted too, and camelCase fields are normalized before the check-in event is stored.
POST /api/v1/check_ins
Authorization: Bearer <token>
Content-Type: application/json{
"check_in": {
"slug": "nightly-reconcile",
"status": "ok",
"expected_interval_seconds": 900,
"environment": "production",
"release": "2026.03.02"
}
}| Field | Default | How Logister uses it |
|---|---|---|
slug | Required | Monitor name, such as nightly-reconcile. |
status | ok | ok keeps the monitor healthy. error marks the latest run as failed. |
expected_interval_seconds | 300 | How often Logister expects the job to report before it can be considered missed. |
environment | App environment | Separates production, staging, and other monitor streams. |
duration_ms | Blank | Optional runtime for the completed job. |
release, trace_id, request_id | Blank | Optional context for tying a check-in back to a deploy or execution trace. |
Responses
Successful writes return the Logister record id.
| Status | Meaning | Body |
|---|---|---|
201 Created | The event or check-in was accepted. | {"id":"event-uuid","status":"accepted"}. The ingest endpoint also includes legacy_id. |
201 Created | The span was accepted. | {"id":"span-uuid","legacy_id":123,"status":"accepted","type":"span"}. |
400 Bad Request | The required event/EVENT or check_in/CHECK_IN envelope was missing or unusable. | {"error":"param is missing..."} |
401 Unauthorized | The API key was missing, revoked, invalid, inactive, or belongs to an archived project. | {"error":"Unauthorized"} |
422 Unprocessable Content | The envelope was present, but the event, span, or check-in failed validation. | {"errors":["..."]} |
429 Too Many Requests | The API token or authentication-failure source exceeded the public API rate limit. | {"error":"Rate limit exceeded","limit":1200,"window_seconds":60,"retry_after":60} |
Accepted and rate-limited responses include rate-limit headers so clients can back off before retrying.
When self-observability is configured with LOGISTER_API_KEY and LOGISTER_ENDPOINT, rejected client submissions are also reported through the Ruby gem as sanitized warning logs. Those diagnostics include the rejection reason, status, endpoint, request metadata, root/envelope keys, normalized payload keys, and API-key or project context when it can be derived safely.
Verify delivery
Make sure your first payload shows up where you expect.
1. Send one test error, transaction, span, or check-in payload
2. Open the matching project in Logister
3. Confirm the record appears in the inbox, activity feed, performance page, or monitors
4. Inspect context fields to verify the payload shape
5. Only then add the rest of your instrumentation