Requirements

  • App record - the PrairieLog service that owns the logs.
  • Ingestion token - the token your app uses to send logs.
  • Alert webhook - the Slack or Discord URL that receives alerts.

Only ERROR logs trigger aggregated alerts, and only when sent through the Kafka-backed ingestion endpoints (what the SDKs use). INFO, WARN, DEBUG, and TRACE are accepted but never notify, and the plain /api/v1/log-events endpoints accept logs for live relay without alerting at all.

SDK install

SDKs are the normal integration path. They batch events, normalize levels, and fill required fields.

  • TypeScript - browser, React, Angular, vanilla JS, and Node services.
  • Python - attach PrairieLogHandler to standard logging.
  • Java - add the Logback appender for JVM services.
Package install targets
npm install @prairielog/client
pip install prairielog-handler

<dependency>
  <groupId>io.github.robertsima</groupId>
  <artifactId>prairielog-logback</artifactId>
  <version>0.2.0</version>
</dependency>

Use npm for TypeScript and JavaScript apps, PyPI for Python services, and Maven Central for Logback-based JVM services.

TypeScript / JavaScript
import { PrairieLogClient } from "@prairielog/client";

const prairieLog = new PrairieLogClient({
  apiUrl: "__API_BASE_URL__",
  ingestionToken: "YOUR_INGESTION_TOKEN",
  defaultLogger: "checkout-web",
  batchSize: 50,
  storageKey: "prairielog-buffer"
});

prairieLog.installGlobalHandlers();

await prairieLog.info("Checkout loaded", { route: "/checkout" });
await prairieLog.captureException(error, {
  endpoint: "/api/v1/checkout",
  orderId: "ord_123"
});
Python logging
import logging
from prairielog_handler import PrairieLogHandler

logging.getLogger().addHandler(PrairieLogHandler(
    api_url="__API_BASE_URL__",
    ingestion_token="YOUR_INGESTION_TOKEN",
    logger_name="checkout-worker",
    batch_size=50,
))

logging.exception("Payment failed")
Java Logback
<appender name="PRAIRIELOG" class="com.prairielog.logback.PrairieLogAppender">
  <apiUrl>__API_BASE_URL__</apiUrl>
  <ingestionToken>${PRAIRIELOG_INGESTION_TOKEN}</ingestionToken>
  <batchSize>50</batchSize>
</appender>

<root level="INFO">
  <appender-ref ref="PRAIRIELOG"/>
</root>

Runtime config

Keep server tokens in environment variables. A token embedded in browser code is visible to anyone who opens the page source, so if you log from the browser, create a separate ingestion token for it — you can revoke it from the dashboard without rotating your server tokens.

  • apiUrl is the PrairieLog API base URL, currently __API_BASE_URL__.
  • ingestionToken is the token created for your PrairieLog app.
  • batchSize controls how many events the SDK sends per request. The API accepts up to 100.
  • metadata should carry route, order, status, user, or feature context.

Framework patterns

React and Angular examples build on the TypeScript client for global error capture, boundaries, and dependency-injected logging.

Loading framework snippets...

API docs

Use the API docs for endpoint groups, curl examples, OpenAPI schemas, and response shapes.

Raw API bootstrap reference

Use these curl steps for credentials and one-off tests. Application logging should use an SDK.

Auth note: in production the management endpoints below (users, apps, tokens, alert destinations) require a signed-in session — add -H "Authorization: Bearer YOUR_ID_TOKEN" or simply use the dashboard, which handles this for you. The unauthenticated curl flow shown here is for local backends with management auth disabled. Sending log events always uses only the X-Ingestion-Token header, in every environment.

Create a user

Local bootstrap only (deprecated): this endpoint registers an owner for your apps on local backends with management auth disabled. In production, skip this step — sign in on the dashboard and your user record is created automatically from your sign-in.

curl
curl -X POST __API_BASE_URL__/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "email": "dev@example.com",
    "username": "devuser"
  }'

Register your app

Register the application or service that will send logs to PrairieLog API.

curl
curl -X POST __API_BASE_URL__/api/v1/apps \
  -H "Content-Type: application/json" \
  -d '{
    "ownerEmail": "dev@example.com",
    "name": "payment-service",
    "description": "Sends live logs from the payment API."
  }'

ownerEmail links the app to your bootstrap user in the local flow. When you call this endpoint with a signed-in bearer token, the owner comes from your session and ownerEmail is ignored.

Generate an ingestion token

The raw token is returned once at creation. Copy it immediately into a server env var (for example PRAIRIELOG_TOKEN). The API will not show the full token again.

Dashboard note: when you generate a token in the dashboard, it stays in this browser tab only until you refresh. Copy it before leaving the page.

curl
curl -X POST __API_BASE_URL__/api/v1/apps/{appId}/tokens \
  -H "Content-Type: application/json" \
  -d '{
    "name": "local-dev-token"
  }'

Add an alert destination

Register the Slack or Discord incoming webhook URL where you want alerts delivered. This is not the same as your ingestion token — it is the channel endpoint PrairieLog posts to.

curl
curl -X POST __API_BASE_URL__/api/v1/apps/{appId}/alert-destinations \
  -H "Content-Type: application/json" \
  -d '{
    "type": "DISCORD",
    "name": "dev-alerts",
    "webhookUrl": "https://discord.com/api/webhooks/..."
  }'

Destination types: SLACK or DISCORD. Webhook URLs are stored by the API but never returned in full from list endpoints.

Send a log event

POST a JSON log event from your app using your ingestion token (not the alert webhook). This plain endpoint accepts the log for live relay only — it never aggregates or alerts, no matter the level.

JSON payload
[
  {
    "level": "ERROR",
    "message": "Failed to process payment for user 123.",
    "logger": "com.example.PaymentService",
    "traceId": "trace-abc-123",
    "metadata": {
      "endpoint": "/payments",
      "userId": 42
    }
  }
]
curl
curl -X POST __API_BASE_URL__/api/v1/log-events/batch \
  -H "Content-Type: application/json" \
  -H "X-Ingestion-Token: YOUR_INGESTION_TOKEN" \
  -d '[{
    "level": "ERROR",
    "message": "Failed to process payment for user 123.",
    "logger": "com.example.PaymentService",
    "traceId": "trace-abc-123"
  }]'

This endpoint has no alerting side effect, even for level: "ERROR". If you want an alert, use the Kafka-backed endpoint below instead.

Trigger an alert (Kafka pipeline)

Alerting is asynchronous and flows exclusively through the Kafka-backed ingestion endpoints. The SDKs use this path automatically. A request queues the event on the central-log-events topic; normalization, aggregation, optional analysis, and delivery to your configured destinations all happen in background consumers, so this endpoint responds as soon as the event is queued, not once an alert is sent.

curl
curl -X POST __API_BASE_URL__/api/v1/kafka/log-events \
  -H "Content-Type: application/json" \
  -H "X-Ingestion-Token: YOUR_INGESTION_TOKEN" \
  -d '{
    "level": "ERROR",
    "message": "Failed to process payment for user 123.",
    "logger": "com.example.PaymentService",
    "traceId": "trace-abc-123"
  }'

A batch variant exists at POST /api/v1/kafka/log-events/batch (array body, same shape as the plain batch endpoint). Both return 503 if the Kafka integration toggle is disabled or the broker is unavailable — check GET /api/v1/kafka/status from a signed-in session if alerts stop arriving. Similar ERROR events that land close together are grouped into one summarized chat message instead of one message per event.